From 3809b55ad5e297c5764d39dfa62d1c15a7e1acf7 Mon Sep 17 00:00:00 2001 From: Anders Pistol Date: Mon, 4 Mar 2024 21:29:09 +0100 Subject: [PATCH] Traktor: Begun implementing GPU culling of terrain patches. --- code/Terrain/TerrainComponent.cpp | 53 ++- code/Terrain/TerrainComponent.h | 4 + .../Terrain/Terrain/Shaders/Cull/Cull.xdi | 437 ++++++++++++++++++ .../Terrain/Terrain/Shaders/Cull/Cull.xdm | 6 + 4 files changed, 498 insertions(+), 2 deletions(-) create mode 100644 data/Source/System/Terrain/Terrain/Shaders/Cull/Cull.xdi create mode 100644 data/Source/System/Terrain/Terrain/Shaders/Cull/Cull.xdm diff --git a/code/Terrain/TerrainComponent.cpp b/code/Terrain/TerrainComponent.cpp index 9680da1aea..1380777bf3 100644 --- a/code/Terrain/TerrainComponent.cpp +++ b/code/Terrain/TerrainComponent.cpp @@ -1,6 +1,6 @@ /* * TRAKTOR - * Copyright (c) 2022 Anders Pistol. + * Copyright (c) 2022-2024 Anders Pistol. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this @@ -22,6 +22,7 @@ #include "Terrain/TerrainSurfaceCache.h" #include "World/IWorldRenderPass.h" #include "World/WorldBuildContext.h" +#include "World/WorldHandles.h" #include "World/WorldRenderView.h" #include "World/WorldSetupContext.h" @@ -30,6 +31,8 @@ namespace traktor::terrain namespace { +const resource::Id< render::Shader > c_shaderCull(L"{8BA73DD8-0FD9-4C15-A772-EACC14014AEC}"); + const render::Handle c_handleTerrain_VisualizeLods(L"Terrain_VisualizeLods"); const render::Handle c_handleTerrain_VisualizeMap(L"Terrain_VisualizeMap"); const render::Handle c_handleTerrain_SurfaceAlbedo(L"Terrain_SurfaceAlbedo"); @@ -49,6 +52,10 @@ const render::Handle c_handleTerrain_DebugMap(L"Terrain_DebugMap"); const render::Handle c_handleTerrain_CutEnable(L"Terrain_CutEnable"); const render::Handle c_handleTerrain_PatchData(L"Terrain_PatchData"); +const render::Handle c_handleTerrain_TargetSize(L"Terrain_TargetSize"); +const render::Handle c_handleTerrain_DrawBuffer(L"Terrain_DrawBuffer"); +const render::Handle c_handleTerrain_CulledDrawBuffer(L"Terrain_CulledDrawBuffer"); + const int32_t c_patchLodSteps = 3; const int32_t c_surfaceLodSteps = 3; @@ -101,6 +108,9 @@ bool TerrainComponent::create(const TerrainComponentData& data) if (!m_resourceManager->bind(data.getTerrain(), m_terrain)) return false; + if (!m_resourceManager->bind(c_shaderCull, m_shaderCull)) + return false; + m_heightfield = m_terrain->getHeightfield(); m_patchLodDistance = data.getPatchLodDistance(); @@ -430,6 +440,32 @@ void TerrainComponent::build( m_dataBuffer->unlock(); } + // Cull draw buffer to HiZ target. + if (worldRenderPass.getTechnique() == world::s_techniqueDeferredGBufferWrite) + { + const Vector2 viewSize = worldRenderView.getViewSize(); + + auto renderBlock = renderContext->allocNamed< render::ComputeRenderBlock >(L"Terrain cull"); + + renderBlock->program = m_shaderCull->getProgram().program; + + renderBlock->programParams = renderContext->alloc< render::ProgramParameters >(); + renderBlock->programParams->beginParameters(renderContext); + + worldRenderPass.setProgramParameters(renderBlock->programParams); + + renderBlock->programParams->setVectorParameter(c_handleTerrain_TargetSize, Vector4(viewSize.x, viewSize.y, 0.0f, 0.0f)); + renderBlock->programParams->setBufferViewParameter(c_handleTerrain_DrawBuffer, m_drawBuffer->getBufferView()); + renderBlock->programParams->setBufferViewParameter(c_handleTerrain_CulledDrawBuffer, m_culledDrawBuffer->getBufferView()); + renderBlock->programParams->setBufferViewParameter(c_handleTerrain_PatchData, m_dataBuffer->getBufferView()); + renderBlock->programParams->endParameters(renderContext); + + renderBlock->workSize[0] = (int32_t)m_view[viewIndex].visiblePatches.size(); + + renderContext->compute(renderBlock); + renderContext->compute< render::BarrierRenderBlock >(render::Stage::Compute, render::Stage::Compute, nullptr, 0); + } + // Render all patches using indirect draw. { auto rb = renderContext->allocNamed< render::IndirectRenderBlock >(L"Terrain patches"); @@ -441,7 +477,12 @@ void TerrainComponent::build( rb->vertexBuffer = m_vertexBuffer->getBufferView(); rb->vertexLayout = m_vertexLayout; rb->primitive = render::PrimitiveType::Triangles; - rb->drawBuffer = m_drawBuffer->getBufferView(); + + if (worldRenderPass.getTechnique() == world::s_techniqueDeferredGBufferWrite) + rb->drawBuffer = m_culledDrawBuffer->getBufferView(); + else + rb->drawBuffer = m_drawBuffer->getBufferView(); + rb->drawCount = m_view[viewIndex].visiblePatches.size(); rb->programParams->beginParameters(renderContext); @@ -801,6 +842,14 @@ bool TerrainComponent::createPatches() if (!m_drawBuffer) return false; + m_culledDrawBuffer = m_renderSystem->createBuffer( + render::BuIndirect, + (uint32_t)m_patches.size() * sizeof(render::IndexedIndirectDraw), + false + ); + if (!m_culledDrawBuffer) + return false; + m_dataBuffer = m_renderSystem->createBuffer( render::BuStructured, (uint32_t)m_patches.size() * sizeof(DrawData), diff --git a/code/Terrain/TerrainComponent.h b/code/Terrain/TerrainComponent.h index 33ad5f6a0b..7bbad4d44e 100644 --- a/code/Terrain/TerrainComponent.h +++ b/code/Terrain/TerrainComponent.h @@ -164,6 +164,9 @@ class T_DLLCLASS TerrainComponent : public world::IEntityComponent world::Entity* m_owner; resource::Proxy< Terrain > m_terrain; resource::Proxy< hf::Heightfield > m_heightfield; + + resource::Proxy< render::Shader > m_shaderCull; + AlignedVector< Patch > m_patches; uint32_t m_patchCount; uint32_t m_cacheSize; @@ -171,6 +174,7 @@ class T_DLLCLASS TerrainComponent : public world::IEntityComponent Ref< render::Buffer > m_indexBuffer; Ref< render::Buffer > m_vertexBuffer; Ref< render::Buffer > m_drawBuffer; + Ref< render::Buffer > m_culledDrawBuffer; Ref< render::Buffer > m_dataBuffer; Ref< render::ITexture > m_defaultColorMap; Ref< render::ITexture > m_defaultCutMap; diff --git a/data/Source/System/Terrain/Terrain/Shaders/Cull/Cull.xdi b/data/Source/System/Terrain/Terrain/Shaders/Cull/Cull.xdi new file mode 100644 index 0000000000..cbf27656dc --- /dev/null +++ b/data/Source/System/Terrain/Terrain/Shaders/Cull/Cull.xdi @@ -0,0 +1,437 @@ + + + + + {CD7BAEF8-BA27-4641-A4F8-5B2418CA61AF} + + + -204 + 309 + + Global + + + {82001117-5EC4-4C89-AC44-99BDB80DD00E} + + + 25 + 318 + + x + + + {D49FA81D-23DC-4D88-89DE-2BB75B119F5C} + + + 291 + 450 + + World_View + Matrix + Frame + + + {ABB90199-B133-44AE-BB92-BE5C5C381F39} + + + 383 + 637 + + World_HiZTexture + Texture2D + Frame + + + {EBE8DE46-0230-4EFA-9298-A0D667904DAA} + + + 679 + 587 + + HiZ + + + 1 + 1 + 1 + + + {45D674A1-6AC4-6B4E-B7CB-DC7F9C2EC215} + + + + {38213B60-FC63-A541-BCC2-95E414C2276D} + Bbmn + + + {484ABC89-3116-A645-8DEB-1DD2AD5B66E9} + Bbmx + + + {38C7084D-4F8D-D749-A614-108D37B2EF5D} + View + + + {B53AF0D1-D6CC-9A40-9334-2C4CD642EE5B} + HiZTexture + + + {6D0649E3-ED26-0646-A195-028038D29BD8} + HiZState + + + {652EFABE-595D-9D4D-BC67-5C63D6168B21} + TargetSize + + + + + {5D1C8949-65AE-2046-A34D-469B22E09B20} + Output + Scalar + + + + + + {0D8D0651-6390-42B7-B095-5E135EFF0A08} + + + 401 + 679 + + FtPoint + FtPoint + FtPoint + AdClamp + AdClamp + AdClamp + CfNone + 0 + true + false + + + {068AB477-6E13-43B5-BC99-858E85F280E4} + + + 376 + 721 + + Terrain_TargetSize + Vector + Frame + + + {16622FDE-F912-416F-A8F5-639C65BFB41D} + + + -114 + 196 + + InstanceWorld + + + rotation + DtFloat4 + + + translation + DtFloat4 + + + boundingBoxMin + DtFloat4 + + + boundingBoxMax + DtFloat4 + + + + + {99FDC25F-406C-45F8-9C49-CA1ABD37CBF0} + + + 225 + 217 + + + rotation + translation + boundingBoxMin + boundingBoxMax + + + + {0B4842AF-8301-42BA-8A59-8F749002877B} + + + -3 + -11 + + Terrain_DrawBuffer + + + indexCount + DtInteger1 + + + instanceCount + DtInteger1 + + + firstIndex + DtInteger1 + + + vertexOffset + DtInteger1 + + + firstInstance + DtInteger1 + + + + + {B210749B-2773-47CC-A54F-0C4C950DB6CF} + + + -15 + 91 + + Terrain_CulledDrawBuffer + + + indexCount + DtInteger1 + + + instanceCount + DtInteger1 + + + firstIndex + DtInteger1 + + + vertexOffset + DtInteger1 + + + firstInstance + DtInteger1 + + + + + {6DE9EB4E-1DF3-4579-B9D1-FB65908F81A0} + + + 520 + 14 + + Copy draw + Default + + 1 + 1 + 1 + + + + + {31C42332-0F95-49D2-9B49-0469F96A3AB2} + Index + + + {6A6FC6E9-D058-4351-9FFD-E428F1765CA1} + DrawBuffer + + + {EC05D81B-0CB3-42B8-8FD7-9B25EB804276} + CulledDrawBuffer + + + + + + + {C43244FA-782F-46B2-9AA7-D7987F946F96} + + + 114 + -86 + + Global + + + + + + + {AAE82FD3-522F-43C6-A594-2E13D126E5DB} + + + + {F2E22CA6-DFF3-4B20-A70A-0D7A44EACD8C} + + + + + + {ACC77B35-91B5-4405-ABC8-D0DA24D68178} + + + + {0FF6511C-0293-41A8-830E-81978BD01F7F} + + + + + + {ADB4FC1D-3726-4CC5-B4D5-1E2468274325} + + + + {0FF6511C-0293-41A8-840E-81978BD01F7F} + + + + + + {0FF6511C-0293-41A8-870E-81978BD01F7F} + + + + {38213B60-FC63-A541-BCC2-95E414C2276D} + + + + + + {0FF6511C-0293-41A8-880E-81978BD01F7F} + + + + {484ABC89-3116-A645-8DEB-1DD2AD5B66E9} + + + + + + {1E6639B6-8B58-4694-99E7-C058E3583522} + + + + {38C7084D-4F8D-D749-A614-108D37B2EF5D} + + + + + + {1E6639B6-8B58-4694-99E7-C058E3583522} + + + + {B53AF0D1-D6CC-9A40-9334-2C4CD642EE5B} + + + + + + {82C966B2-7B19-48B2-8FE0-B85FF4E3C504} + + + + {6D0649E3-ED26-0646-A195-028038D29BD8} + + + + + + {1E6639B6-8B58-4694-99E7-C058E3583522} + + + + {652EFABE-595D-9D4D-BC67-5C63D6168B21} + + + + + + {ACC77B35-91B5-4405-ABC8-D0DA24D68178} + + + + {EC05D81B-0CB3-42B8-8FD7-9B25EB804276} + + + + + + {ACC77B35-91B5-4405-ABC8-D0DA24D68178} + + + + {6A6FC6E9-D058-4351-9FFD-E428F1765CA1} + + + + + + {AAE82FD3-522F-43C6-A594-2E13D126E5DB} + + + + {31C42332-0F95-49D2-9B49-0469F96A3AB2} + + + + + diff --git a/data/Source/System/Terrain/Terrain/Shaders/Cull/Cull.xdm b/data/Source/System/Terrain/Terrain/Shaders/Cull/Cull.xdm new file mode 100644 index 0000000000..64c98816e5 --- /dev/null +++ b/data/Source/System/Terrain/Terrain/Shaders/Cull/Cull.xdm @@ -0,0 +1,6 @@ + + + {8BA73DD8-0FD9-4C15-A772-EACC14014AEC} + traktor.render.ShaderGraph + +