Explorar el Código

Add LOD selection to GPU visibility

Panagiotis Christopoulos Charitos hace 2 años
padre
commit
949ad200f7

+ 16 - 11
AnKi/Renderer/GpuVisibility.cpp

@@ -12,6 +12,8 @@
 #include <AnKi/Core/GpuMemory/RebarTransientMemoryPool.h>
 #include <AnKi/Core/GpuMemory/GpuSceneBuffer.h>
 #include <AnKi/Collision/Functions.h>
+#include <AnKi/Shaders/Include/MiscRendererTypes.h>
+#include <AnKi/Core/ConfigSet.h>
 
 namespace anki {
 
@@ -93,25 +95,28 @@ void GpuVisibility::populateRenderGraph(RenderingContext& ctx)
 
 		rpass.bindStorageBuffer(0, 7, m_runCtx.m_mdiDrawCounts);
 
-		struct Uniforms
-		{
-			Vec4 m_clipPlanes[6u];
-
-			UVec3 m_padding;
-			U32 m_aabbCount;
-		} unis;
+		GpuVisibilityUniforms* unis = allocateAndBindUniforms<GpuVisibilityUniforms*>(sizeof(GpuVisibilityUniforms), cmdb, 0, 8);
 
 		Array<Plane, 6> planes;
 		extractClipPlanes(ctx.m_matrices.m_viewProjection, planes);
 		for(U32 i = 0; i < 6; ++i)
 		{
-			unis.m_clipPlanes[i] = Vec4(planes[i].getNormal().xyz(), planes[i].getOffset());
+			unis->m_clipPlanes[i] = Vec4(planes[i].getNormal().xyz(), planes[i].getOffset());
 		}
 
-		unis.m_aabbCount = GpuSceneContiguousArrays::getSingleton().getElementCount(GpuSceneContiguousArrayType::kRenderableBoundingVolumesGBuffer);
-		cmdb.setPushConstants(&unis, sizeof(unis));
+		const U32 aabbCount =
+			GpuSceneContiguousArrays::getSingleton().getElementCount(GpuSceneContiguousArrayType::kRenderableBoundingVolumesGBuffer);
+		unis->m_aabbCount = aabbCount;
+
+		ANKI_ASSERT(kMaxLodCount == 3);
+		unis->m_maxLodDistances[0] = ConfigSet::getSingleton().getLod0MaxDistance();
+		unis->m_maxLodDistances[1] = ConfigSet::getSingleton().getLod1MaxDistance();
+		unis->m_maxLodDistances[2] = kMaxF32;
+		unis->m_maxLodDistances[3] = kMaxF32;
+
+		unis->m_cameraOrigin = ctx.m_matrices.m_cameraTransform.getTranslationPart().xyz();
 
-		dispatchPPCompute(cmdb, 64, 1, unis.m_aabbCount, 1);
+		dispatchPPCompute(cmdb, 64, 1, aabbCount, 1);
 	});
 }
 

+ 13 - 0
AnKi/Shaders/CollisionFunctions.hlsl

@@ -145,3 +145,16 @@ F32 testPlaneAabb(Vec3 planeNormal, F32 planeOffset, Vec3 aabbMin, Vec3 aabbMax)
 	test = testPlanePoint(planeNormal, planeOffset, diagMax);
 	return (test >= 0.0) ? 0.0 : test;
 }
+
+F32 testPlaneSphere(Vec3 planeNormal, F32 planeOffset, Vec3 sphereCenter, F32 sphereRadius)
+{
+	const F32 centerDist = testPlanePoint(planeNormal, planeOffset, sphereCenter);
+	F32 dist = centerDist - sphereRadius;
+	if(dist >= 0.0f)
+	{
+		return dist;
+	}
+
+	dist = centerDist + sphereRadius;
+	return (dist < 0.0f) ? dist : 0.0f;
+}

