From 72e60cfe3086364d4dedd7bc20a85dacc8ebd477 Mon Sep 17 00:00:00 2001 From: Dynamitos Date: Tue, 22 Oct 2024 13:31:58 +0200 Subject: [PATCH] View culling is stupid --- res/shaders/DepthCullingTask.slang | 6 +- res/shaders/terrain/LEB.slang | 8 +- res/shaders/terrain/Parameters.slang | 2 +- res/shaders/terrain/update_utils.slang | 12 +- src/Editor/Asset/MeshLoader.cpp | 2 +- src/Editor/main.cpp | 8 +- src/Engine/Component/Camera.cpp | 2 +- src/Engine/Graphics/CBT/CBT.cpp | 106 ++++++++++-------- src/Engine/Graphics/RenderPass/RenderPass.cpp | 41 +++++-- src/Engine/Graphics/RenderPass/RenderPass.h | 4 +- .../Graphics/RenderPass/TerrainRenderer.cpp | 3 +- 11 files changed, 118 insertions(+), 76 deletions(-) diff --git a/res/shaders/DepthCullingTask.slang b/res/shaders/DepthCullingTask.slang index e229043..0aa964a 100644 --- a/res/shaders/DepthCullingTask.slang +++ b/res/shaders/DepthCullingTask.slang @@ -90,7 +90,7 @@ void taskMain( p.instanceId = pOffsets.instanceOffset + groupID; p.meshletOffset = mesh.meshletOffset; p.cullingOffset = pScene.cullingOffsets[p.instanceId]; - modelViewProjection = mul(mul(pViewParams.projectionMatrix, pViewParams.viewMatrix), instance.transformMatrix); + modelViewProjection = mul(pViewParams.viewProjectionMatrix, instance.transformMatrix); float3 origin = viewToModel(instance.inverseTransformMatrix, float4(0, 0, 0, 1)).xyz; const float offset = 0.0f; float3 corners[4] = { @@ -103,8 +103,8 @@ void taskMain( viewFrustum.sides[1] = computePlane(origin, corners[1], corners[3]); viewFrustum.sides[2] = computePlane(origin, corners[0], corners[1]); viewFrustum.sides[3] = computePlane(origin, corners[3], corners[2]); - //meshVisible = mesh.bounding.insideFrustum(viewFrustum) && isBoxVisible(mesh.bounding); - meshVisible = true; + meshVisible = mesh.bounding.insideFrustum(viewFrustum) && isBoxVisible(mesh.bounding); + //meshVisible = true; } GroupMemoryBarrierWithGroupSync(); if(!meshVisible) diff --git a/res/shaders/terrain/LEB.slang b/res/shaders/terrain/LEB.slang index e629445..162f224 100644 --- a/res/shaders/terrain/LEB.slang +++ b/res/shaders/terrain/LEB.slang @@ -310,9 +310,9 @@ void EvaluateLEB(uint currentID : SV_DispatchThreadID, uint groupIndex: SV_Group EvaluateElementPosition(cHeapID, 0, pParams.geometry.baseDepth, pParams.currentVertexBuffer, parentTri, childTri); // Export the child - pParams.lebPositionBuffer[3 * currentID] = float4((childTri.p[0]), 1.0f); - pParams.lebPositionBuffer[3 * currentID + 1] = float4((childTri.p[1]), 1.0f); - pParams.lebPositionBuffer[3 * currentID + 2] = float4((childTri.p[2]), 1.0f); + pParams.lebPositionBuffer[3 * currentID + 0] = float4(1000 * (childTri.p[0]), 1.0f); + pParams.lebPositionBuffer[3 * currentID + 1] = float4(1000 * (childTri.p[1]), 1.0f); + pParams.lebPositionBuffer[3 * currentID + 2] = float4(1000 * (childTri.p[2]), 1.0f); // Export the fourth element if (pParams.geometry.baseDepth < depth) @@ -321,6 +321,6 @@ void EvaluateLEB(uint currentID : SV_DispatchThreadID, uint groupIndex: SV_Group const uint parentOffset = 3 * pParams.geometry.totalNumElements; // Transform the coordinate to planet space - pParams.lebPositionBuffer[parentOffset + currentID] = float4((cHeapID % 2 == 0 ? parentTri.p[0] : parentTri.p[2]), 1.0f); + pParams.lebPositionBuffer[parentOffset + currentID] = float4(1000 * (cHeapID % 2 == 0 ? parentTri.p[0] : parentTri.p[2]), 1.0f); } } diff --git a/res/shaders/terrain/Parameters.slang b/res/shaders/terrain/Parameters.slang index b321a66..896f079 100644 --- a/res/shaders/terrain/Parameters.slang +++ b/res/shaders/terrain/Parameters.slang @@ -84,7 +84,7 @@ struct ComputeParams // 21 RWStructuredBuffer lebPositionBuffer; // 22 - StructuredBuffer lebMatrixCache; + StructuredBuffer lebMatrixCache; // 23 globallycoherent RWStructuredBuffer debugBuffer; }; diff --git a/res/shaders/terrain/update_utils.slang b/res/shaders/terrain/update_utils.slang index cbe148b..7af302e 100644 --- a/res/shaders/terrain/update_utils.slang +++ b/res/shaders/terrain/update_utils.slang @@ -2,6 +2,7 @@ import Common; import Bisector; import CBT; import Parameters; +import Bounding; // Needs to be defined before including update_utilities struct BisectorGeometry @@ -43,10 +44,10 @@ bool FrustumAABBIntersect(in Frustum frustum, float3 aabbMin, float3 aabbMax) int ClassifyBisector(in BisectorGeometry tri, uint depth) { // Check the triangle's visibility - float3 triNormal = normalize(cross(tri.p[2] - tri.p[1], tri.p[0] - tri.p[1])); + float3 triNormal = normalize(cross(tri.p[2] - tri.p[0], tri.p[1] - tri.p[0])); float3 triCenter = (tri.p[0] + tri.p[1] + tri.p[2]) / 3.0; float3 viewDir = normalize(-triCenter); - float FdotV = dot(viewDir, pViewParams.cameraForward_WS.xyz); + float FdotV = dot(viewDir, -pViewParams.cameraForward_WS.xyz); float VdotN = dot(viewDir, triNormal); // Here we don't use 0 as it introduces stability issues at grazing angles @@ -54,11 +55,12 @@ int ClassifyBisector(in BisectorGeometry tri, uint depth) return BACK_FACE_CULLED; // Compute the triangle's AABB - float3 aabbMin = float3(min(min(tri.p[0].x, tri.p[1].x), tri.p[2].x), min(min(tri.p[0].y, tri.p[1].y), tri.p[2].y), min(min(tri.p[0].z, tri.p[1].z), tri.p[2].z)); - float3 aabbMax = float3(max(max(tri.p[0].x, tri.p[1].x), tri.p[2].x), max(max(tri.p[0].y, tri.p[1].y), tri.p[2].y), max(max(tri.p[0].z, tri.p[1].z), tri.p[2].z)); + AABB aabb; + aabb.minCorner = float3(min(min(tri.p[0].x, tri.p[1].x), tri.p[2].x), min(min(tri.p[0].y, tri.p[1].y), tri.p[2].y), min(min(tri.p[0].z, tri.p[1].z), tri.p[2].z)); + aabb.maxCorner = float3(max(max(tri.p[0].x, tri.p[1].x), tri.p[2].x), max(max(tri.p[0].y, tri.p[1].y), tri.p[2].y), max(max(tri.p[0].z, tri.p[1].z), tri.p[2].z)); // First we do a frustum culling pass - if (!FrustumAABBIntersect(pViewParams.viewFrustum, aabbMin, aabbMax)) + if (!FrustumAABBIntersect(pViewParams.viewFrustum, aabb.minCorner, aabb.maxCorner)) return FRUSTUM_CULLED; // Project the points on screen diff --git a/src/Editor/Asset/MeshLoader.cpp b/src/Editor/Asset/MeshLoader.cpp index f7be451..6333528 100644 --- a/src/Editor/Asset/MeshLoader.cpp +++ b/src/Editor/Asset/MeshLoader.cpp @@ -558,7 +558,7 @@ void MeshLoader::loadGlobalMeshes(const aiScene* scene, const Arrayblas = graphics->createBottomLevelAccelerationStructure(Gfx::BottomLevelASCreateInfo{ .mesh = globalMeshes[meshIndex], }); - vertexData->registerBottomLevelAccelerationStructure(globalMeshes[meshIndex]->blas); + //vertexData->registerBottomLevelAccelerationStructure(globalMeshes[meshIndex]->blas); }); } getThreadPool().runAndWait(std::move(work)); diff --git a/src/Editor/main.cpp b/src/Editor/main.cpp index 0cbf0c1..e957624 100644 --- a/src/Editor/main.cpp +++ b/src/Editor/main.cpp @@ -109,10 +109,10 @@ int main() { //AssetImporter::importTexture(TextureImportArgs{ // .filePath = sourcePath / "import/textures/wgen.png", //}); - // AssetImporter::importMesh(MeshImportArgs{ - // .filePath = sourcePath / "import/models/after-the-rain-vr-sound/source/Whitechapel.glb", - // .importPath = "Whitechapel", - // }); + AssetImporter::importMesh(MeshImportArgs{ + .filePath = sourcePath / "import/models/after-the-rain-vr-sound/source/Whitechapel.glb", + .importPath = "Whitechapel", + }); // AssetImporter::importMesh(MeshImportArgs{521 // .filePath = sourcePath / "import/models/city-suburbs/source/city-suburbs.obj", // .importPath = "suburbs", diff --git a/src/Engine/Component/Camera.cpp b/src/Engine/Component/Camera.cpp index f544071..6c1940b 100644 --- a/src/Engine/Component/Camera.cpp +++ b/src/Engine/Component/Camera.cpp @@ -48,6 +48,6 @@ void Camera::buildViewMatrix() { Vector lookAt = eyePos + getTransform().getForward(); viewMatrix = glm::lookAt(eyePos, lookAt, Vector(0, 1, 0)); cameraPos = eyePos; - cameraForward = -getTransform().getForward(); + cameraForward = getTransform().getForward(); bNeedsViewBuild = false; } diff --git a/src/Engine/Graphics/CBT/CBT.cpp b/src/Engine/Graphics/CBT/CBT.cpp index 6c7145b..14e8629 100644 --- a/src/Engine/Graphics/CBT/CBT.cpp +++ b/src/Engine/Graphics/CBT/CBT.cpp @@ -23,59 +23,76 @@ struct Halfedge { }; Array edges = { Halfedge{0, 1, 2, 4294967295}, - Halfedge{1, 2, 0, 3}, - Halfedge{4, 0, 1, 4294967295}, + Halfedge{4, 2, 0, 3}, + Halfedge{1, 0, 1, 4294967295}, + Halfedge{4, 4, 5, 1}, - Halfedge{1, 5, 3, 8}, - Halfedge{5, 3, 4, 18}, + Halfedge{5, 5, 3, 8}, + Halfedge{1, 3, 4, 18}, + Halfedge{1, 7, 8, 4294967295}, - Halfedge{2, 8, 6, 9}, - Halfedge{5, 6, 7, 4}, + Halfedge{5, 8, 6, 9}, + Halfedge{2, 6, 7, 4}, + Halfedge{5, 10, 11, 7}, - Halfedge{2, 11, 9, 14}, - Halfedge{6, 9, 10, 24}, + Halfedge{6, 11, 9, 14}, + Halfedge{2, 9, 10, 24}, + Halfedge{2, 13, 14, 4294967295}, - Halfedge{3, 14, 12, 15}, - Halfedge{6, 12, 13, 10}, + Halfedge{6, 14, 12, 15}, + Halfedge{3, 12, 13, 10}, + Halfedge{6, 16, 17, 13}, - Halfedge{3, 17, 15, 4294967295}, - Halfedge{7, 15, 16, 30}, + Halfedge{7, 17, 15, 4294967295}, + Halfedge{3, 15, 16, 30}, + Halfedge{4, 19, 20, 5}, - Halfedge{5, 20, 18, 21}, - Halfedge{8, 18, 19, 4294967295}, + Halfedge{8, 20, 18, 21}, + Halfedge{5, 18, 19, 4294967295}, + Halfedge{8, 22, 23, 19}, - Halfedge{5, 23, 21, 26}, - Halfedge{9, 21, 22, 36}, + Halfedge{9, 23, 21, 26}, + Halfedge{5, 21, 22, 36}, + Halfedge{5, 25, 26, 11}, - Halfedge{6, 26, 24, 27}, - Halfedge{9, 24, 25, 22}, + Halfedge{9, 26, 24, 27}, + Halfedge{6, 24, 25, 22}, + Halfedge{9, 28, 29, 25}, - Halfedge{6, 29, 27, 32}, - Halfedge{10, 27, 28, 42}, + Halfedge{10, 29, 27, 32}, + Halfedge{6, 27, 28, 42}, + Halfedge{6, 31, 32, 17}, - Halfedge{7, 32, 30, 33}, - Halfedge{10, 30, 31, 28}, + Halfedge{10, 32, 30, 33}, + Halfedge{7, 30, 31, 28}, + Halfedge{10, 34, 35, 31}, - Halfedge{7, 35, 33, 4294967295}, - Halfedge{11, 33, 34, 48}, + Halfedge{11, 35, 33, 4294967295}, + Halfedge{7, 33, 34, 48}, + Halfedge{8, 37, 38, 23}, - Halfedge{9, 38, 36, 39}, - Halfedge{12, 36, 37, 4294967295}, + Halfedge{12, 38, 36, 39}, + Halfedge{9, 36, 37, 4294967295}, + Halfedge{12, 40, 41, 37}, - Halfedge{9, 41, 39, 44}, - Halfedge{13, 39, 40, 4294967295}, + Halfedge{13, 41, 39, 44}, + Halfedge{9, 39, 40, 4294967295}, + Halfedge{9, 43, 44, 29}, - Halfedge{10, 44, 42, 45}, - Halfedge{13, 42, 43, 40}, + Halfedge{13, 44, 42, 45}, + Halfedge{10, 42, 43, 40}, + Halfedge{13, 46, 47, 43}, - Halfedge{10, 47, 45, 50}, - Halfedge{14, 45, 46, 4294967295}, + Halfedge{14, 47, 45, 50}, + Halfedge{10, 45, 46, 4294967295}, + Halfedge{10, 49, 50, 35}, - Halfedge{11, 50, 48, 51}, - Halfedge{14, 48, 49, 46}, + Halfedge{14, 50, 48, 51}, + Halfedge{11, 48, 49, 46}, + Halfedge{14, 52, 53, 49}, - Halfedge{11, 53, 51, 4294967295}, - Halfedge{15, 51, 52, 4294967295}, + Halfedge{15, 53, 51, 4294967295}, + Halfedge{11, 51, 52, 4294967295}, // Halfedge{1, 1, 2, 5}, Halfedge{2, 2, 0, 36}, Halfedge{6, 0, 1, 39}, Halfedge{1, 4, 5, 51}, Halfedge{7, 5, 3, 48}, // Halfedge{2, 3, 4, 0}, Halfedge{3, 7, 8, 9}, Halfedge{4, 8, 6, 45}, Halfedge{5, 6, 7, 42}, Halfedge{4, 10, 11, 6}, @@ -150,7 +167,7 @@ Matrix3 splittingMatrix(uint32 bitValue) { float b = float(bitValue); float c = 1.0f - b; - return Matrix3({ + return glm::transpose(Matrix3({ 0.0f, b, c, @@ -160,7 +177,7 @@ Matrix3 splittingMatrix(uint32 bitValue) { b, c, 0.0f, - }); + })); } Matrix3 decodeSubdivisionMatrix(uint64 heapID) { @@ -175,19 +192,16 @@ Matrix3 decodeSubdivisionMatrix(uint64 heapID) { void LebMatrixCache::init(Gfx::PGraphics graphics, uint32 depth) { cacheDepth = depth; uint32 matrixCount = 2ULL << cacheDepth; - struct PaddedMatrix { - Matrix3 m; - uint8 pad[12]; - }; - std::vector table(matrixCount); - table[0].m = Matrix3({1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f}); + Matrix3 m; + std::vector table(matrixCount); + table[0] = Matrix3({1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f}); for (uint64 heapID = 1ULL; heapID < (2ULL << cacheDepth); ++heapID) { - table[heapID].m = decodeSubdivisionMatrix(heapID); + table[heapID] = decodeSubdivisionMatrix(heapID); } lebMatrixBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{ .sourceData = { - .size = sizeof(PaddedMatrix) * matrixCount, + .size = sizeof(Matrix3) * matrixCount, .data = (uint8*)table.data(), }, .name = "LebMatrixCache", diff --git a/src/Engine/Graphics/RenderPass/RenderPass.cpp b/src/Engine/Graphics/RenderPass/RenderPass.cpp index 4ad7076..d381343 100644 --- a/src/Engine/Graphics/RenderPass/RenderPass.cpp +++ b/src/Engine/Graphics/RenderPass/RenderPass.cpp @@ -81,15 +81,7 @@ void RenderPass::beginFrame(const Component::Camera& cam) { corners[i] = world / world.w; } - //viewParams.viewFrustum = { - // .planes = - // { - // computePlane(cam.getCameraPosition(), Vector(corners[2]), Vector(corners[0])), - // computePlane(cam.getCameraPosition(), Vector(corners[1]), Vector(corners[3])), - // computePlane(cam.getCameraPosition(), Vector(corners[0]), Vector(corners[1])), - // computePlane(cam.getCameraPosition(), Vector(corners[3]), Vector(corners[2])), - // }, - //}; + extract_planes_from_view_projection_matrix(viewParams.viewProjectionMatrix, viewParams.viewFrustum); viewParamsBuffer->rotateBuffer(sizeof(ViewParameter)); viewParamsBuffer->updateContents(0, sizeof(ViewParameter), &viewParams); @@ -107,3 +99,34 @@ void RenderPass::beginFrame(const Component::Camera& cam) { void RenderPass::setResources(PRenderGraphResources _resources) { resources = _resources; } void RenderPass::setViewport(Gfx::PViewport _viewport) { viewport = _viewport; } + +void RenderPass::normalize_plane(Plane& plane) { + float l = sqrtf(plane.n.x * plane.n.x + plane.n.y * plane.n.y + plane.n.z * plane.n.z); + plane.n.x /= l; + plane.n.y /= l; + plane.n.z /= l; + plane.d /= l; +} + +void RenderPass::extract_planes_from_view_projection_matrix(const Matrix4 viewProj, Frustum& frustum) { + // Compute all the planes + frustum.planes[0] = { + .n = Vector(viewProj[0][0] + viewProj[0][3], viewProj[1][0] + viewProj[1][3], viewProj[2][0] + viewProj[2][3]), + .d = viewProj[3][0] + viewProj[3][3], + }; + frustum.planes[1] = { + .n = Vector(-viewProj[0][0] + viewProj[0][3], -viewProj[1][0] + viewProj[1][3], -viewProj[2][0] + viewProj[2][3]), + .d = -viewProj[3][0] + viewProj[3][3], + }; + frustum.planes[2] = { + .n = Vector(viewProj[0][1] + viewProj[0][3], viewProj[1][1] + viewProj[1][3], viewProj[2][1] + viewProj[2][3]), + .d = viewProj[3][1] + viewProj[3][3], + }; + frustum.planes[3] = { + .n = Vector(-viewProj[0][1] + viewProj[0][3], -viewProj[1][1] + viewProj[1][3], -viewProj[2][1] + viewProj[2][3]), + .d = -viewProj[3][1] + viewProj[3][3], + }; + // Normalize all the planes + for (uint32_t planeIdx = 0; planeIdx < 4; ++planeIdx) + normalize_plane(frustum.planes[planeIdx]); +} \ No newline at end of file diff --git a/src/Engine/Graphics/RenderPass/RenderPass.h b/src/Engine/Graphics/RenderPass/RenderPass.h index 6663ad9..0c2a425 100644 --- a/src/Engine/Graphics/RenderPass/RenderPass.h +++ b/src/Engine/Graphics/RenderPass/RenderPass.h @@ -46,7 +46,9 @@ class RenderPass { return plane; } - + void normalize_plane(Plane& plane); + void extract_planes_from_view_projection_matrix(const Matrix4 viewProj, Frustum& frustum); + struct ViewParameter { Frustum viewFrustum; Matrix4 viewMatrix; diff --git a/src/Engine/Graphics/RenderPass/TerrainRenderer.cpp b/src/Engine/Graphics/RenderPass/TerrainRenderer.cpp index 4dba548..7cca862 100644 --- a/src/Engine/Graphics/RenderPass/TerrainRenderer.cpp +++ b/src/Engine/Graphics/RenderPass/TerrainRenderer.cpp @@ -298,7 +298,7 @@ void TerrainRenderer::setViewport(Gfx::PViewport _viewport, Gfx::PRenderPass ren .rasterizationState = { .polygonMode = Gfx::SE_POLYGON_MODE_LINE, - .cullMode = Gfx::SE_CULL_MODE_NONE, + .cullMode = Gfx::SE_CULL_MODE_BACK_BIT, }, .colorBlend = { @@ -310,6 +310,7 @@ void TerrainRenderer::setViewport(Gfx::PViewport _viewport, Gfx::PRenderPass ren }, }, }, + }; pipeline = graphics->createGraphicsPipeline(std::move(pipelineInfo)); }