Browse Source

Add an additional visibility test that helps probe generation

Panagiotis Christopoulos Charitos 2 years ago
parent
commit
401d54a3b2

+ 1 - 0
AnKi/Renderer/ForwardShading.cpp

@@ -37,6 +37,7 @@ void ForwardShading::populateRenderGraph(RenderingContext& ctx)
 	visIn.m_gatherAabbIndices = g_dbgCVar.get();
 	RenderTargetHandle hzb = getRenderer().getGBuffer().getHzbRt();
 	visIn.m_hzbRt = &hzb;
+	visIn.m_finalRenderTargetSize = getRenderer().getInternalResolution();
 
 	getRenderer().getGpuVisibility().populateRenderGraph(visIn, m_runCtx.m_visOut);
 }

+ 1 - 0
AnKi/Renderer/GBuffer.cpp

@@ -177,6 +177,7 @@ void GBuffer::populateRenderGraph(RenderingContext& ctx)
 		visIn.m_rgraph = &rgraph;
 		visIn.m_hzbRt = &m_runCtx.m_hzbRt;
 		visIn.m_gatherAabbIndices = g_dbgCVar.get();
+		visIn.m_finalRenderTargetSize = getRenderer().getInternalResolution();
 
 		getRenderer().getGpuVisibility().populateRenderGraph(visIn, visOut);
 

+ 2 - 0
AnKi/Renderer/IndirectDiffuseProbes.cpp

@@ -244,6 +244,7 @@ void IndirectDiffuseProbes::populateRenderGraph(RenderingContext& rctx)
 			visIn.m_lodReferencePoint = cellCenter;
 			visIn.m_lodDistances = lodDistances;
 			visIn.m_rgraph = &rgraph;
+			visIn.m_finalRenderTargetSize = UVec2(m_tileSize);
 
 			getRenderer().getGpuVisibility().populateRenderGraph(visIn, visOuts[i]);
 		}
@@ -324,6 +325,7 @@ void IndirectDiffuseProbes::populateRenderGraph(RenderingContext& rctx)
 				visIn.m_lodReferencePoint = cellCenter;
 				visIn.m_lodDistances = lodDistances;
 				visIn.m_rgraph = &rgraph;
+				visIn.m_finalRenderTargetSize = UVec2(m_shadowMapping.m_rtDescr.m_height);
 
 				getRenderer().getGpuVisibility().populateRenderGraph(visIn, shadowVisOuts[i]);
 			}

+ 2 - 0
AnKi/Renderer/ProbeReflections.cpp

@@ -367,6 +367,7 @@ void ProbeReflections::populateRenderGraph(RenderingContext& rctx)
 		visIn.m_lodReferencePoint = probeToRefresh->getWorldPosition();
 		visIn.m_lodDistances = lodDistances;
 		visIn.m_rgraph = &rgraph;
+		visIn.m_finalRenderTargetSize = UVec2(m_gbuffer.m_tileSize);
 
 		getRenderer().getGpuVisibility().populateRenderGraph(visIn, visOuts[i]);
 	}
@@ -439,6 +440,7 @@ void ProbeReflections::populateRenderGraph(RenderingContext& rctx)
 			visIn.m_lodReferencePoint = probeToRefresh->getWorldPosition();
 			visIn.m_lodDistances = lodDistances;
 			visIn.m_rgraph = &rgraph;
+			visIn.m_finalRenderTargetSize = UVec2(m_shadowMapping.m_rtDescr.m_height);
 
 			getRenderer().getGpuVisibility().populateRenderGraph(visIn, shadowVisOuts[i]);
 		}

+ 2 - 0
AnKi/Renderer/ShadowMapping.cpp

@@ -397,6 +397,7 @@ void ShadowMapping::processLights(RenderingContext& ctx)
 			visIn.m_lodDistances = lodDistances;
 			visIn.m_hzbRt = &hzbGenIn.m_cascades[cascade].m_hzbRt;
 			visIn.m_rgraph = &rgraph;
+			visIn.m_finalRenderTargetSize = work.m_viewport.zw();
 
 			getRenderer().getGpuVisibility().populateRenderGraph(visIn, work.m_visOut);
 
@@ -538,6 +539,7 @@ void ShadowMapping::processLights(RenderingContext& ctx)
 			visIn.m_rgraph = &rgraph;
 			visIn.m_viewProjectionMatrix = lightc->getSpotLightViewProjectionMatrix();
 			visIn.m_hashVisibles = true;
