diff --git a/Content/Editor/DebugMaterials/DDGIDebugProbes.flax b/Content/Editor/DebugMaterials/DDGIDebugProbes.flax index f38eb04bd..49c91d5b4 100644 --- a/Content/Editor/DebugMaterials/DDGIDebugProbes.flax +++ b/Content/Editor/DebugMaterials/DDGIDebugProbes.flax @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:cd7232c07e5969b4db266528006dc0bad9b737f77da7bca56730fcf652509e9a -size 37759 +oid sha256:78c41dd01f6f2740fbdd08c2e0f05875398f38ba8e09bd91495636281a6ec6cc +size 37799 diff --git a/Content/Shaders/GI/DDGI.flax b/Content/Shaders/GI/DDGI.flax index a8463dbec..3285a98d5 100644 --- a/Content/Shaders/GI/DDGI.flax +++ b/Content/Shaders/GI/DDGI.flax @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:97b8d640c0f47b0eedba8bb90190043081ae26a5e371eba1c5e5c1271e411ddf -size 18125 +oid sha256:a321b884ea74537d1b4f2fd0769cd81ff91280d35ad193c0811b6fc995b9f38d +size 18502 diff --git a/Content/Shaders/GI/GlobalSurfaceAtlas.flax b/Content/Shaders/GI/GlobalSurfaceAtlas.flax index 460f42dc1..6184bb640 100644 --- a/Content/Shaders/GI/GlobalSurfaceAtlas.flax +++ b/Content/Shaders/GI/GlobalSurfaceAtlas.flax @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d10f34a19ddbeea914082a23362317a2fc6ca31ca18d9307447023c9f2789414 -size 10610 +oid sha256:22313af733ee40c4789fd184d172b6ad8ea3d46ee3da9b33dd34403a642f76f6 +size 11710 diff --git a/Source/Engine/Renderer/GI/DynamicDiffuseGlobalIllumination.cpp b/Source/Engine/Renderer/GI/DynamicDiffuseGlobalIllumination.cpp index a81f6c939..9d86a9585 100644 --- a/Source/Engine/Renderer/GI/DynamicDiffuseGlobalIllumination.cpp +++ b/Source/Engine/Renderer/GI/DynamicDiffuseGlobalIllumination.cpp @@ -43,7 +43,8 @@ PACK_STRUCT(struct Data0 GlobalSignDistanceFieldPass::ConstantsData GlobalSDF; GlobalSurfaceAtlasPass::ConstantsData GlobalSurfaceAtlas; GBufferData GBuffer; - Vector3 Padding0; + Vector2 Padding0; + float ResetBlend; float IndirectLightingIntensity; }); @@ -283,7 +284,7 @@ bool DynamicDiffuseGlobalIlluminationPass::Render(RenderContext& renderContext, // TODO: configurable via graphics settings const Quality quality = Quality::Ultra; - bool debugProbes = true; // TODO: add debug option to draw probes locations -> in Graphics window - Editor-only + bool debugProbes = false; // TODO: add debug option to draw probes locations -> in Graphics window - Editor-only // TODO: configurable via postFx settings (maybe use Global SDF distance?) const float indirectLightingIntensity = 1.0f; const Vector3 giDistance(2000, 2000, 2000); // GI distance around the view (in each direction) @@ -291,7 +292,7 @@ bool DynamicDiffuseGlobalIlluminationPass::Render(RenderContext& renderContext, const Int3 probesCounts(Vector3::Ceil(giDistance / giResolution)); const Vector3 probesDistance = Vector3(probesCounts) * giResolution; const int32 probeRaysCount = Math::Min(Math::AlignUp(256, DDGI_TRACE_RAYS_GROUP_SIZE_X), DDGI_TRACE_RAYS_LIMIT); // TODO: make it based on the GI Quality - const float probeHistoryWeight = 0.97f; + const float probeHistoryWeight = 0.8f; // Init buffers const int32 probesCount = probesCounts.X * probesCounts.Y * probesCounts.Z; @@ -347,6 +348,7 @@ bool DynamicDiffuseGlobalIlluminationPass::Render(RenderContext& renderContext, viewOrigin += viewDirection * viewOriginOffset; const float viewOriginSnapping = giResolution; viewOrigin = Vector3::Floor(viewOrigin / viewOriginSnapping) * viewOriginSnapping; + //viewOrigin = Vector3::Zero; CalculateVolumeScrolling(ddgiData, viewOrigin); // Upload constants @@ -377,6 +379,7 @@ bool DynamicDiffuseGlobalIlluminationPass::Render(RenderContext& renderContext, data.DDGI = ddgiData.Result.Constants; data.GlobalSDF = bindingDataSDF.Constants; data.GlobalSurfaceAtlas = bindingDataSurfaceAtlas.Constants; + data.ResetBlend = clear ? 1.0f : 0.0f; data.IndirectLightingIntensity = indirectLightingIntensity; GBufferPass::SetInputs(renderContext.View, data.GBuffer); context->UpdateCB(_cb0, &data); diff --git a/Source/Engine/Renderer/GI/GlobalSurfaceAtlasPass.cpp b/Source/Engine/Renderer/GI/GlobalSurfaceAtlasPass.cpp index 2b8675ff0..e278a121a 100644 --- a/Source/Engine/Renderer/GI/GlobalSurfaceAtlasPass.cpp +++ b/Source/Engine/Renderer/GI/GlobalSurfaceAtlasPass.cpp @@ -437,7 +437,7 @@ bool GlobalSurfaceAtlasPass::Render(RenderContext& renderContext, GPUContext* co surfaceAtlasData.TileTexelsPerWorldUnit = 1.0f / 10.0f; // Scales the tiles resolution surfaceAtlasData.DistanceScalingStart = 2000.0f; // Distance from camera at which the tiles resolution starts to be scaled down surfaceAtlasData.DistanceScalingEnd = 5000.0f; // Distance from camera at which the tiles resolution end to be scaled down - surfaceAtlasData.DistanceScaling = 0.1f; // The scale for tiles at distanceScalingEnd and further away + surfaceAtlasData.DistanceScaling = 0.2f; // The scale for tiles at distanceScalingEnd and further away // TODO: add DetailsScale param to adjust quality of scene details in Global Surface Atlas const uint32 viewMask = renderContext.View.RenderLayersMask; const Vector3 viewPosition = renderContext.View.Position; @@ -595,6 +595,9 @@ bool GlobalSurfaceAtlasPass::Render(RenderContext& renderContext, GPUContext* co result.Constants.ChunkSize = distance / (float)GLOBAL_SURFACE_ATLAS_CHUNKS_RESOLUTION; result.Constants.ObjectsCount = surfaceAtlasData.Objects.Count(); + // If we don't know the culled objects buffer capacity then we shouldn't use atlas results as many objects are still missing (see CulledObjectsCounterIndex usage) + bool notReady = false; + // Cull objects into chunks (for faster Atlas sampling) if (surfaceAtlasData.Objects.Count() != 0) { @@ -620,18 +623,23 @@ bool GlobalSurfaceAtlasPass::Render(RenderContext& renderContext, GPUContext* co if (surfaceAtlasData.CulledObjectsCounterIndex != -1) { // Get the last counter value (accept staging readback delay) + notReady = true; auto data = (uint32*)_culledObjectsSizeBuffer->Map(GPUResourceMapMode::Read); if (data) { uint32 counter = data[surfaceAtlasData.CulledObjectsCounterIndex]; _culledObjectsSizeBuffer->Unmap(); if (counter > 0) + { objectsBufferCapacity = counter * sizeof(Vector4); + notReady = false; + } } } if (surfaceAtlasData.CulledObjectsCounterIndex == -1) { // Find a free timer slot + notReady = true; for (int32 i = 0; i < ARRAY_COUNT(_culledObjectsSizeFrames); i++) { if (currentFrame - _culledObjectsSizeFrames[i] > GPU_ASYNC_LATENCY) @@ -870,12 +878,10 @@ bool GlobalSurfaceAtlasPass::Render(RenderContext& renderContext, GPUContext* co context->ResetRenderTarget(); } - // TODO: indirect lighting apply to get infinite bounces for GI - // TODO: explore atlas tiles optimization with feedback from renderer (eg. when tile is sampled by GI/Reflections mark it as used, then sort tiles by importance and prioritize updates for ones frequently used) #undef WRITE_TILE - return false; + return notReady; } void GlobalSurfaceAtlasPass::RenderDebug(RenderContext& renderContext, GPUContext* context, GPUTexture* output) diff --git a/Source/Shaders/GI/DDGI.shader b/Source/Shaders/GI/DDGI.shader index 1e4dd1200..d5daae4ba 100644 --- a/Source/Shaders/GI/DDGI.shader +++ b/Source/Shaders/GI/DDGI.shader @@ -27,7 +27,8 @@ DDGIData DDGI; GlobalSDFData GlobalSDF; GlobalSurfaceAtlasData GlobalSurfaceAtlas; GBufferData GBuffer; -float3 Padding0; +float2 Padding0; +float ResetBlend; float IndirectLightingIntensity; META_CB_END @@ -228,8 +229,7 @@ void CS_UpdateProbes(uint3 DispatchThreadId : SV_DispatchThreadID, uint GroupInd { // Clear probe and return //RWOutput[outputCoords] = float4(0, 0, 0, 0); - if (!skip) - RWOutput[outputCoords] = float4(0, 0, 0, 0); + //if (!skip) RWOutput[outputCoords] = float4(0, 0, 0, 0); skip = true; } } @@ -260,7 +260,7 @@ void CS_UpdateProbes(uint3 DispatchThreadId : SV_DispatchThreadID, uint GroupInd if (skip) { // Clear probe - //RWOutput[outputCoords] = float4(0, 0, 0, 0); + RWOutput[outputCoords] = float4(0, 0, 0, 0); return; } @@ -310,17 +310,15 @@ void CS_UpdateProbes(uint3 DispatchThreadId : SV_DispatchThreadID, uint GroupInd // Blend current value with the previous probe data float3 previous = RWOutput[outputCoords].rgb; float historyWeight = DDGI.ProbeHistoryWeight; - if (dot(previous, previous) == 0) - { - // Cut any blend from zero + //historyWeight = 0.0f; + if (ResetBlend || dot(previous, previous) == 0) historyWeight = 0.0f; - } #if DDGI_PROBE_UPDATE_MODE == 0 result *= IndirectLightingIntensity; #if DDGI_SRGB_BLENDING result.rgb = pow(result.rgb, 1.0f / DDGI.IrradianceGamma); #endif - float3 irradianceDelta = result.rgb - previous.rgb; + float3 irradianceDelta = result.rgb - previous; float irradianceDeltaMax = Max3(abs(irradianceDelta)); if (irradianceDeltaMax > 0.25f) { @@ -330,12 +328,13 @@ void CS_UpdateProbes(uint3 DispatchThreadId : SV_DispatchThreadID, uint GroupInd if (irradianceDeltaMax > 0.8f) { // Reduce flickering during rapid brightness changes - result.rgb = previous.rgb + (irradianceDelta * 0.25f); + result.rgb = previous + (irradianceDelta * 0.25f); } float3 resultDelta = (1.0f - historyWeight) * irradianceDelta; - if (Max3(result.rgb) < Max3(previous.rgb)) + if (Max3(result.rgb) < Max3(previous)) resultDelta = min(max(abs(resultDelta), 1.0f / 1024.0f), abs(irradianceDelta)) * sign(resultDelta); - result = float4(previous.rgb + resultDelta, 1.0f); + result = float4(previous + resultDelta, 1.0f); + //result = float4(lerp(result.rgb, previous.rgb, historyWeight), 1.0f); #else result = float4(lerp(result.rg, previous.rg, historyWeight), 0.0f, 1.0f); #endif diff --git a/Source/Shaders/GI/GlobalSurfaceAtlas.shader b/Source/Shaders/GI/GlobalSurfaceAtlas.shader index c917583d7..4f91680d3 100644 --- a/Source/Shaders/GI/GlobalSurfaceAtlas.shader +++ b/Source/Shaders/GI/GlobalSurfaceAtlas.shader @@ -117,6 +117,7 @@ float4 PS_Lighting(AtlasVertexOutput input) : SV_Target // Sample irradiance float bias = 1.0f; float3 irradiance = SampleDDGIIrradiance(DDGI, ProbesState, ProbesDistance, ProbesIrradiance, gBuffer.WorldPos, gBuffer.Normal, bias); + //irradiance = 0; // Calculate lighting float3 diffuseColor = GetDiffuseColor(gBuffer);