From eb6050cf274347b5c592c9565084f8ef7bd32f3a Mon Sep 17 00:00:00 2001 From: Wojciech Figat Date: Fri, 27 May 2022 11:44:39 +0200 Subject: [PATCH] Improve probes relocation algorithm to reduce visual artifacts due to probes flickering --- .../Engine/Renderer/GI/GlobalSurfaceAtlasPass.cpp | 1 + Source/Shaders/GI/DDGI.hlsl | 14 ++++++-------- Source/Shaders/GI/DDGI.shader | 10 ++++++++-- 3 files changed, 15 insertions(+), 10 deletions(-) diff --git a/Source/Engine/Renderer/GI/GlobalSurfaceAtlasPass.cpp b/Source/Engine/Renderer/GI/GlobalSurfaceAtlasPass.cpp index f6c13ac01..4e6a6b566 100644 --- a/Source/Engine/Renderer/GI/GlobalSurfaceAtlasPass.cpp +++ b/Source/Engine/Renderer/GI/GlobalSurfaceAtlasPass.cpp @@ -896,6 +896,7 @@ void GlobalSurfaceAtlasPass::RenderDebug(RenderContext& renderContext, GPUContex Vector2 outputSizeTwoThird = outputSize * 0.666f; GPUTexture* tempBuffer = renderContext.Buffers->RT2_FloatRGB; + context->Clear(tempBuffer->View(), Color::Black); context->SetRenderTarget(tempBuffer->View()); // Full screen - direct light diff --git a/Source/Shaders/GI/DDGI.hlsl b/Source/Shaders/GI/DDGI.hlsl index b36cc5d3d..69619faa9 100644 --- a/Source/Shaders/GI/DDGI.hlsl +++ b/Source/Shaders/GI/DDGI.hlsl @@ -97,16 +97,10 @@ float LoadDDGIProbeState(DDGIData data, Texture2D probesState, uint prob // Loads probe world-space position (XYZ) and probe state (W) float4 LoadDDGIProbePositionAndState(DDGIData data, Texture2D probesState, uint probeIndex, uint3 probeCoords) { - float4 result; - result.xyz = GetDDGIProbeWorldPosition(data, probeCoords); - - // Probe state contains relocation's offset and the classification's state int2 probeDataCoords = GetDDGIProbeTexelCoords(data, probeIndex); float4 probeState = probesState.Load(int3(probeDataCoords, 0)); - result.xyz += probeState.xyz; - result.w = probeState.w; - - return result; + probeState.xyz += GetDDGIProbeWorldPosition(data, probeCoords); + return probeState; } // Calculates texture UVs for sampling probes atlas texture (irradiance or distance) @@ -193,6 +187,10 @@ float3 SampleDDGIIrradiance(DDGIData data, Texture2D probesState, Textur probeIrradiance = pow(probeIrradiance, data.IrradianceGamma * 0.5f); #endif + // Debug probe offset visualization + //float4 probeState = probesState.Load(int3(GetDDGIProbeTexelCoords(data, probeIndex), 0)); + //probeIrradiance = float3(max(frac(probeState.xyz) * 2, 0.1f)); + // Accumulate weighted irradiance irradiance += float4(probeIrradiance * weight, weight); } diff --git a/Source/Shaders/GI/DDGI.shader b/Source/Shaders/GI/DDGI.shader index d6713e67d..1e4dd1200 100644 --- a/Source/Shaders/GI/DDGI.shader +++ b/Source/Shaders/GI/DDGI.shader @@ -90,8 +90,13 @@ void CS_Classify(uint3 DispatchThreadId : SV_DispatchThreadID) { if (abs(sdf) < relocateLimit) { - // Relocate it - probeState.xyz = probeState.xyz + sdfNormal * (sdf + threshold); + float3 offsetToAdd = sdfNormal * (sdf + threshold); + if (distance(probeState.xyz, offsetToAdd) < relocateLimit) + { + // Relocate it + probeState.xyz = probeState.xyz + offsetToAdd; + } + // TODO: maybe sample SDF at the relocated location and disable probe if it's still in the geometry? } else { @@ -400,6 +405,7 @@ void CS_UpdateBorders(uint3 DispatchThreadId : SV_DispatchThreadID) copyCoordinates = uint2(threadCoordinates.x - 1, probeStart + offset); #endif COPY_PIXEL; + #undef COPY_PIXEL #undef COPY_PIXEL_DEBUG }