+ 22 - 13
AnKi/Shaders/GpuVisibility.ankiprog

@@ -6,6 +6,7 @@
 #pragma anki start comp
 
 #include <AnKi/Shaders/Include/GpuSceneTypes.h>
+#include <AnKi/Shaders/Include/MiscRendererTypes.h>
 #include <AnKi/Shaders/CollisionFunctions.hlsl>
 
 // Buffers that point to the GPU scene
@@ -24,15 +25,7 @@
 // The MDI counts. One for each render state bucket
 [[vk::binding(7)]] RWStructuredBuffer<U32> g_mdiDrawCounts;
 
-struct Uniforms
-{
-	Vec4 m_clipPlanes[6u];
-
-	UVec3 m_padding;
-	U32 m_aabbCount;
-};
-
-[[vk::push_constant]] ConstantBuffer<Uniforms> g_unis;
+[[vk::binding(8)]] ConstantBuffer<GpuVisibilityUniforms> g_unis;
 
 [numthreads(64, 1, 1)] void main(UVec3 svDispatchThreadId : SV_DISPATCHTHREADID)
 {
@@ -60,9 +53,24 @@ struct Uniforms
 
 	// TODO HiZ testing
 
-	// TODO LOD selection
-	const U32 lod = 0;
+	// Compute the LOD
+	//
+	const Vec4 nearPlane = g_unis.m_clipPlanes[0];
+	const F32 distFromNearPlane = testPlaneSphere(nearPlane.xyz, nearPlane.w, aabb.m_sphereCenter, -aabb.m_negativeSphereRadius);
 
+	U32 lod;
+	if(distFromNearPlane < g_unis.m_maxLodDistances[0])
+	{
+		lod = 0u;
+	}
+	else if(distFromNearPlane < g_unis.m_maxLodDistances[1])
+	{
+		lod = 1u;
+	}
+	else
+	{
+		lod = 2u;
+	}
 	// Add the drawcall
 	//
 	const U32 renderStateBucket = aabb.m_renderableIndexAndRenderStateBucket & ((1u << 12u) - 1u);
@@ -73,7 +81,8 @@ struct Uniforms
 	indirectIdx += g_drawIndirectArgsOffsets[renderStateBucket];
 
 	const GpuSceneRenderable renderableIn = g_renderables[renderableIdx];
-	const GpuSceneMeshLod meshLod = g_gpuScene.Load<GpuSceneMeshLod>(renderableIn.m_geometryOffset + sizeof(GpuSceneMeshLod) * lod);
+	const U32 meshLodOffset = renderableIn.m_geometryOffset + sizeof(GpuSceneMeshLod) * lod;
+	const GpuSceneMeshLod meshLod = g_gpuScene.Load<GpuSceneMeshLod>(meshLodOffset);
 
 	DrawIndexedIndirectArgs indirect;
 	indirect.m_indexCount = meshLod.m_indexCount;
@@ -84,7 +93,7 @@ struct Uniforms
 	g_drawIndexedIndirectArgs[indirectIdx] = indirect;
 
 	GpuSceneRenderable renderableOut = renderableIn;
-	renderableOut.m_geometryOffset += sizeof(GpuSceneMeshLod) * lod;
+	renderableOut.m_geometryOffset = meshLodOffset;
 	g_instanceRateRenderables[indirectIdx] = renderableOut;
 }
 

+ 13 - 0
AnKi/Shaders/Include/MiscRendererTypes.h

@@ -147,4 +147,17 @@ struct SpotLightExtra
 	Mat4 m_textureMatrix;
 };
 
+struct GpuVisibilityUniforms
+{
+	Vec4 m_clipPlanes[6u];
+
+	UVec3 m_padding1;
+	U32 m_aabbCount;
+
+	Vec4 m_maxLodDistances;
+
+	Vec3 m_cameraOrigin;
+	F32 m_padding2;
+};
+
 ANKI_END_NAMESPACE