diff --git a/Content/Shaders/GI/DDGI.flax b/Content/Shaders/GI/DDGI.flax index 8d8ba1d43..25b849638 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:6ad0a077984ef2749700d6eb08bf1f6a23ea1fd84e4296128ecbe3d57994b007 -size 19306 +oid sha256:5d0a6384fca382ceb56dd0623dfef87eec29002f667b0608317f9519b492cfd1 +size 19388 diff --git a/Content/Shaders/GI/GlobalSurfaceAtlas.flax b/Content/Shaders/GI/GlobalSurfaceAtlas.flax index 6c82a055f..8a5772f9e 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:f207d29b09af5c4e3564ee73f87b4d0eb0075d5982bbbd7c6275a723ab84ef1d -size 11787 +oid sha256:c34156f4c30f14b6d6bae1505b640d186557060c13bfec5ccf75777ca929c033 +size 11800 diff --git a/Source/Engine/Renderer/GI/DynamicDiffuseGlobalIllumination.cpp b/Source/Engine/Renderer/GI/DynamicDiffuseGlobalIllumination.cpp index 679df6254..1d4bdbb27 100644 --- a/Source/Engine/Renderer/GI/DynamicDiffuseGlobalIllumination.cpp +++ b/Source/Engine/Renderer/GI/DynamicDiffuseGlobalIllumination.cpp @@ -276,6 +276,7 @@ bool DynamicDiffuseGlobalIlluminationPass::Render(RenderContext& renderContext, const float distanceExtent = distance / cascadesDistanceScales[cascadesCount - 1]; const float verticalRangeScale = 0.8f; // Scales the probes volume size at Y axis (horizontal aspect ratio makes the DDGI use less probes vertically to cover whole screen) const float probesSpacing = 200.0f; // GI probes placement spacing nearby camera (for closest cascade; gets automatically reduced for further cascades) + const Color fallbackIrradiance = Color::Black; // Irradiance lighting outside the DDGI range used as a fallback to prevent pure-black scene outside the GI range const Int3 probesCounts(Vector3::Ceil(Vector3(distanceExtent, distanceExtent * verticalRangeScale, distanceExtent) / probesSpacing)); 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 @@ -413,6 +414,7 @@ bool DynamicDiffuseGlobalIlluminationPass::Render(RenderContext& renderContext, ddgiData.Result.Constants.RaysCount = probeRaysCount; ddgiData.Result.Constants.ProbeHistoryWeight = probeHistoryWeight; ddgiData.Result.Constants.IrradianceGamma = 5.0f; + ddgiData.Result.Constants.FallbackIrradiance = fallbackIrradiance.ToVector3() * fallbackIrradiance.A; ddgiData.Result.ProbesState = ddgiData.ProbesState->View(); ddgiData.Result.ProbesDistance = ddgiData.ProbesDistance->View(); ddgiData.Result.ProbesIrradiance = ddgiData.ProbesIrradiance->View(); diff --git a/Source/Engine/Renderer/GI/DynamicDiffuseGlobalIllumination.h b/Source/Engine/Renderer/GI/DynamicDiffuseGlobalIllumination.h index 64bc0b3ca..35158a7bc 100644 --- a/Source/Engine/Renderer/GI/DynamicDiffuseGlobalIllumination.h +++ b/Source/Engine/Renderer/GI/DynamicDiffuseGlobalIllumination.h @@ -27,6 +27,8 @@ public: Vector4 RaysRotation; Vector3 ViewDir; uint32 RaysCount; + Vector3 FallbackIrradiance; + float Padding1; }); // Binding data for the GPU. diff --git a/Source/Shaders/GI/DDGI.hlsl b/Source/Shaders/GI/DDGI.hlsl index e09b364f4..7aaf6527b 100644 --- a/Source/Shaders/GI/DDGI.hlsl +++ b/Source/Shaders/GI/DDGI.hlsl @@ -34,6 +34,8 @@ struct DDGIData float4 RaysRotation; float3 ViewDir; uint RaysCount; + float3 FallbackIrradiance; + float Padding1; }; uint GetDDGIProbeIndex(DDGIData data, uint3 probeCoords) @@ -133,7 +135,7 @@ float3 SampleDDGIIrradiance(DDGIData data, Texture2D probesState, Textur break; } if (cascadeIndex == data.CascadesCount) - return float3(0, 0, 0); + return data.FallbackIrradiance; float probesSpacing = data.ProbesOriginAndSpacing[cascadeIndex].w; float3 probesOrigin = data.ProbesScrollOffsets[cascadeIndex].xyz * probesSpacing + data.ProbesOriginAndSpacing[cascadeIndex].xyz; diff --git a/Source/Shaders/GI/DDGI.shader b/Source/Shaders/GI/DDGI.shader index ab29d23d5..c22b33200 100644 --- a/Source/Shaders/GI/DDGI.shader +++ b/Source/Shaders/GI/DDGI.shader @@ -86,7 +86,7 @@ void CS_Classify(uint3 DispatchThreadId : SV_DispatchThreadID) float sdf; float3 sdfNormal = normalize(SampleGlobalSDFGradient(GlobalSDF, GlobalSDFTex, probePosition.xyz, sdf)); float sdfDst = abs(sdf); - float threshold = GlobalSDF.CascadeVoxelSize[CascadeIndex] * 0.5f; + float threshold = GlobalSDF.CascadeVoxelSize[CascadeIndex]; float distanceLimit = length(probesSpacing) * 2.0f; float relocateLimit = length(probesSpacing) * 0.6f; if (sdfDst > distanceLimit) // Probe is too far from geometry @@ -305,7 +305,10 @@ void CS_UpdateProbes(uint3 DispatchThreadId : SV_DispatchThreadID, uint GroupInd // Skip further blending after reaching backfaces limit if (backfacesCount >= backfacesLimit) - return; + { + result = float4(0, 0, 0, 1); + break; + } continue; } @@ -313,7 +316,7 @@ void CS_UpdateProbes(uint3 DispatchThreadId : SV_DispatchThreadID, uint GroupInd result += float4(rayRadiance.rgb * rayWeight, rayWeight); #else // Increase reaction speed for depth discontinuities - rayWeight = pow(rayWeight, 4.0f); + rayWeight = pow(rayWeight, 10.0f); // Add distance (R), distance^2 (G) and weight (A) float rayDistance = min(abs(rayRadiance.w), distanceLimit);