Explorar el Código

[REFACTORING] Move volumetric fog to world space normal

Panagiotis Christopoulos Charitos hace 8 años
padre
commit
683b86513f

+ 5 - 2
programs/VolumetricFog.ankiprog

@@ -152,7 +152,7 @@ void main()
 	vec3 newCol = vec3(0.0);
 	for(uint k = 0u; k < CLUSTER_COUNT.z; ++k)
 	{
-		float kFar = computeClusterFar(k, u_near, u_clustererMagic);
+		float kFar = -computeClusterFar(u_clustererMagic, k);
 
 		//
 		// Compute sample count
@@ -191,7 +191,10 @@ void main()
 
 			vec3 fragPos = viewDir * (zMedian / viewDir.z);
 
-			newCol += computeLightColor(fragPos, plightCount, plightIdx, slightCount, slightIdx);
+			// Move to world space
+			vec4 newWorldPos4 = u_invViewMat * vec4(fragPos, 1.0);
+
+			newCol += computeLightColor(newWorldPos4.xyz, plightCount, plightIdx, slightCount, slightIdx);
 		}
 
 		kNear = kFar;

+ 5 - 4
shaders/ClusterLightCommon.glsl

@@ -7,6 +7,7 @@
 #define ANKI_SHADERS_CLUSTER_LIGHT_COMMON_GLSL
 
 #include "shaders/LightFunctions.glsl"
+#include "shaders/Clusterer.glsl"
 
 // Common uniforms between lights
 struct LightingUniforms
@@ -14,9 +15,9 @@ struct LightingUniforms
 	vec4 projectionParams;
 	vec4 rendererSizeTimeNear;
 	vec4 cameraPosFar;
-	vec4 clustererMagic;
-	mat3 invViewRotation;
+	ClustererMagicValues clustererMagicValues;
 	uvec4 tileCount;
+	mat4 invViewMat;
 	mat4 invViewProjMat;
 	mat4 prevViewProjMat;
 	mat4 invProjMat;
@@ -77,10 +78,10 @@ layout(ANKI_UBO_BINDING(LIGHT_SET, LIGHT_UBO_BINDING), std140, row_major) unifor
 #define u_far readFirstInvocationARB(u_lightingUniforms.cameraPosFar.w)
 #define u_clusterCountX readFirstInvocationARB(u_lightingUniforms.tileCount.x)
 #define u_clusterCountY readFirstInvocationARB(u_lightingUniforms.tileCount.y)
-#define u_clustererMagic readFirstInvocationARB(u_lightingUniforms.clustererMagic)
+#define u_clustererMagic u_lightingUniforms.clustererMagicValues
 #define u_time readFirstInvocationARB(u_lightingUniforms.rendererSizeTimeNear.z)
 #define u_unprojectionParams readFirstInvocationARB(u_lightingUniforms.projectionParams)
-#define u_invViewRotation u_lightingUniforms.invViewRotation
+#define u_invViewMat u_lightingUniforms.invViewMat
 #define u_invProjMat u_lightingUniforms.invProjMat
 #define u_invViewProjMat u_lightingUniforms.invViewProjMat
 #define u_prevViewProjMat u_lightingUniforms.prevViewProjMat

+ 16 - 10
shaders/Clusterer.glsl

@@ -10,32 +10,38 @@
 
 #include "shaders/Common.glsl"
 
-uint computeClusterK(vec4 clustererMagic, vec3 worldPos)
+// See the documentation of the Clusterer class.
+struct ClustererMagicValues
 {
-	float fz = sqrt(dot(clustererMagic.xyz, worldPos) - clustererMagic.w);
+	vec4 val0;
+	vec4 val1;
+};
+
+uint computeClusterK(ClustererMagicValues magic, vec3 worldPos)
+{
+	float fz = sqrt(dot(magic.val0.xyz, worldPos) - magic.val0.w);
 	uint z = uint(fz);
 	return z;
 }
 
 // Compute cluster index
-uint computeClusterIndex(vec2 uv, vec4 clustererMagic, vec3 worldPos, uint clusterCountX, uint clusterCountY)
+uint computeClusterIndex(ClustererMagicValues magic, vec2 uv, vec3 worldPos, uint clusterCountX, uint clusterCountY)
 {
 	uvec2 xy = uvec2(uv * vec2(clusterCountX, clusterCountY));
 
-	return computeClusterK(clustererMagic, worldPos) * (clusterCountX * clusterCountY) + xy.y * clusterCountX + xy.x;
+	return computeClusterK(magic, worldPos) * (clusterCountX * clusterCountY) + xy.y * clusterCountX + xy.x;
 }
 
 // Compute the Z of the near plane given a cluster idx
-float computeClusterNear(uint k, float near, vec4 clustererMagic)
+float computeClusterNear(ClustererMagicValues magic, uint k)
 {
-	// TODO
-	return near;
+	float fk = float(k);
+	return magic.val1.x * fk * fk + magic.val1.y;
 }
 
-float computeClusterFar(uint k, float near, vec4 clustererMagic)
+float computeClusterFar(ClustererMagicValues magic, uint k)
 {
-	// TODO
-	return near;
+	return computeClusterNear(magic, k + 1u);
 }
 
 #endif

