Improve DDGI quality
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -24,7 +24,7 @@ public:
|
||||
float RayMaxDistance;
|
||||
float IndirectLightingIntensity;
|
||||
Float4 RaysRotation;
|
||||
Float3 ViewDir;
|
||||
Float3 ViewPos;
|
||||
uint32 RaysCount;
|
||||
Float3 FallbackIrradiance;
|
||||
float Padding0;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user