From 5239a2b410d3c54d6b2233d211f34a32f5e25cfe Mon Sep 17 00:00:00 2001 From: Wojciech Figat Date: Mon, 20 Jun 2022 09:49:40 +0200 Subject: [PATCH] Optimize DDGI probes state data from `R16G16B16A16_Float` to `R8G8B8A8_SNorm` --- .../GI/DynamicDiffuseGlobalIllumination.cpp | 2 +- Source/Shaders/GI/DDGI.hlsl | 18 +++++++++++++++--- Source/Shaders/GI/DDGI.shader | 12 +++++++----- Source/Shaders/GI/GlobalSurfaceAtlas.shader | 2 +- Source/Shaders/VolumetricFog.shader | 2 +- 5 files changed, 25 insertions(+), 11 deletions(-) diff --git a/Source/Engine/Renderer/GI/DynamicDiffuseGlobalIllumination.cpp b/Source/Engine/Renderer/GI/DynamicDiffuseGlobalIllumination.cpp index f87a8b5da..f6477592b 100644 --- a/Source/Engine/Renderer/GI/DynamicDiffuseGlobalIllumination.cpp +++ b/Source/Engine/Renderer/GI/DynamicDiffuseGlobalIllumination.cpp @@ -373,7 +373,7 @@ bool DynamicDiffuseGlobalIlluminationPass::Render(RenderContext& renderContext, #define INIT_TEXTURE(texture, format, width, height) desc.Format = format; desc.Width = width; desc.Height = height; ddgiData.texture = RenderTargetPool::Get(desc); if (!ddgiData.texture) return true; memUsage += ddgiData.texture->GetMemoryUsage() desc.Flags = GPUTextureFlags::ShaderResource | GPUTextureFlags::UnorderedAccess; INIT_TEXTURE(ProbesTrace, PixelFormat::R16G16B16A16_Float, probeRaysCount, Math::Min(probesCountCascade, DDGI_TRACE_RAYS_PROBES_COUNT_LIMIT)); - INIT_TEXTURE(ProbesState, PixelFormat::R16G16B16A16_Float, probesCountTotalX, probesCountTotalY); // TODO: optimize to a RGBA32 (pos offset can be normalized to [0-0.5] range of ProbesSpacing and packed with state flag) + INIT_TEXTURE(ProbesState, PixelFormat::R8G8B8A8_SNorm, probesCountTotalX, probesCountTotalY); INIT_TEXTURE(ProbesIrradiance, PixelFormat::R11G11B10_Float, probesCountTotalX * (DDGI_PROBE_RESOLUTION_IRRADIANCE + 2), probesCountTotalY * (DDGI_PROBE_RESOLUTION_IRRADIANCE + 2)); INIT_TEXTURE(ProbesDistance, PixelFormat::R16G16_Float, probesCountTotalX * (DDGI_PROBE_RESOLUTION_DISTANCE + 2), probesCountTotalY * (DDGI_PROBE_RESOLUTION_DISTANCE + 2)); #undef INIT_TEXTURE diff --git a/Source/Shaders/GI/DDGI.hlsl b/Source/Shaders/GI/DDGI.hlsl index 2452cccdf..d3b2bd368 100644 --- a/Source/Shaders/GI/DDGI.hlsl +++ b/Source/Shaders/GI/DDGI.hlsl @@ -90,19 +90,30 @@ float3 GetDDGIProbeWorldPosition(DDGIData data, uint cascadeIndex, uint3 probeCo } // Loads probe probe state -float LoadDDGIProbeState(DDGIData data, Texture2D probesState, uint cascadeIndex, uint probeIndex) +float LoadDDGIProbeState(DDGIData data, Texture2D probesState, uint cascadeIndex, uint probeIndex) { int2 probeDataCoords = GetDDGIProbeTexelCoords(data, cascadeIndex, probeIndex); float4 probeState = probesState.Load(int3(probeDataCoords, 0)); return probeState.w; } +// Loads probe world-space position (XYZ) and probe state (W) +float4 LoadDDGIProbePositionAndState(DDGIData data, Texture2D probesState, uint cascadeIndex, uint probeIndex, uint3 probeCoords) +{ + int2 probeDataCoords = GetDDGIProbeTexelCoords(data, cascadeIndex, probeIndex); + float4 probeState = probesState.Load(int3(probeDataCoords, 0)); + probeState.xyz *= data.ProbesOriginAndSpacing[cascadeIndex].w; // Probe offset is [-1;1] within probes spacing + probeState.xyz += GetDDGIProbeWorldPosition(data, cascadeIndex, probeCoords); // Place probe on a grid + return probeState; +} + // Loads probe world-space position (XYZ) and probe state (W) float4 LoadDDGIProbePositionAndState(DDGIData data, Texture2D probesState, uint cascadeIndex, uint probeIndex, uint3 probeCoords) { int2 probeDataCoords = GetDDGIProbeTexelCoords(data, cascadeIndex, probeIndex); float4 probeState = probesState.Load(int3(probeDataCoords, 0)); - probeState.xyz += GetDDGIProbeWorldPosition(data, cascadeIndex, probeCoords); + probeState.xyz *= data.ProbesOriginAndSpacing[cascadeIndex].w; // Probe offset is [-1;1] within probes spacing + probeState.xyz += GetDDGIProbeWorldPosition(data, cascadeIndex, probeCoords); // Place probe on a grid return probeState; } @@ -120,7 +131,7 @@ 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 probesState, Texture2D probesDistance, Texture2D probesIrradiance, float3 worldPosition, float3 worldNormal, float bias, float dither = 0.0f) +float3 SampleDDGIIrradiance(DDGIData data, Texture2D probesState, Texture2D probesDistance, Texture2D probesIrradiance, float3 worldPosition, float3 worldNormal, float bias, float dither = 0.0f) { // Select the highest cascade that contains the sample location uint cascadeIndex = 0; @@ -182,6 +193,7 @@ float3 SampleDDGIIrradiance(DDGIData data, Texture2D probesState, Textur float4 probeState = probeStates[i]; if (probeState.w == DDGI_PROBE_STATE_INACTIVE) continue; + probeState.xyz *= probesSpacing; // Probe offset is [-1;1] within probes spacing float3 probeBasePosition = baseProbeWorldPosition + ((probeCoords - baseProbeCoords) * probesSpacing); float3 probePosition = probeBasePosition + probeState.xyz; diff --git a/Source/Shaders/GI/DDGI.shader b/Source/Shaders/GI/DDGI.shader index 2cf4ae36e..9edce817c 100644 --- a/Source/Shaders/GI/DDGI.shader +++ b/Source/Shaders/GI/DDGI.shader @@ -58,7 +58,7 @@ float3 GetProbeRayDirection(DDGIData data, uint rayIndex) #ifdef _CS_Classify -RWTexture2D RWProbesState : register(u0); +RWTexture2D RWProbesState : register(u0); Texture3D GlobalSDFTex : register(t0); Texture3D GlobalSDFMip : register(t1); @@ -79,6 +79,7 @@ void CS_Classify(uint3 DispatchThreadId : SV_DispatchThreadID) // Load probe state and position float4 probeState = RWProbesState[probeDataCoords]; + probeState.xyz *= probesSpacing; // Probe offset is [-1;1] within probes spacing float3 probeBasePosition = GetDDGIProbeWorldPosition(DDGI, CascadeIndex, probeCoords); float3 probePosition = probeBasePosition + probeState.xyz; probeState.w = DDGI_PROBE_STATE_ACTIVE; @@ -128,7 +129,8 @@ void CS_Classify(uint3 DispatchThreadId : SV_DispatchThreadID) probeState.xyz = float3(0, 0, 0); } } - + + probeState.xyz /= probesSpacing; RWProbesState[probeDataCoords] = probeState; } @@ -144,7 +146,7 @@ ByteAddressBuffer GlobalSurfaceAtlasChunks : register(t2); Buffer GlobalSurfaceAtlasCulledObjects : register(t3); Texture2D GlobalSurfaceAtlasDepth : register(t4); Texture2D GlobalSurfaceAtlasTex : register(t5); -Texture2D ProbesState : register(t6); +Texture2D ProbesState : register(t6); TextureCube Skybox : register(t7); // Compute shader for tracing rays for probes using Global SDF and Global Surface Atlas. @@ -217,7 +219,7 @@ groupshared float CachedProbesTraceDistance[DDGI_TRACE_RAYS_LIMIT]; groupshared float3 CachedProbesTraceDirection[DDGI_TRACE_RAYS_LIMIT]; RWTexture2D RWOutput : register(u0); -Texture2D ProbesState : register(t0); +Texture2D ProbesState : register(t0); Texture2D ProbesTrace : register(t1); // Compute shader for updating probes irradiance or distance texture. @@ -453,7 +455,7 @@ void CS_UpdateBorders(uint3 DispatchThreadId : SV_DispatchThreadID) #include "./Flax/Random.hlsl" #include "./Flax/LightingCommon.hlsl" -Texture2D ProbesState : register(t4); +Texture2D ProbesState : register(t4); Texture2D ProbesDistance : register(t5); Texture2D ProbesIrradiance : register(t6); diff --git a/Source/Shaders/GI/GlobalSurfaceAtlas.shader b/Source/Shaders/GI/GlobalSurfaceAtlas.shader index 3993f995b..f43332157 100644 --- a/Source/Shaders/GI/GlobalSurfaceAtlas.shader +++ b/Source/Shaders/GI/GlobalSurfaceAtlas.shader @@ -71,7 +71,7 @@ void PS_Clear(out float4 Light : SV_Target0, out float4 RT0 : SV_Target1, out fl // GBuffer+Depth at 0-3 slots Buffer GlobalSurfaceAtlasObjects : register(t4); #if INDIRECT_LIGHT -Texture2D ProbesState : register(t5); +Texture2D ProbesState : register(t5); Texture2D ProbesDistance : register(t6); Texture2D ProbesIrradiance : register(t7); #else diff --git a/Source/Shaders/VolumetricFog.shader b/Source/Shaders/VolumetricFog.shader index 90f280838..570802086 100644 --- a/Source/Shaders/VolumetricFog.shader +++ b/Source/Shaders/VolumetricFog.shader @@ -286,7 +286,7 @@ Texture3D LightScatteringHistory : register(t2); Texture3D LocalShadowedLightScattering : register(t3); Texture2DArray ShadowMapCSM : register(t4); #if USE_DDGI -Texture2D ProbesState : register(t5); +Texture2D ProbesState : register(t5); Texture2D ProbesDistance : register(t6); Texture2D ProbesIrradiance : register(t7); #else