+ 1 - 1
shaders/ForwardShadingCommonFrag.glsl

@@ -52,7 +52,7 @@ vec3 computeLightColor(vec3 diffCol)
 
 	// Find the cluster and then the light counts
 	uint clusterIdx = computeClusterIndex(
-		gl_FragCoord.xy / RENDERER_SIZE, u_clustererMagic, vec3(0.0), u_clusterCountX, u_clusterCountY);
+		u_clustererMagic, gl_FragCoord.xy / RENDERER_SIZE, vec3(0.0), u_clusterCountX, u_clusterCountY);
 	clusterIdx = 0; // TODO
 
 	uint idxOffset = u_clusters[clusterIdx];

+ 9 - 2
src/anki/renderer/Clusterer.cpp

@@ -203,7 +203,8 @@ void Clusterer::prepare(ThreadPool& threadPool, const ClustererPrepareInfo& inf)
 	m_unprojParams = m_projMat.extractPerspectiveUnprojectionParams();
 	m_calcNearOpt = (m_far - m_near) / pow(m_counts[2], 2.0);
 
-	// Compute magic val
+	// Compute magic val 0
+	// It's been used to calculate the 'k' of a cluster given the world position
 	{
 		// Given a distance 'd' from the camera's near plane in world space the 'k' split is calculated like:
 		// k = sqrt(d / (f - n) * Cz2)  (1)
@@ -231,7 +232,13 @@ void Clusterer::prepare(ThreadPool& threadPool, const ClustererPrepareInfo& inf)
 		Vec3 A = nearPlane.getNormal().xyz() * (m_counts[2] * m_counts[2]) / (m_far - m_near);
 		F32 B = nearPlane.getOffset() * (m_counts[2] * m_counts[2]) / (m_far - m_near);
 
-		m_shaderMagicVal = Vec4(A, B);
+		m_shaderMagicVals.m_val0 = Vec4(A, B);
+	}
+
+	// Compute magic val 1
+	{
+		m_shaderMagicVals.m_val1.x() = m_calcNearOpt;
+		m_shaderMagicVals.m_val1.y() = m_near;
 	}
 
 	//

+ 10 - 3
src/anki/renderer/Clusterer.h

@@ -130,6 +130,13 @@ public:
 	F32 m_far;
 };
 
+/// Some transparent valued used by shaders.
+struct ClustererShaderMagicValues
+{
+	Vec4 m_val0;
+	Vec4 m_val1;
+};
+
 /// Collection of clusters for visibility tests.
 class Clusterer
 {
@@ -157,9 +164,9 @@ public:
 
 	/// A value that will be used in shaders to calculate the cluster index. See the code that calculates it for info
 	/// on what it is.
-	const Vec4& getShaderMagicValue() const
+	const ClustererShaderMagicValues& getShaderMagicValues() const
 	{
-		return m_shaderMagicVal;
+		return m_shaderMagicVals;
 	}
 
 	U getClusterCountX() const
@@ -212,7 +219,7 @@ private:
 	F32 m_near = 0.0;
 	F32 m_far = 0.0;
 	F32 m_calcNearOpt = 0.0f;
-	Vec4 m_shaderMagicVal = Vec4(0.0f);
+	ClustererShaderMagicValues m_shaderMagicVals = {Vec4(0.0f), Vec4(0.0f)};
 
 	F32 calcNear(U k) const;
 

+ 4 - 4
src/anki/renderer/LightShading.cpp

@@ -26,9 +26,9 @@ struct ShaderCommonUniforms
 	Vec4 m_projectionParams;
 	Vec4 m_rendererSizeTimeNear;
 	Vec4 m_cameraPosFar;
-	Vec4 m_clustererMagic;
-	Mat3x4 m_invViewRotation;
+	ClustererShaderMagicValues m_clustererMagicValues;
 	UVec4 m_tileCount;
+	Mat4 m_invViewMat;
 	Mat4 m_invViewProjMat;
 	Mat4 m_prevViewProjMat;
 	Mat4 m_invProjMat;
@@ -186,7 +186,7 @@ void LightShading::updateCommonBlock(RenderingContext& ctx)
 	// Start writing
 	blk->m_projectionParams = ctx.m_unprojParams;
 
-	blk->m_invViewRotation = Mat3x4(ctx.m_renderQueue->m_viewMatrix.getInverse().getRotationPart());
+	blk->m_invViewMat = ctx.m_renderQueue->m_viewMatrix.getInverse();
 
 	blk->m_rendererSizeTimeNear =
 		Vec4(m_r->getWidth(), m_r->getHeight(), HighRezTimer::getCurrentTime(), ctx.m_renderQueue->m_cameraNear);
@@ -200,7 +200,7 @@ void LightShading::updateCommonBlock(RenderingContext& ctx)
 	blk->m_cameraPosFar =
 		Vec4(ctx.m_renderQueue->m_cameraTransform.getTranslationPart().xyz(), ctx.m_renderQueue->m_cameraFar);
 
-	blk->m_clustererMagic = m_lightBin->getClusterer().getShaderMagicValue();
+	blk->m_clustererMagicValues = m_lightBin->getClusterer().getShaderMagicValues();
 }
 
 void LightShading::populateRenderGraph(RenderingContext& ctx)