+			visIn.m_finalRenderTargetSize = atlasViewport.zw();
 
 			GpuVisibilityOutput visOut;
 			getRenderer().getGpuVisibility().populateRenderGraph(visIn, visOut);

+ 3 - 0
AnKi/Renderer/Utils/GpuVisibility.cpp

@@ -62,6 +62,7 @@ void GpuVisibility::populateRenderGraphInternal(Bool distanceBased, BaseGpuVisib
 	public:
 		RenderTargetHandle m_hzbRt;
 		Mat4 m_viewProjMat;
+		UVec2 m_finalRenderTargetSize;
 	};
 
 	FrustumTestData* frustumTestData = nullptr;
@@ -79,6 +80,7 @@ void GpuVisibility::populateRenderGraphInternal(Bool distanceBased, BaseGpuVisib
 		frustumTestData = newInstance<FrustumTestData>(getRenderer().getFrameMemoryPool());
 		const FrustumGpuVisibilityInput& fin = static_cast<FrustumGpuVisibilityInput&>(in);
 		frustumTestData->m_viewProjMat = fin.m_viewProjectionMatrix;
+		frustumTestData->m_finalRenderTargetSize = fin.m_finalRenderTargetSize;
 	}
 
 	U32 aabbCount = 0;
@@ -303,6 +305,7 @@ void GpuVisibility::populateRenderGraphInternal(Bool distanceBased, BaseGpuVisib
 
 			unis->m_lodReferencePoint = lodReferencePoint;
 			unis->m_viewProjectionMat = frustumTestData->m_viewProjMat;
+			unis->m_finalRenderTargetSize = Vec2(frustumTestData->m_finalRenderTargetSize);
 
 			if(frustumTestData->m_hzbRt.isValid())
 			{

+ 5 - 0
AnKi/Renderer/Utils/GpuVisibility.h

@@ -34,6 +34,10 @@ class FrustumGpuVisibilityInput : public BaseGpuVisibilityInput
 {
 public:
 	Mat4 m_viewProjectionMatrix;
+
+	/// The size of the render target the visibility results will be used on. Used to kill objects that don't touch the sampling positions.
+	UVec2 m_finalRenderTargetSize;
+
 	const RenderTargetHandle* m_hzbRt = nullptr; ///< Optional.
 };
 
@@ -75,6 +79,7 @@ public:
 	void populateRenderGraph(FrustumGpuVisibilityInput& in, GpuVisibilityOutput& out)
 	{
 		ANKI_ASSERT(in.m_viewProjectionMatrix != Mat4::getZero());
+		ANKI_ASSERT(in.m_finalRenderTargetSize != UVec2(0u));
 		populateRenderGraphInternal(false, in, out);
 	}
 

+ 9 - 0
AnKi/Shaders/GpuVisibility.ankiprog

@@ -110,6 +110,15 @@ struct DrawIndirectArgsWithPadding
 	aabbMinDepth = saturate(aabbMinDepth);
 	if(any(minNdc > 1.0f) || any(maxNdc < -1.0f))
 	{
+		// Outside of the screen
+		return;
+	}
+
+	const Vec2 windowCoordsMin = ndcToUv(minNdc) * g_consts.m_finalRenderTargetSize;
+	const Vec2 windowCoordsMax = ndcToUv(maxNdc) * g_consts.m_finalRenderTargetSize;
+	if(any(round(windowCoordsMin) == round(windowCoordsMax)))
+	{
+		// Doesn't touch the sampling points
 		return;
 	}
 

+ 2 - 0
AnKi/Shaders/Include/GpuVisibilityTypes.h

@@ -19,6 +19,8 @@ struct FrustumGpuVisibilityConstants
 	F32 m_padding3;
 
 	Mat4 m_viewProjectionMat;
+
+	Vec2 m_finalRenderTargetSize;
 };
 
 struct DistanceGpuVisibilityConstants

+ 6 - 0
AnKi/Shaders/Intellisense.hlsl

@@ -212,6 +212,12 @@ U32 NonUniformResourceIndex(U32 x);
 template<typename T>
 T rsqrt(T x);
 
+template<typename T>
+T round(T x);
+
+template<typename T>
+T ceil(T x);
+
 // Atomics
 
 template<typename T>