diff --git a/Content/Shaders/GlobalSurfaceAtlas.flax b/Content/Shaders/GlobalSurfaceAtlas.flax index 900052f79..a4cb58313 100644 --- a/Content/Shaders/GlobalSurfaceAtlas.flax +++ b/Content/Shaders/GlobalSurfaceAtlas.flax @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7444088469d72ca5bd6f3507726e4ba68a2f550fcd78cfbd5c7a7b2fbee5e982 -size 7113 +oid sha256:adb567f9a7774b558e1cd4ce3e3c69e15b5a1904bb85b2d29527c3ecdc2635db +size 7235 diff --git a/Source/Engine/Renderer/GlobalSurfaceAtlasPass.cpp b/Source/Engine/Renderer/GlobalSurfaceAtlasPass.cpp index 755fb6660..5f2fe6dd9 100644 --- a/Source/Engine/Renderer/GlobalSurfaceAtlasPass.cpp +++ b/Source/Engine/Renderer/GlobalSurfaceAtlasPass.cpp @@ -18,7 +18,8 @@ #include "Engine/Utilities/RectPack.h" // This must match HLSL -#define GLOBAL_SURFACE_ATLAS_OBJECT_SIZE (5 + 6 * 5) // Amount of float4s per-object +#define GLOBAL_SURFACE_ATLAS_OBJECT_BUFFER_STRIDE 6 // Amount of float4s per-object +#define GLOBAL_SURFACE_ATLAS_TILE_BUFFER_STRIDE 5 // Amount of float4s per-tile #define GLOBAL_SURFACE_ATLAS_TILE_PADDING 1 // 1px padding to prevent color bleeding between tiles #define GLOBAL_SURFACE_ATLAS_TILE_PROJ_PLANE_OFFSET 0.1f // Small offset to prevent clipping with the closest triangles (shifts near and far planes) #define GLOBAL_SURFACE_ATLAS_DEBUG_FORCE_REDRAW_TILES 0 // Forces to redraw all object tiles every frame @@ -55,6 +56,7 @@ struct GlobalSurfaceAtlasTile : RectPack Vector3 ViewPosition; Vector3 ViewBoundsSize; Matrix ViewMatrix; + uint16 TileIndex; GlobalSurfaceAtlasTile(uint16 x, uint16 y, uint16 width, uint16 height) : RectPack(x, y, width, height) @@ -118,13 +120,16 @@ public: GPUTexture* AtlasGBuffer2 = nullptr; GPUTexture* AtlasDirectLight = nullptr; DynamicTypedBuffer ObjectsBuffer; + DynamicTypedBuffer TilesBuffer; uint32 ObjectIndexCounter; + uint16 TileIndexCounter; GlobalSurfaceAtlasPass::BindingData Result; GlobalSurfaceAtlasTile* AtlasTiles = nullptr; // TODO: optimize with a single allocation for atlas tiles Dictionary Objects; GlobalSurfaceAtlasCustomBuffer() - : ObjectsBuffer(256 * GLOBAL_SURFACE_ATLAS_OBJECT_SIZE, PixelFormat::R32G32B32A32_Float, false, TEXT("GlobalSurfaceAtlas.ObjectsBuffer")) + : ObjectsBuffer(256 * GLOBAL_SURFACE_ATLAS_OBJECT_BUFFER_STRIDE, PixelFormat::R32G32B32A32_Float, false, TEXT("GlobalSurfaceAtlas.ObjectsBuffer")) + , TilesBuffer(256 * GLOBAL_SURFACE_ATLAS_TILE_BUFFER_STRIDE * 3 / 4, PixelFormat::R32G32B32A32_Float, false, TEXT("GlobalSurfaceAtlas.TilesBuffer")) { } @@ -133,6 +138,7 @@ public: LastFrameAtlasDefragmentation = Engine::FrameCount; SAFE_DELETE(AtlasTiles); ObjectsBuffer.Clear(); + TilesBuffer.Clear(); Objects.Clear(); } @@ -344,20 +350,28 @@ bool GlobalSurfaceAtlasPass::Render(RenderContext& renderContext, GPUContext* co Half2 min(minPos * posToClipMul + posToClipAdd), max(maxPos * posToClipMul + posToClipAdd); \ Vector2 minUV(0, 0), maxUV(1, 1); \ auto* quad = _vertexBuffer->WriteReserve(6); \ - quad[0] = { { max }, { maxUV }, (uint16)object.Index, (uint16)tileIndex }; \ - quad[1] = { { min.X, max.Y }, { minUV.X, maxUV.Y }, (uint16)object.Index, (uint16)tileIndex }; \ - quad[2] = { { min }, { minUV }, (uint16)object.Index, (uint16)tileIndex }; \ + quad[0] = { { max }, { maxUV }, (uint16)object.Index, tile->TileIndex }; \ + quad[1] = { { min.X, max.Y }, { minUV.X, maxUV.Y }, (uint16)object.Index, tile->TileIndex }; \ + quad[2] = { { min }, { minUV }, (uint16)object.Index, tile->TileIndex }; \ quad[3] = quad[2]; \ - quad[4] = { { max.X, min.Y }, { maxUV.X, minUV.Y }, (uint16)object.Index, (uint16)tileIndex }; \ + quad[4] = { { max.X, min.Y }, { maxUV.X, minUV.Y }, (uint16)object.Index, tile->TileIndex }; \ quad[5] = quad[0] #define VB_DRAW() \ _vertexBuffer->Flush(context); \ auto vb = _vertexBuffer->GetBuffer(); \ context->BindVB(ToSpan(&vb, 1)); \ context->DrawInstanced(_vertexBuffer->Data.Count() / sizeof(AtlasTileVertex), 1); + // Add objects into the atlas surfaceAtlasData.ObjectsBuffer.Clear(); + surfaceAtlasData.TilesBuffer.Clear(); surfaceAtlasData.ObjectIndexCounter = 0; + { + // Tile at index 0 is invalid + surfaceAtlasData.TileIndexCounter = 1; + auto* tileData = surfaceAtlasData.TilesBuffer.WriteReserve(GLOBAL_SURFACE_ATLAS_TILE_BUFFER_STRIDE); + Platform::MemoryClear(tileData, sizeof(Vector4) * GLOBAL_SURFACE_ATLAS_TILE_BUFFER_STRIDE); + } _dirtyObjectsBuffer.Clear(); { PROFILE_CPU_NAMED("Draw"); @@ -468,23 +482,22 @@ bool GlobalSurfaceAtlasPass::Render(RenderContext& renderContext, GPUContext* co Matrix::Invert(object->Bounds.Transformation, worldToLocalBounds); // TODO: cache data for static objects to optimize CPU perf (move ObjectsBuffer into surfaceAtlasData) object->Index = surfaceAtlasData.ObjectIndexCounter++; - auto* objectData = surfaceAtlasData.ObjectsBuffer.WriteReserve(GLOBAL_SURFACE_ATLAS_OBJECT_SIZE); + auto* objectData = surfaceAtlasData.ObjectsBuffer.WriteReserve(GLOBAL_SURFACE_ATLAS_OBJECT_BUFFER_STRIDE); objectData[0] = *(Vector4*)&e.Bounds; objectData[1] = Vector4(worldToLocalBounds.M11, worldToLocalBounds.M12, worldToLocalBounds.M13, worldToLocalBounds.M41); objectData[2] = Vector4(worldToLocalBounds.M21, worldToLocalBounds.M22, worldToLocalBounds.M23, worldToLocalBounds.M42); objectData[3] = Vector4(worldToLocalBounds.M31, worldToLocalBounds.M32, worldToLocalBounds.M33, worldToLocalBounds.M43); - objectData[4] = Vector4(object->Bounds.Extents, 0.0f); + objectData[4] = Vector4(object->Bounds.Extents, 0.0f); // w unused + objectData[5] = Vector4::Zero; // w unused + auto tileIndices = reinterpret_cast(&objectData[5]); // xyz used for tile indices packed into uint16 // TODO: try to optimize memory footprint (eg. merge scale into extents and use rotation+offset but reconstruct rotation from two axes with sign) for (int32 tileIndex = 0; tileIndex < 6; tileIndex++) { auto* tile = object->Tiles[tileIndex]; - const int32 tileStart = 5 + tileIndex * 5; if (!tile) - { - // Disable tile - objectData[tileStart + 4] = Vector4::Zero; continue; - } + tile->TileIndex = surfaceAtlasData.TileIndexCounter++; + tileIndices[tileIndex] = tile->TileIndex; // Setup view to render object from the side Vector3 xAxis, yAxis, zAxis = Vector3::Zero; @@ -517,11 +530,12 @@ bool GlobalSurfaceAtlasPass::Render(RenderContext& renderContext, GPUContext* co // Per-tile data const float tileWidth = (float)tile->Width - GLOBAL_SURFACE_ATLAS_TILE_PADDING; const float tileHeight = (float)tile->Height - GLOBAL_SURFACE_ATLAS_TILE_PADDING; - objectData[tileStart + 0] = Vector4(tile->X, tile->Y, tileWidth, tileHeight) * resolutionInv; - objectData[tileStart + 1] = Vector4(tile->ViewMatrix.M11, tile->ViewMatrix.M12, tile->ViewMatrix.M13, tile->ViewMatrix.M41); - objectData[tileStart + 2] = Vector4(tile->ViewMatrix.M21, tile->ViewMatrix.M22, tile->ViewMatrix.M23, tile->ViewMatrix.M42); - objectData[tileStart + 3] = Vector4(tile->ViewMatrix.M31, tile->ViewMatrix.M32, tile->ViewMatrix.M33, tile->ViewMatrix.M43); - objectData[tileStart + 4] = Vector4(tile->ViewBoundsSize, 1.0f); + auto* tileData = surfaceAtlasData.TilesBuffer.WriteReserve(GLOBAL_SURFACE_ATLAS_TILE_BUFFER_STRIDE); + tileData[0] = Vector4(tile->X, tile->Y, tileWidth, tileHeight) * resolutionInv; + tileData[1] = Vector4(tile->ViewMatrix.M11, tile->ViewMatrix.M12, tile->ViewMatrix.M13, tile->ViewMatrix.M41); + tileData[2] = Vector4(tile->ViewMatrix.M21, tile->ViewMatrix.M22, tile->ViewMatrix.M23, tile->ViewMatrix.M42); + tileData[3] = Vector4(tile->ViewMatrix.M31, tile->ViewMatrix.M32, tile->ViewMatrix.M33, tile->ViewMatrix.M43); + tileData[4] = Vector4(tile->ViewBoundsSize, 0.0f); // w unused } } } @@ -548,6 +562,7 @@ bool GlobalSurfaceAtlasPass::Render(RenderContext& renderContext, GPUContext* co { PROFILE_GPU_CPU("Update Objects"); surfaceAtlasData.ObjectsBuffer.Flush(context); + surfaceAtlasData.TilesBuffer.Flush(context); } // Rasterize world geometry material properties into Global Surface Atlas @@ -670,6 +685,7 @@ bool GlobalSurfaceAtlasPass::Render(RenderContext& renderContext, GPUContext* co result.Atlas[3] = surfaceAtlasData.AtlasGBuffer2; result.Atlas[4] = surfaceAtlasData.AtlasDirectLight; result.Objects = surfaceAtlasData.ObjectsBuffer.GetBuffer(); + result.Tiles = surfaceAtlasData.TilesBuffer.GetBuffer(); result.GlobalSurfaceAtlas.Resolution = (float)resolution; result.GlobalSurfaceAtlas.ObjectsCount = surfaceAtlasData.Objects.Count(); surfaceAtlasData.Result = result; @@ -693,10 +709,11 @@ bool GlobalSurfaceAtlasPass::Render(RenderContext& renderContext, GPUContext* co context->BindSR(2, surfaceAtlasData.AtlasGBuffer2->View()); context->BindSR(3, surfaceAtlasData.AtlasDepth->View()); context->BindSR(4, surfaceAtlasData.ObjectsBuffer.GetBuffer()->View()); + context->BindSR(5, surfaceAtlasData.TilesBuffer.GetBuffer()->View()); for (int32 i = 0; i < 4; i++) { - context->BindSR(i + 5, bindingDataSDF.Cascades[i]->ViewVolume()); - context->BindSR(i + 9, bindingDataSDF.CascadeMips[i]->ViewVolume()); + context->BindSR(i + 6, bindingDataSDF.Cascades[i]->ViewVolume()); + context->BindSR(i + 10, bindingDataSDF.CascadeMips[i]->ViewVolume()); } context->BindCB(0, _cb0); Data0 data; @@ -827,13 +844,14 @@ void GlobalSurfaceAtlasPass::RenderDebug(RenderContext& renderContext, GPUContex context->BindSR(i + 4, bindingDataSDF.CascadeMips[i]->ViewVolume()); } context->BindSR(8, bindingData.Objects ? bindingData.Objects->View() : nullptr); - context->BindSR(9, bindingData.Atlas[0]->View()); + context->BindSR(9, bindingData.Tiles ? bindingData.Tiles->View() : nullptr); + context->BindSR(10, bindingData.Atlas[0]->View()); { //GPUTexture* tex = bindingData.Atlas[1]; // Preview diffuse //GPUTexture* tex = bindingData.Atlas[2]; // Preview normals //GPUTexture* tex = bindingData.Atlas[3]; // Preview roughness/metalness/ao GPUTexture* tex = bindingData.Atlas[4]; // Preview direct light - context->BindSR(10, tex->View()); + context->BindSR(11, tex->View()); } context->SetState(_psDebug); context->SetRenderTarget(output->View()); diff --git a/Source/Engine/Renderer/GlobalSurfaceAtlasPass.h b/Source/Engine/Renderer/GlobalSurfaceAtlasPass.h index 2b225bc46..68a4da65d 100644 --- a/Source/Engine/Renderer/GlobalSurfaceAtlasPass.h +++ b/Source/Engine/Renderer/GlobalSurfaceAtlasPass.h @@ -23,6 +23,7 @@ public: { GPUTexture* Atlas[5]; GPUBuffer* Objects; + GPUBuffer* Tiles; GlobalSurfaceAtlasData GlobalSurfaceAtlas; }; diff --git a/Source/Shaders/GlobalSurfaceAtlas.hlsl b/Source/Shaders/GlobalSurfaceAtlas.hlsl index 540425a8b..0fbec4531 100644 --- a/Source/Shaders/GlobalSurfaceAtlas.hlsl +++ b/Source/Shaders/GlobalSurfaceAtlas.hlsl @@ -4,7 +4,8 @@ #include "./Flax/Collisions.hlsl" // This must match C++ -#define GLOBAL_SURFACE_ATLAS_OBJECT_SIZE (5 + 6 * 5) // Amount of float4s per-object +#define GLOBAL_SURFACE_ATLAS_OBJECT_BUFFER_STRIDE 6 // Amount of float4s per-object +#define GLOBAL_SURFACE_ATLAS_TILE_BUFFER_STRIDE 5 // Amount of float4s per-tile #define GLOBAL_SURFACE_ATLAS_TILE_NORMAL_THRESHOLD 0.1f // Cut-off value for tiles transitions blending during sampling #define GLOBAL_SURFACE_ATLAS_TILE_PROJ_PLANE_OFFSET 0.1f // Small offset to prevent clipping with the closest triangles (shifts near and far planes) @@ -13,7 +14,6 @@ struct GlobalSurfaceTile float4 AtlasRectUV; float4x4 WorldToLocal; float3 ViewBoundsSize; - bool Enabled; }; struct GlobalSurfaceObject @@ -22,24 +22,26 @@ struct GlobalSurfaceObject float BoundsRadius; float4x4 WorldToLocal; float3 Extent; + uint TileIndices[6]; }; float4 LoadGlobalSurfaceAtlasObjectBounds(Buffer objects, uint objectIndex) { // This must match C++ - const uint objectStart = objectIndex * GLOBAL_SURFACE_ATLAS_OBJECT_SIZE; + const uint objectStart = objectIndex * GLOBAL_SURFACE_ATLAS_OBJECT_BUFFER_STRIDE; return objects.Load(objectStart); } GlobalSurfaceObject LoadGlobalSurfaceAtlasObject(Buffer objects, uint objectIndex) { // This must match C++ - const uint objectStart = objectIndex * GLOBAL_SURFACE_ATLAS_OBJECT_SIZE; + const uint objectStart = objectIndex * GLOBAL_SURFACE_ATLAS_OBJECT_BUFFER_STRIDE; float4 vector0 = objects.Load(objectStart + 0); float4 vector1 = objects.Load(objectStart + 1); float4 vector2 = objects.Load(objectStart + 2); float4 vector3 = objects.Load(objectStart + 3); float4 vector4 = objects.Load(objectStart + 4); // w unused + float4 vector5 = objects.Load(objectStart + 5); // w unused GlobalSurfaceObject object = (GlobalSurfaceObject)0; object.BoundsPosition = vector0.xyz; object.BoundsRadius = vector0.w; @@ -48,19 +50,27 @@ GlobalSurfaceObject LoadGlobalSurfaceAtlasObject(Buffer objects, uint ob object.WorldToLocal[2] = float4(vector3.xyz, 0.0f); object.WorldToLocal[3] = float4(vector1.w, vector2.w, vector3.w, 1.0f); object.Extent = vector4.xyz; + uint vector5x = asuint(vector5.x); + uint vector5y = asuint(vector5.y); + uint vector5z = asuint(vector5.z); + object.TileIndices[0] = vector5x & 0xffff; // Limitation on max 65k active tiles + object.TileIndices[1] = vector5x >> 16; + object.TileIndices[2] = vector5y & 0xffff; + object.TileIndices[3] = vector5y >> 16; + object.TileIndices[4] = vector5z & 0xffff; + object.TileIndices[5] = vector5z >> 16; return object; } -GlobalSurfaceTile LoadGlobalSurfaceAtlasTile(Buffer objects, uint objectIndex, uint tileIndex) +GlobalSurfaceTile LoadGlobalSurfaceAtlasTile(Buffer objects, uint tileIndex) { // This must match C++ - const uint objectStart = objectIndex * GLOBAL_SURFACE_ATLAS_OBJECT_SIZE; - const uint tileStart = objectStart + 5 + tileIndex * 5; + const uint tileStart = tileIndex * GLOBAL_SURFACE_ATLAS_TILE_BUFFER_STRIDE; float4 vector0 = objects.Load(tileStart + 0); float4 vector1 = objects.Load(tileStart + 1); float4 vector2 = objects.Load(tileStart + 2); float4 vector3 = objects.Load(tileStart + 3); - float4 vector4 = objects.Load(tileStart + 4); + float4 vector4 = objects.Load(tileStart + 4); // w unused GlobalSurfaceTile tile = (GlobalSurfaceTile)0; tile.AtlasRectUV = vector0.xyzw; tile.WorldToLocal[0] = float4(vector1.xyz, 0.0f); @@ -68,7 +78,6 @@ GlobalSurfaceTile LoadGlobalSurfaceAtlasTile(Buffer objects, uint object tile.WorldToLocal[2] = float4(vector3.xyz, 0.0f); tile.WorldToLocal[3] = float4(vector1.w, vector2.w, vector3.w, 1.0f); tile.ViewBoundsSize = vector4.xyz; - tile.Enabled = vector4.w > 0; return tile; } @@ -138,7 +147,7 @@ float4 SampleGlobalSurfaceAtlasTile(const GlobalSurfaceAtlasData data, GlobalSur } // Samples the Global Surface Atlas and returns the lighting (with opacity) at the given world location (and direction). -float4 SampleGlobalSurfaceAtlas(const GlobalSurfaceAtlasData data, Buffer objects, Texture2D depth, Texture2D atlas, float3 worldPosition, float3 worldNormal) +float4 SampleGlobalSurfaceAtlas(const GlobalSurfaceAtlasData data, Buffer objects, Buffer tiles, Texture2D depth, Texture2D atlas, float3 worldPosition, float3 worldNormal) { float4 result = float4(0, 0, 0, 0); float surfaceThreshold = 20.0f; // Additional threshold between object or tile size compared with input data (error due to SDF or LOD incorrect appearance) @@ -157,25 +166,24 @@ float4 SampleGlobalSurfaceAtlas(const GlobalSurfaceAtlasData data, Buffer GLOBAL_SURFACE_ATLAS_TILE_NORMAL_THRESHOLD * GLOBAL_SURFACE_ATLAS_TILE_NORMAL_THRESHOLD) + uint tileIndex = object.TileIndices[localNormal.x > 0.0f ? 0 : 1]; + if (localNormalSq.x > GLOBAL_SURFACE_ATLAS_TILE_NORMAL_THRESHOLD * GLOBAL_SURFACE_ATLAS_TILE_NORMAL_THRESHOLD && tileIndex != 0) { - uint tileIndex = localNormal.x > 0.0f ? 0 : 1; - GlobalSurfaceTile tile = LoadGlobalSurfaceAtlasTile(objects, objectIndex, tileIndex); + GlobalSurfaceTile tile = LoadGlobalSurfaceAtlasTile(tiles, tileIndex); result += SampleGlobalSurfaceAtlasTile(data, tile, depth, atlas, worldPosition, worldNormal, surfaceThreshold); } - if (localNormalSq.y > GLOBAL_SURFACE_ATLAS_TILE_NORMAL_THRESHOLD * GLOBAL_SURFACE_ATLAS_TILE_NORMAL_THRESHOLD) + tileIndex = object.TileIndices[localNormal.y > 0.0f ? 2 : 3]; + if (localNormalSq.y > GLOBAL_SURFACE_ATLAS_TILE_NORMAL_THRESHOLD * GLOBAL_SURFACE_ATLAS_TILE_NORMAL_THRESHOLD && tileIndex != 0) { - uint tileIndex = localNormal.y > 0.0f ? 2 : 3; - GlobalSurfaceTile tile = LoadGlobalSurfaceAtlasTile(objects, objectIndex, tileIndex); + GlobalSurfaceTile tile = LoadGlobalSurfaceAtlasTile(tiles, tileIndex); result += SampleGlobalSurfaceAtlasTile(data, tile, depth, atlas, worldPosition, worldNormal, surfaceThreshold); } - if (localNormalSq.z > GLOBAL_SURFACE_ATLAS_TILE_NORMAL_THRESHOLD * GLOBAL_SURFACE_ATLAS_TILE_NORMAL_THRESHOLD) + tileIndex = object.TileIndices[localNormal.z > 0.0f ? 4 : 5]; + if (localNormalSq.z > GLOBAL_SURFACE_ATLAS_TILE_NORMAL_THRESHOLD * GLOBAL_SURFACE_ATLAS_TILE_NORMAL_THRESHOLD && tileIndex != 0) { - uint tileIndex = localNormal.z > 0.0f ? 4 : 5; - GlobalSurfaceTile tile = LoadGlobalSurfaceAtlasTile(objects, objectIndex, tileIndex); + GlobalSurfaceTile tile = LoadGlobalSurfaceAtlasTile(tiles, tileIndex); result += SampleGlobalSurfaceAtlasTile(data, tile, depth, atlas, worldPosition, worldNormal, surfaceThreshold); } } diff --git a/Source/Shaders/GlobalSurfaceAtlas.shader b/Source/Shaders/GlobalSurfaceAtlas.shader index cd9f1cba7..4e19ef772 100644 --- a/Source/Shaders/GlobalSurfaceAtlas.shader +++ b/Source/Shaders/GlobalSurfaceAtlas.shader @@ -67,8 +67,9 @@ 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); -Texture3D GlobalSDFTex[4] : register(t5); -Texture3D GlobalSDFMip[4] : register(t9); +Buffer GlobalSurfaceAtlasTiles : register(t5); +Texture3D GlobalSDFTex[4] : register(t6); +Texture3D GlobalSDFMip[4] : register(t10); // Pixel shader for Global Surface Atlas shading with direct light contribution META_PS(true, FEATURE_LEVEL_SM5) @@ -78,7 +79,7 @@ float4 PS_DirectLighting(AtlasVertexOutput input) : SV_Target { // Load current tile info //GlobalSurfaceObject object = LoadGlobalSurfaceAtlasObject(GlobalSurfaceAtlasObjects, input.Index.x); - GlobalSurfaceTile tile = LoadGlobalSurfaceAtlasTile(GlobalSurfaceAtlasObjects, input.Index.x, input.Index.y); + GlobalSurfaceTile tile = LoadGlobalSurfaceAtlasTile(GlobalSurfaceAtlasTiles, input.Index.y); float2 atlasUV = input.TileUV * tile.AtlasRectUV.zw + tile.AtlasRectUV.xy; // Load GBuffer sample from atlas @@ -161,8 +162,9 @@ float4 PS_DirectLighting(AtlasVertexOutput input) : SV_Target Texture3D GlobalSDFTex[4] : register(t0); Texture3D GlobalSDFMip[4] : register(t4); Buffer GlobalSurfaceAtlasObjects : register(t8); -Texture2D GlobalSurfaceAtlasDepth : register(t9); -Texture2D GlobalSurfaceAtlasTex : register(t10); +Buffer GlobalSurfaceAtlasTiles : register(t9); +Texture2D GlobalSurfaceAtlasDepth : register(t10); +Texture2D GlobalSurfaceAtlasTex : register(t11); // Pixel shader for Global Surface Atlas debug drawing META_PS(true, FEATURE_LEVEL_SM5) @@ -185,7 +187,7 @@ float4 PS_Debug(Quad_VS2PS input) : SV_Target //return float4(hit.HitNormal * 0.5f + 0.5f, 1); // Sample Global Surface Atlas at the hit location - float4 surfaceColor = SampleGlobalSurfaceAtlas(GlobalSurfaceAtlas, GlobalSurfaceAtlasObjects, GlobalSurfaceAtlasDepth, GlobalSurfaceAtlasTex, hit.GetHitPosition(trace), -viewRay); + float4 surfaceColor = SampleGlobalSurfaceAtlas(GlobalSurfaceAtlas, GlobalSurfaceAtlasObjects, GlobalSurfaceAtlasTiles, GlobalSurfaceAtlasDepth, GlobalSurfaceAtlasTex, hit.GetHitPosition(trace), -viewRay); return float4(surfaceColor.rgb, 1); }