Improve DDGI quality

This commit is contained in:
Wojciech Figat
2022-06-24 16:17:32 +02:00
parent a7b31fbf9b
commit 282b9066b8
6 changed files with 13 additions and 11 deletions

View File

@@ -462,7 +462,7 @@ bool DynamicDiffuseGlobalIlluminationPass::Render(RenderContext& renderContext,
ddgiData.Result.Constants.ProbesScrollOffsets[cascadeIndex] = Int4(cascade.ProbeScrollOffsets, 0);
}
ddgiData.Result.Constants.RayMaxDistance = 10000.0f; // TODO: adjust to match perf/quality ratio (make it based on Global SDF and Global Surface Atlas distance)
ddgiData.Result.Constants.ViewDir = renderContext.View.Direction;
ddgiData.Result.Constants.ViewPos = renderContext.View.Position;
ddgiData.Result.Constants.RaysCount = probeRaysCount;
ddgiData.Result.Constants.ProbeHistoryWeight = probeHistoryWeight;
ddgiData.Result.Constants.IrradianceGamma = 5.0f;

View File

@@ -24,7 +24,7 @@ public:
float RayMaxDistance;
float IndirectLightingIntensity;
Float4 RaysRotation;
Float3 ViewDir;
Float3 ViewPos;
uint32 RaysCount;
Float3 FallbackIrradiance;
float Padding0;

View File

@@ -32,7 +32,7 @@ struct DDGIData
float RayMaxDistance;
float IndirectLightingIntensity;
float4 RaysRotation;
float3 ViewDir;
float3 ViewPos;
uint RaysCount;
float3 FallbackIrradiance;
float Padding0;
@@ -120,8 +120,9 @@ float2 GetDDGIProbeUV(DDGIData data, uint cascadeIndex, uint probeIndex, float2
}
// Samples DDGI probes volume at the given world-space position and returns the irradiance.
// rand - randomized per-pixel value in range 0-1, used to smooth dithering for cascades blending
float3 SampleDDGIIrradiance(DDGIData data, Texture2D<snorm float4> probesState, Texture2D<float4> probesDistance, Texture2D<float4> probesIrradiance, float3 worldPosition, float3 worldNormal, float bias, float dither = 0.0f)
// bias - scales the bias vector to the initial sample point to reduce self-shading artifacts
// dither - randomized per-pixel value in range 0-1, used to smooth dithering for cascades blending
float3 SampleDDGIIrradiance(DDGIData data, Texture2D<snorm float4> probesState, Texture2D<float4> probesDistance, Texture2D<float4> probesIrradiance, float3 worldPosition, float3 worldNormal, float bias = 0.2f, float dither = 0.0f)
{
// Select the highest cascade that contains the sample location
uint cascadeIndex = 0;
@@ -163,7 +164,8 @@ float3 SampleDDGIIrradiance(DDGIData data, Texture2D<snorm float4> probesState,
float3 probesExtent = (data.ProbesCounts - 1) * (probesSpacing * 0.5f);
// Bias the world-space position to reduce artifacts
float3 surfaceBias = (worldNormal * bias) + (data.ViewDir * (bias * -4.0f));
float3 viewDir = normalize(data.ViewPos - worldPosition);
float3 surfaceBias = (worldNormal * 0.2f + viewDir * 0.8f) * (0.75f * probesSpacing * bias);
float3 biasedWorldPosition = worldPosition + surfaceBias;
// Get the grid coordinates of the probe nearest the biased world position
@@ -190,7 +192,7 @@ float3 SampleDDGIIrradiance(DDGIData data, Texture2D<snorm float4> probesState,
// Calculate the distance and direction from the (biased and non-biased) shading point and the probe
float3 worldPosToProbe = normalize(probePosition - worldPosition);
float3 biasedPosToProbe = normalize(probePosition - biasedWorldPosition);
float biasedPosToProbeDist = length(probePosition - biasedWorldPosition);
float biasedPosToProbeDist = length(probePosition - biasedWorldPosition) * 0.95f;
// Smooth backface test
float weight = Square(dot(worldPosToProbe, worldNormal) * 0.5f + 0.5f);

View File

@@ -387,7 +387,7 @@ void CS_UpdateProbes(uint3 GroupThreadId : SV_GroupThreadID, uint3 GroupId : SV_
// Load current probe value
float3 previous = RWOutput[outputCoords].rgb;
bool wasActivated = GetProbeState(probeState, DDGI_PROBE_STATE_ACTIVATED);
if (wasActivated)
if (ResetBlend || wasActivated)
previous = float3(0, 0, 0);
// Blend current value with the previous probe data
@@ -522,7 +522,7 @@ void PS_IndirectLighting(Quad_VS2PS input, out float4 output : SV_Target0)
}
// Sample irradiance
float bias = 1.0f;
float bias = 0.2f;
float dither = RandN2(input.TexCoord + TemporalTime).x;
float3 irradiance = SampleDDGIIrradiance(DDGI, ProbesState, ProbesDistance, ProbesIrradiance, gBuffer.WorldPos, gBuffer.Normal, bias, dither);

View File

@@ -125,7 +125,7 @@ float4 PS_Lighting(AtlasVertexOutput input) : SV_Target
// Calculate lighting
float3 diffuseColor = GetDiffuseColor(gBuffer);
diffuseColor = min(diffuseColor, 0.9f); // Nothing reflects diffuse like perfectly in the real world (ensure to have energy loss at each light bounce)
diffuseColor = min(diffuseColor, 0.98f); // Nothing reflects diffuse like perfectly in the real world (ensure to have energy loss at each light bounce)
float3 diffuse = Diffuse_Lambert(diffuseColor);
float4 light = float4(diffuse * irradiance * gBuffer.AO, 1);
#else

View File

@@ -337,7 +337,7 @@ void CS_LightScattering(uint3 GroupId : SV_GroupID, uint3 DispatchThreadId : SV_
#if USE_DDGI
// Dynamic Diffuse Global Illumination
float3 irradiance = SampleDDGIIrradiance(DDGI, ProbesState, ProbesDistance, ProbesIrradiance, positionWS, cameraVectorNormalized, 1.0f);
float3 irradiance = SampleDDGIIrradiance(DDGI, ProbesState, ProbesDistance, ProbesIrradiance, positionWS, cameraVectorNormalized, 0.0f, cellOffset.x);
lightScattering += float4(irradiance, 1);
#else
// Sky light