diff --git a/Source/Engine/Renderer/GlobalSignDistanceFieldPass.cpp b/Source/Engine/Renderer/GlobalSignDistanceFieldPass.cpp index 7e4846b7f..60bcde40b 100644 --- a/Source/Engine/Renderer/GlobalSignDistanceFieldPass.cpp +++ b/Source/Engine/Renderer/GlobalSignDistanceFieldPass.cpp @@ -251,7 +251,7 @@ bool GlobalSignDistanceFieldPass::Render(RenderContext& renderContext, GPUContex const int32 mipFactor = 4; const int32 resolutionMip = Math::DivideAndRoundUp(resolution, mipFactor); // TODO: configurable via postFx settings - const float distanceExtent = 2500.0f; + const float distanceExtent = 2000.0f; const float cascadesDistances[] = { distanceExtent, distanceExtent * 2.0f, distanceExtent * 4.0f, distanceExtent * 8.0f }; // Initialize buffers @@ -403,8 +403,10 @@ bool GlobalSignDistanceFieldPass::Render(RenderContext& renderContext, GPUContex PROFILE_GPU_CPU("Rasterize Chunks"); for (auto& e : chunks) { - // Rasterize non-empty chunk + // Rasterize non-empty chunk (first layer so can override existing chunk data) auto& key = e.Key; + if (key.Layer != 0) + continue; auto& chunk = e.Value; for (int32 i = 0; i < chunk.ModelsCount; i++) { @@ -417,20 +419,9 @@ bool GlobalSignDistanceFieldPass::Render(RenderContext& renderContext, GPUContex data.ModelsCount = chunk.ModelsCount; if (_cb1) context->UpdateCB(_cb1, &data); - GPUShaderProgramCS* cs; - if (key.Layer == 0) - { - // First layer so can override existing chunk data - cs = _csRasterizeModel0; - nonEmptyChunks.Add(key); - } - else - { - // Another layer so need combine with existing chunk data - cs = _csRasterizeModel1; - } - context->Dispatch(cs, chunkDispatchGroups, chunkDispatchGroups, chunkDispatchGroups); - // TODO: don't stall with UAV barrier on D3D12/Vulkan if UAVs don't change between dispatches - only for a sequence of _csRasterizeModel0 dispatches (maybe cache per-shader write/read flags for all UAVs?) + nonEmptyChunks.Add(key); + context->Dispatch(_csRasterizeModel0, chunkDispatchGroups, chunkDispatchGroups, chunkDispatchGroups); + // TODO: don't stall with UAV barrier on D3D12/Vulkan if UAVs don't change between dispatches (maybe cache per-shader write/read flags for all UAVs?) #if GLOBAL_SDF_DEBUG_CHUNKS // Debug draw chunk bounds in world space with number of models in it @@ -443,6 +434,26 @@ bool GlobalSignDistanceFieldPass::Render(RenderContext& renderContext, GPUContex } #endif } + for (auto& e : chunks) + { + // Rasterize non-empty chunk (additive layers so so need combine with existing chunk data) + auto& key = e.Key; + if (key.Layer == 0) + continue; + auto& chunk = e.Value; + for (int32 i = 0; i < chunk.ModelsCount; i++) + { + int32 model = chunk.Models[i]; + data.Models[i] = model; + context->BindSR(i + 1, _modelsTextures[model]); + } + ASSERT_LOW_LAYER(chunk.ModelsCount != 0); + data.ChunkCoord = key.Coord * GLOBAL_SDF_RASTERIZE_CHUNK_SIZE; + data.ModelsCount = chunk.ModelsCount; + if (_cb1) + context->UpdateCB(_cb1, &data); + context->Dispatch(_csRasterizeModel1, chunkDispatchGroups, chunkDispatchGroups, chunkDispatchGroups); + } } // Generate mip out of cascade (empty chunks have distance value 1 which is incorrect so mip will be used as a fallback - lower res) diff --git a/Source/Shaders/GlobalSurfaceAtlas.hlsl b/Source/Shaders/GlobalSurfaceAtlas.hlsl index ef64ac1f4..dab389ab9 100644 --- a/Source/Shaders/GlobalSurfaceAtlas.hlsl +++ b/Source/Shaders/GlobalSurfaceAtlas.hlsl @@ -99,7 +99,7 @@ float4 SampleGlobalSurfaceAtlasTile(const GlobalSurfaceAtlasData data, GlobalSur // Get tile UV and depth at the world position float3 tilePosition = mul(float4(worldPosition, 1), tile.WorldToLocal).xyz; float tileDepth = tilePosition.z / tile.ViewBoundsSize.z; - float2 tileUV = (tilePosition.xy / tile.ViewBoundsSize.xy) + 0.5f; + float2 tileUV = saturate((tilePosition.xy / tile.ViewBoundsSize.xy) + 0.5f); tileUV.y = 1.0 - tileUV.y; float2 atlasUV = tileUV * tile.AtlasRectUV.zw + tile.AtlasRectUV.xy; @@ -143,7 +143,7 @@ float4 SampleGlobalSurfaceAtlas(const GlobalSurfaceAtlasData data, Buffer