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.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.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.RaysCount = probeRaysCount;
ddgiData.Result.Constants.ProbeHistoryWeight = probeHistoryWeight; ddgiData.Result.Constants.ProbeHistoryWeight = probeHistoryWeight;
ddgiData.Result.Constants.IrradianceGamma = 5.0f; ddgiData.Result.Constants.IrradianceGamma = 5.0f;

View File

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

View File

@@ -32,7 +32,7 @@ struct DDGIData
float RayMaxDistance; float RayMaxDistance;
float IndirectLightingIntensity; float IndirectLightingIntensity;
float4 RaysRotation; float4 RaysRotation;
float3 ViewDir; float3 ViewPos;
uint RaysCount; uint RaysCount;
float3 FallbackIrradiance; float3 FallbackIrradiance;
float Padding0; 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. // 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 // bias - scales the bias vector to the initial sample point to reduce self-shading artifacts
float3 SampleDDGIIrradiance(DDGIData data, Texture2D<snorm float4> probesState, Texture2D<float4> probesDistance, Texture2D<float4> probesIrradiance, float3 worldPosition, float3 worldNormal, float bias, float dither = 0.0f) // 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 // Select the highest cascade that contains the sample location
uint cascadeIndex = 0; uint cascadeIndex = 0;
@@ -163,7 +164,8 @@ float3 SampleDDGIIrradiance(DDGIData data, Texture2D<snorm float4> probesState,
float3 probesExtent = (data.ProbesCounts - 1) * (probesSpacing * 0.5f); float3 probesExtent = (data.ProbesCounts - 1) * (probesSpacing * 0.5f);
// Bias the world-space position to reduce artifacts // 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; float3 biasedWorldPosition = worldPosition + surfaceBias;
// Get the grid coordinates of the probe nearest the biased world position // 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 // Calculate the distance and direction from the (biased and non-biased) shading point and the probe
float3 worldPosToProbe = normalize(probePosition - worldPosition); float3 worldPosToProbe = normalize(probePosition - worldPosition);
float3 biasedPosToProbe = normalize(probePosition - biasedWorldPosition); float3 biasedPosToProbe = normalize(probePosition - biasedWorldPosition);
float biasedPosToProbeDist = length(probePosition - biasedWorldPosition); float biasedPosToProbeDist = length(probePosition - biasedWorldPosition) * 0.95f;
// Smooth backface test // Smooth backface test
float weight = Square(dot(worldPosToProbe, worldNormal) * 0.5f + 0.5f); 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 // Load current probe value
float3 previous = RWOutput[outputCoords].rgb; float3 previous = RWOutput[outputCoords].rgb;
bool wasActivated = GetProbeState(probeState, DDGI_PROBE_STATE_ACTIVATED); bool wasActivated = GetProbeState(probeState, DDGI_PROBE_STATE_ACTIVATED);
if (wasActivated) if (ResetBlend || wasActivated)
previous = float3(0, 0, 0); previous = float3(0, 0, 0);
// Blend current value with the previous probe data // 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 // Sample irradiance
float bias = 1.0f; float bias = 0.2f;
float dither = RandN2(input.TexCoord + TemporalTime).x; float dither = RandN2(input.TexCoord + TemporalTime).x;
float3 irradiance = SampleDDGIIrradiance(DDGI, ProbesState, ProbesDistance, ProbesIrradiance, gBuffer.WorldPos, gBuffer.Normal, bias, dither); 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 // Calculate lighting
float3 diffuseColor = GetDiffuseColor(gBuffer); 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); float3 diffuse = Diffuse_Lambert(diffuseColor);
float4 light = float4(diffuse * irradiance * gBuffer.AO, 1); float4 light = float4(diffuse * irradiance * gBuffer.AO, 1);
#else #else

View File

@@ -337,7 +337,7 @@ void CS_LightScattering(uint3 GroupId : SV_GroupID, uint3 DispatchThreadId : SV_
#if USE_DDGI #if USE_DDGI
// Dynamic Diffuse Global Illumination // 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); lightScattering += float4(irradiance, 1);
#else #else
// Sky light // Sky light