Przeglądaj źródła

Some fix/opt for varying precision. Mitigate the C-buffer visibility delay

Panagiotis Christopoulos Charitos 3 lat temu
rodzic
commit
5faff19c56

+ 11 - 1
AnKi/Scene/Components/FrustumComponent.cpp

@@ -35,7 +35,17 @@ Bool FrustumComponent::updateInternal()
 	ANKI_ASSERT(m_frustumType != FrustumType::COUNT);
 	ANKI_ASSERT(m_frustumType != FrustumType::COUNT);
 
 
 	Bool updated = false;
 	Bool updated = false;
-	m_prevViewProjMat = m_viewProjMat;
+
+	for(U32 i = kPrevMatrixHistory - 1; i != 0; --i)
+	{
+		m_prevViewProjMats[i] = m_prevViewProjMats[i - 1];
+		m_prevViewMats[i] = m_prevViewMats[i - 1];
+		m_prevProjMats[i] = m_prevProjMats[i - 1];
+	}
+
+	m_prevViewProjMats[0] = m_viewProjMat;
+	m_prevViewMats[0] = m_viewMat;
+	m_prevProjMats[0] = m_projMat;
 
 
 	// Update the shape
 	// Update the shape
 	if(m_shapeMarkedForUpdate)
 	if(m_shapeMarkedForUpdate)

+ 21 - 3
AnKi/Scene/Components/FrustumComponent.h

@@ -244,9 +244,23 @@ public:
 		return m_viewProjMat;
 		return m_viewProjMat;
 	}
 	}
 
 
-	const Mat4& getPreviousViewProjectionMatrix() const
+	/// @param nMinusOneFrame The number of the previous frame. If 0 means the previous frame, 1 means the
+	///                       previous-previous frame.
+	const Mat4& getPreviousViewProjectionMatrix(U32 nMinusOneFrame = 0) const
 	{
 	{
-		return m_prevViewProjMat;
+		return m_prevViewProjMats[nMinusOneFrame];
+	}
+
+	/// @see getPreviousViewProjectionMatrix.
+	const Mat3x4& getPreviousViewMatrix(U32 nMinusOneFrame = 0) const
+	{
+		return m_prevViewMats[nMinusOneFrame];
+	}
+
+	/// @see getPreviousViewProjectionMatrix.
+	const Mat4& getPreviousProjectionMatrix(U32 nMinusOneFrame = 0) const
+	{
+		return m_prevProjMats[nMinusOneFrame];
 	}
 	}
 
 
 	/// Check if a shape is inside the frustum.
 	/// Check if a shape is inside the frustum.
@@ -423,7 +437,11 @@ private:
 	Mat4 m_projMat = Mat4::getIdentity(); ///< Projection matrix
 	Mat4 m_projMat = Mat4::getIdentity(); ///< Projection matrix
 	Mat3x4 m_viewMat = Mat3x4::getIdentity(); ///< View matrix
 	Mat3x4 m_viewMat = Mat3x4::getIdentity(); ///< View matrix
 	Mat4 m_viewProjMat = Mat4::getIdentity(); ///< View projection matrix
 	Mat4 m_viewProjMat = Mat4::getIdentity(); ///< View projection matrix
-	Mat4 m_prevViewProjMat = Mat4::getIdentity();
+
+	static constexpr U32 kPrevMatrixHistory = 2;
+	Array<Mat3x4, kPrevMatrixHistory> m_prevViewMats = {Mat3x4::getIdentity(), Mat3x4::getIdentity()};
+	Array<Mat4, kPrevMatrixHistory> m_prevProjMats = {Mat4::getIdentity(), Mat4::getIdentity()};
+	Array<Mat4, kPrevMatrixHistory> m_prevViewProjMats = {Mat4::getIdentity(), Mat4::getIdentity()};
 
 
 	/// How far to render shadows for this frustum. If negative it's the m_frustum's far.
 	/// How far to render shadows for this frustum. If negative it's the m_frustum's far.
 	F32 m_effectiveShadowDistance = -1.0f;
 	F32 m_effectiveShadowDistance = -1.0f;

+ 9 - 6
AnKi/Scene/Visibility.cpp

@@ -187,13 +187,16 @@ void FillRasterizerWithCoverageTask::fill()
 	ANKI_ASSERT(width > 0 && height > 0 && depthBuff.getSize() > 0);
 	ANKI_ASSERT(width > 0 && height > 0 && depthBuff.getSize() > 0);
 
 
 	// Init the rasterizer
 	// Init the rasterizer
