From 611961cefedf273fd920aef3820d163ac2d59f0c Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Tue, 18 Jun 2024 10:52:28 +0200 Subject: [PATCH] Improve DDGI cascade selection by using biased world position --- Source/Shaders/GI/DDGI.hlsl | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/Source/Shaders/GI/DDGI.hlsl b/Source/Shaders/GI/DDGI.hlsl index 1c052e8e0..63f70b15a 100644 --- a/Source/Shaders/GI/DDGI.hlsl +++ b/Source/Shaders/GI/DDGI.hlsl @@ -139,14 +139,16 @@ float3 SampleDDGIIrradiance(DDGIData data, Texture2D probesData, T // Select the highest cascade that contains the sample location uint cascadeIndex = 0; float probesSpacing = 0; - float3 probesOrigin = (float3)0, probesExtent = (float3)0; + float3 probesOrigin = (float3)0, probesExtent = (float3)0, biasedWorldPosition = (float3)0; + float3 viewDir = normalize(data.ViewPos - worldPosition); for (; cascadeIndex < data.CascadesCount; cascadeIndex++) { probesSpacing = data.ProbesOriginAndSpacing[cascadeIndex].w; probesOrigin = data.ProbesScrollOffsets[cascadeIndex].xyz * probesSpacing + data.ProbesOriginAndSpacing[cascadeIndex].xyz; probesExtent = (data.ProbesCounts - 1) * (probesSpacing * 0.5f); + biasedWorldPosition = worldPosition + (worldNormal * 0.2f + viewDir * 0.8f) * (0.75f * probesSpacing * bias); float fadeDistance = probesSpacing * 0.5f; - float cascadeWeight = saturate(Min3(probesExtent - abs(worldPosition - probesOrigin)) / fadeDistance); + float cascadeWeight = saturate(Min3(probesExtent - abs(biasedWorldPosition - probesOrigin)) / fadeDistance); if (cascadeWeight > dither) // Use dither to make transition smoother break; } @@ -155,11 +157,6 @@ float3 SampleDDGIIrradiance(DDGIData data, Texture2D probesData, T uint3 probeCoordsEnd = data.ProbesCounts - uint3(1, 1, 1); uint3 baseProbeCoords = clamp(uint3((worldPosition - probesOrigin + probesExtent) / probesSpacing), uint3(0, 0, 0), probeCoordsEnd); - // Bias the world-space position to reduce artifacts - 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 float3 baseProbeWorldPosition = GetDDGIProbeWorldPosition(data, cascadeIndex, baseProbeCoords); float3 biasAlpha = saturate((biasedWorldPosition - baseProbeWorldPosition) / probesSpacing);