-	m_frcCtx->m_r = alloc.newInstance<SoftwareRasterizer>();
-	m_frcCtx->m_r->init(alloc);
-	m_frcCtx->m_r->prepare(Mat4(m_frcCtx->m_frc->getViewMatrix(), Vec4(0.0f, 0.0f, 0.0f, 1.0f)),
-						   m_frcCtx->m_frc->getProjectionMatrix(), width, height);
+	if(true)
+	{
+		m_frcCtx->m_r = alloc.newInstance<SoftwareRasterizer>();
+		m_frcCtx->m_r->init(alloc);
+		m_frcCtx->m_r->prepare(Mat4(m_frcCtx->m_frc->getPreviousViewMatrix(1), Vec4(0.0f, 0.0f, 0.0f, 1.0f)),
+							   m_frcCtx->m_frc->getPreviousProjectionMatrix(1), width, height);
 
 
-	// Do the work
-	m_frcCtx->m_r->fillDepthBuffer(depthBuff);
+		// Do the work
+		m_frcCtx->m_r->fillDepthBuffer(depthBuff);
+	}
 }
 }
 
 
 void GatherVisiblesFromOctreeTask::gather(ThreadHive& hive)
 void GatherVisiblesFromOctreeTask::gather(ThreadHive& hive)

+ 9 - 2
AnKi/Shaders/GBufferCommon.glsl

@@ -18,6 +18,13 @@ ANKI_BINDLESS_SET(MATERIAL_SET_BINDLESS)
 #define REALLY_USING_PARALLAX \
 #define REALLY_USING_PARALLAX \
 	(PARALLAX == 1 && ANKI_TECHNIQUE == RENDERING_TECHNIQUE_GBUFFER && ANKI_LOD == 0 && ALPHA_TEST == 0)
 	(PARALLAX == 1 && ANKI_TECHNIQUE == RENDERING_TECHNIQUE_GBUFFER && ANKI_LOD == 0 && ALPHA_TEST == 0)
 
 
+// For some reason nVidia doesn't like mediump precision on bitangents
+#if ANKI_PLATFORM_MOBILE
+#	define BITANGENT_PRECISION ANKI_RP
+#else
+#	define BITANGENT_PRECISION
+#endif
+
 //
 //
 // Vert input
 // Vert input
 //
 //
@@ -53,7 +60,7 @@ layout(location = 0) out Vec2 out_uv;
 #	if ANKI_TECHNIQUE == RENDERING_TECHNIQUE_GBUFFER
 #	if ANKI_TECHNIQUE == RENDERING_TECHNIQUE_GBUFFER
 layout(location = 1) out ANKI_RP Vec3 out_normal;
 layout(location = 1) out ANKI_RP Vec3 out_normal;
 layout(location = 2) out ANKI_RP Vec3 out_tangent;
 layout(location = 2) out ANKI_RP Vec3 out_tangent;
-layout(location = 3) out ANKI_RP Vec3 out_bitangent;
+layout(location = 3) out BITANGENT_PRECISION Vec3 out_bitangent;
 
 
 #		if REALLY_USING_PARALLAX
 #		if REALLY_USING_PARALLAX
 layout(location = 4) out F32 out_distFromTheCamera;
 layout(location = 4) out F32 out_distFromTheCamera;
@@ -81,7 +88,7 @@ layout(location = 0) in Vec2 in_uv;
 #	if ANKI_TECHNIQUE == RENDERING_TECHNIQUE_GBUFFER
 #	if ANKI_TECHNIQUE == RENDERING_TECHNIQUE_GBUFFER
 layout(location = 1) in ANKI_RP Vec3 in_normal;
 layout(location = 1) in ANKI_RP Vec3 in_normal;
 layout(location = 2) in ANKI_RP Vec3 in_tangent;
 layout(location = 2) in ANKI_RP Vec3 in_tangent;
-layout(location = 3) in ANKI_RP Vec3 in_bitangent;
+layout(location = 3) in BITANGENT_PRECISION Vec3 in_bitangent;
 
 
 #		if REALLY_USING_PARALLAX
 #		if REALLY_USING_PARALLAX
 layout(location = 4) in F32 in_distFromTheCamera;
 layout(location = 4) in F32 in_distFromTheCamera;