소스 검색

[REFACTORING] Move light shading's normal to world space

Panagiotis Christopoulos Charitos 8 년 전
부모
커밋
7e65d7c09a

+ 21 - 26
programs/LightShading.ankiprog

@@ -8,6 +8,7 @@ http://www.anki3d.org/LICENSE
 	<inputs>
 		<input name="CLUSTER_COUNT_X" type="uint" const="1"/>
 		<input name="CLUSTER_COUNT_Y" type="uint" const="1"/>
+		<input name="CLUSTER_COUNT_Z" type="uint" const="1"/>
 		<input name="CLUSTER_COUNT" type="uint" const="1"/>
 		<input name="IR_MIPMAP_COUNT" type="uint" const="1"/>
 	</inputs>
@@ -68,7 +69,7 @@ const float SUBSURFACE_MIN = 0.05;
 
 // Common code for lighting
 #define LIGHTING_COMMON_BRDF() \
-	vec3 frag2Light = light.posRadius.xyz - fragPos; \
+	vec3 frag2Light = light.posRadius.xyz - worldPos; \
 	vec3 l = normalize(frag2Light); \
 	float nol = max(0.0, dot(normal, l)); \
 	vec3 specC = computeSpecularColorBrdf(viewDir, l, normal, specCol, light.specularColorRadius.rgb, a2, nol); \
@@ -85,9 +86,9 @@ void debugIncorrectColor(inout vec3 c)
 }
 
 // Compute the colors of a decal.
-void appendDecalColors(in Decal decal, in vec3 fragPos, inout vec3 diffuseColor, inout float roughness)
+void appendDecalColors(in Decal decal, in vec3 worldPos, inout vec3 diffuseColor, inout float roughness)
 {
-	vec4 texCoords4 = decal.texProjectionMat * vec4(fragPos, 1.0);
+	vec4 texCoords4 = decal.texProjectionMat * vec4(worldPos, 1.0);
 	vec2 texCoords2 = texCoords4.xy / texCoords4.w;
 
 	// Clamp the tex coords. Expect a border in the texture atlas
@@ -147,16 +148,11 @@ void main()
 	float depth = texture(u_msDepthRt, in_uv, 0.0).r;
 	vec2 ndc = UV_TO_NDC(in_uv);
 
-	// Get frag pos in view space
-	vec4 fragPos4 = u_invProjMat * vec4(ndc, depth, 1.0);
-	vec3 fragPos = fragPos4.xyz / fragPos4.w;
-
 	// Get world position
 	vec3 worldPos;
 	{
 		vec4 worldPos4 = u_invViewProjMat * vec4(ndc, depth, 1.0);
-		worldPos4 = worldPos4 / worldPos4.w;
-		worldPos = worldPos4.xyz;
+		worldPos = worldPos4.xyz / worldPos4.w;
 	}
 
 	// Decode GBuffer
@@ -180,13 +176,17 @@ void main()
 
 	// Get SSAO
 	float ssao = texture(u_ssaoTex, in_uv).r;
-	diffCol *= ssao;
+	//diffCol *= ssao; TODO
 
-	// Get counts and offsets
-	uint clusterIdx = computeClusterK(u_near, u_clustererMagic, fragPos.z) * (CLUSTER_COUNT_X * CLUSTER_COUNT_Y)
-		+ uint(in_clusterIJ.y) * CLUSTER_COUNT_X + uint(in_clusterIJ.x);
+	// Get first light index
+	uint idxOffset;
+	{
+		uint k = computeClusterK(u_clustererMagic, worldPos);
+		uint clusterIdx = 
+			k * (CLUSTER_COUNT_X * CLUSTER_COUNT_Y) + uint(in_clusterIJ.y) * CLUSTER_COUNT_X + uint(in_clusterIJ.x);
 
-	uint idxOffset = u_clusters[clusterIdx];
+		idxOffset = u_clusters[clusterIdx];
+	}
 
 	// Decals
 	uint count = u_lightIndices[idxOffset++];
@@ -194,7 +194,7 @@ void main()
 	{
 		Decal decal = u_decals[u_lightIndices[idxOffset++]];
 
-		appendDecalColors(decal, fragPos, diffCol, roughness);
+		appendDecalColors(decal, worldPos, diffCol, roughness);
 	}
 
 	// Ambient and emissive color
@@ -205,7 +205,7 @@ void main()
 	a2 *= a2 * a2;
 
 	// Point lights
-	vec3 viewDir = normalize(-fragPos);
+	vec3 viewDir = normalize(u_cameraPos - worldPos);
 	count = u_lightIndices[idxOffset++];
 	while(count-- != 0)
 	{
@@ -217,14 +217,13 @@ void main()
 		{
 			float shadow = computeShadowFactorOmni(frag2Light, 
 				light.specularColorRadius.w, 
-				u_invViewRotation, 
 				light.atlasTilesPad2.xy, 
 				light.diffuseColorShadowmapId.w,
 				u_shadowTex);
 			lambert *= shadow;
 		}
 
-		outC += (specC + diffC) * (att * max(subsurface, lambert));
+		outC += (diffC + specC) * (att * max(subsurface, lambert));
 	}
 
 	// Spot lights
@@ -241,7 +240,7 @@ void main()
 		if(shadowmapLayerIdx >= 0.0)
 		{
 			float shadow = computeShadowFactorSpot(
-				light.texProjectionMat, fragPos, light.specularColorRadius.w, u_shadowTex);
+				light.texProjectionMat, worldPos, light.specularColorRadius.w, u_shadowTex);
 			lambert *= shadow;
 		}
 
@@ -250,10 +249,7 @@ void main()
 
 	// Indirect
 	vec3 eye = -viewDir;
-
-	vec3 worldEye = u_invViewRotation * eye;
-	vec3 worldNormal = u_invViewRotation * normal;
-	vec3 worldR = reflect(worldEye, worldNormal);
+	vec3 reflVec = reflect(eye, normal);
 
 	float reflLod = float(IR_MIPMAP_COUNT) * a2;
 
@@ -262,12 +258,11 @@ void main()
 	vec3 specIndirectTerm = specCol * envBRDF.x + envBRDF.y;
 
 	vec3 specIndirect, diffIndirect;
-	readIndirect(idxOffset, worldPos, worldR, worldNormal, reflLod, specIndirect, diffIndirect);
+	readIndirect(idxOffset, worldPos, reflVec, normal, reflLod, specIndirect, diffIndirect);
 
 	outC += specIndirect * specIndirectTerm + diffIndirect * diffCol;
 
-	//out_color = outC;
-	out_color = diffCol;
+	out_color = outC;
 #if 0
 	count = scount;
 	if(count == 0)

+ 0 - 1
programs/VolumetricFog.ankiprog

@@ -77,7 +77,6 @@ vec3 computeLightColor(vec3 fragPos, uint plightCount, uint plightIdx, uint slig
 		{
 			factor *= computeShadowFactorOmni(frag2Light, 
 				-1.0 / light.posRadius.w, 
-				u_invViewRotation, 
 				light.atlasTilesPad2.xy,
 				light.diffuseColorShadowmapId.w,
 				u_shadowTex);

+ 13 - 29
shaders/ClusterLightCommon.glsl

@@ -12,8 +12,9 @@
 struct LightingUniforms
 {
 	vec4 projectionParams;
-	vec4 rendererSizeTimePad1;
-	vec4 nearFarClustererMagicPad1;
+	vec4 rendererSizeTimeNear;
+	vec4 cameraPosFar;
+	vec4 clustererMagic;
 	mat3 invViewRotation;
 	uvec4 tileCount;
 	mat4 invViewProjMat;
@@ -72,36 +73,19 @@ layout(ANKI_UBO_BINDING(LIGHT_SET, LIGHT_UBO_BINDING), std140, row_major) unifor
 	LightingUniforms u_lightingUniforms;
 };
 
-#define u_near readFirstInvocationARB(u_lightingUniforms.nearFarClustererMagicPad1.x)
-#define u_far readFirstInvocationARB(u_lightingUniforms.nearFarClustererMagicPad1.y)
+#define u_near readFirstInvocationARB(u_lightingUniforms.rendererSizeTimeNear.w)
+#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.nearFarClustererMagicPad1.z)
-#define u_time readFirstInvocationARB(u_lightingUniforms.rendererSizeTimePad1.z)
+#define u_clustererMagic readFirstInvocationARB(u_lightingUniforms.clustererMagic)
+#define u_time readFirstInvocationARB(u_lightingUniforms.rendererSizeTimeNear.z)
 #define u_unprojectionParams readFirstInvocationARB(u_lightingUniforms.projectionParams)
-
-#define u_invViewRotation                                               \
-	mat3(readFirstInvocationARB(u_lightingUniforms.invViewRotation[0]), \
-		readFirstInvocationARB(u_lightingUniforms.invViewRotation[1]),  \
-		readFirstInvocationARB(u_lightingUniforms.invViewRotation[2]))
-
-#define u_invProjMat                                               \
-	mat4(readFirstInvocationARB(u_lightingUniforms.invProjMat[0]), \
-		readFirstInvocationARB(u_lightingUniforms.invProjMat[1]),  \
-		readFirstInvocationARB(u_lightingUniforms.invProjMat[2]),  \
-		readFirstInvocationARB(u_lightingUniforms.invProjMat[3]))
-
-#define u_invViewProjMat                                               \
-	mat4(readFirstInvocationARB(u_lightingUniforms.invViewProjMat[0]), \
-		readFirstInvocationARB(u_lightingUniforms.invViewProjMat[1]),  \
-		readFirstInvocationARB(u_lightingUniforms.invViewProjMat[2]),  \
-		readFirstInvocationARB(u_lightingUniforms.invViewProjMat[3]))
-
-#define u_prevViewProjMat                                               \
-	mat4(readFirstInvocationARB(u_lightingUniforms.prevViewProjMat[0]), \
-		readFirstInvocationARB(u_lightingUniforms.prevViewProjMat[1]),  \
-		readFirstInvocationARB(u_lightingUniforms.prevViewProjMat[2]),  \
-		readFirstInvocationARB(u_lightingUniforms.prevViewProjMat[3]))
+#define u_invViewRotation u_lightingUniforms.invViewRotation
+#define u_invProjMat u_lightingUniforms.invProjMat
+#define u_invViewProjMat u_lightingUniforms.invViewProjMat
+#define u_prevViewProjMat u_lightingUniforms.prevViewProjMat
+#define u_cameraPos u_lightingUniforms.cameraPosFar.xyz
+#define u_rendererSize u_lightingUniforms.rendererSizeTimeNear.xy
 
 #else
 const uint _NEXT_UBO_BINDING = LIGHT_UBO_BINDING;

+ 10 - 17
shaders/Clusterer.glsl

@@ -10,39 +10,32 @@
 
 #include "shaders/Common.glsl"
 
-uint computeClusterK(float near, float clustererMagic, float zVSpace)
+uint computeClusterK(vec4 clustererMagic, vec3 worldPos)
 {
-	float fz = sqrt((zVSpace + near) * clustererMagic);
+	float fz = sqrt(dot(clustererMagic.xyz, worldPos) - clustererMagic.w);
 	uint z = uint(fz);
 	return z;
 }
 
-uint computeClusterKSafe(float near, float far, float clustererMagic, float zVSpace)
-{
-	float z = clamp(zVSpace, -far, -near);
-	float kf = sqrt((z + near) * clustererMagic);
-	return uint(kf);
-}
-
 // Compute cluster index
-uint computeClusterIndex(
-	vec2 uv, float near, float clustererMagic, float zVSpace, uint clusterCountX, uint clusterCountY)
+uint computeClusterIndex(vec2 uv, vec4 clustererMagic, vec3 worldPos, uint clusterCountX, uint clusterCountY)
 {
 	uvec2 xy = uvec2(uv * vec2(clusterCountX, clusterCountY));
 
-	return computeClusterK(near, clustererMagic, zVSpace) * (clusterCountX * clusterCountY) + xy.y * clusterCountX
-		+ xy.x;
+	return computeClusterK(clustererMagic, 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, float clustererMagic)
+float computeClusterNear(uint k, float near, vec4 clustererMagic)
 {
-	return 1.0 / clustererMagic * pow(float(k), 2.0) - near;
+	// TODO
+	return near;
 }
 
-float computeClusterFar(uint k, float near, float clustererMagic)
+float computeClusterFar(uint k, float near, vec4 clustererMagic)
 {
-	return 1.0 / clustererMagic * pow(float(k + 1u), 2.0) - near;
+	// TODO
+	return near;
 }
 
 #endif

+ 3 - 3
shaders/ForwardShadingCommonFrag.glsl

@@ -22,7 +22,7 @@ layout(ANKI_TEX_BINDING(0, 0)) uniform sampler2D anki_msDepthRt;
 #include "shaders/ClusterLightCommon.glsl"
 
 #define anki_u_time u_time
-#define RENDERER_SIZE (u_lightingUniforms.rendererSizeTimePad1.xy * 0.5)
+#define RENDERER_SIZE (u_rendererSize * 0.5)
 
 // Varyings
 layout(location = 0) flat in float in_alpha;
@@ -52,7 +52,8 @@ vec3 computeLightColor(vec3 diffCol)
 
 	// Find the cluster and then the light counts
 	uint clusterIdx = computeClusterIndex(
-		gl_FragCoord.xy / RENDERER_SIZE, u_near, u_clustererMagic, fragPos.z, u_clusterCountX, u_clusterCountY);
+		gl_FragCoord.xy / RENDERER_SIZE, u_clustererMagic, vec3(0.0), u_clusterCountX, u_clusterCountY);
+	clusterIdx = 0; // TODO
 
 	uint idxOffset = u_clusters[clusterIdx];
 
@@ -79,7 +80,6 @@ vec3 computeLightColor(vec3 diffCol)
 		{
 			shadow = computeShadowFactorOmni(frag2Light,
 				light.specularColorRadius.w,
-				u_invViewRotation,
 				light.atlasTilesPad2.xy,
 				light.diffuseColorShadowmapId.w,
 				u_shadowTex);

+ 4 - 5
shaders/LightFunctions.glsl

@@ -90,9 +90,9 @@ uint computeShadowSampleCount(const uint COUNT, float zVSpace)
 	return sampleCount;
 }
 
-float computeShadowFactorSpot(mat4 lightProjectionMat, vec3 fragPos, float distance, sampler2D spotMapArr)
+float computeShadowFactorSpot(mat4 lightProjectionMat, vec3 worldPos, float distance, sampler2D spotMapArr)
 {
-	vec4 texCoords4 = lightProjectionMat * vec4(fragPos, 1.0);
+	vec4 texCoords4 = lightProjectionMat * vec4(worldPos, 1.0);
 	vec3 texCoords3 = texCoords4.xyz / texCoords4.w;
 
 	const float near = LIGHT_FRUSTUM_NEAR_PLANE;
@@ -103,10 +103,9 @@ float computeShadowFactorSpot(mat4 lightProjectionMat, vec3 fragPos, float dista
 	return clamp(exp(ESM_CONSTANT * (textureLod(spotMapArr, texCoords3.xy, 0.0).r - linearDepth)), 0.0, 1.0);
 }
 
-float computeShadowFactorOmni(
-	vec3 frag2Light, float radius, mat3 invViewMat, uvec2 atlasTiles, float tileSize, sampler2D shadowMap)
+float computeShadowFactorOmni(vec3 frag2Light, float radius, uvec2 atlasTiles, float tileSize, sampler2D shadowMap)
 {
-	vec3 dir = invViewMat * -frag2Light;
+	vec3 dir = -frag2Light;
 	vec3 dirabs = abs(dir);
 	float dist = max(dirabs.x, max(dirabs.y, dirabs.z));
 

+ 38 - 8
src/anki/renderer/Clusterer.cpp

@@ -196,24 +196,54 @@ void Clusterer::prepare(ThreadPool& threadPool, const ClustererPrepareInfo& inf)
 	m_projMat = inf.m_projMat;
 	m_viewMat = inf.m_viewMat;
 	m_camTrf = inf.m_camTrf;
+	m_near = inf.m_near;
+	m_far = inf.m_far;
+	ANKI_ASSERT(m_near < m_far && m_near > 0.0);
 
 	m_unprojParams = m_projMat.extractPerspectiveUnprojectionParams();
-	m_near = -m_unprojParams.z() / (m_unprojParams.w() + 0.0);
-	m_far = -m_unprojParams.z() / (m_unprojParams.w() + 1.0);
-	ANKI_ASSERT(m_near < m_far && m_near > 0.0);
 	m_calcNearOpt = (m_far - m_near) / pow(m_counts[2], 2.0);
-	m_shaderMagicVal = -1.0 / m_calcNearOpt;
+
+	// Compute magic val
+	{
+		// 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)
+		// where 'n' and 'f' are the near and f vals of the projection and Cz2 is the m_counts[2]^2
+		// If the 'd' is not known and the world position instead is known then 'd' is the distance from that position
+		// to the camera's near plane.
+		// d = dot(Pn, W) - Po  (2)
+		// where 'Pn' is the plane's normal, 'Po' is the plane's offset and 'W' is the world position.
+		// Substituting d from (2) in (1) we have:
+		// k = sqrt((dot(Pn, W) - Po) / (f - n) * Cz2) =>
+		// k = sqrt((dot(Pn, W) * Cz2 - Po * Cz2) / (f - n))
+		// k = sqrt(dot(Pn, W) * Cz2 / (f - n) - Po * Cz2 / (f - n))
+		// k = sqrt(dot(Pn * Cz2 / (f - n), W) - Po * Cz2 / (f - n))
+		// If we assume that:
+		// A = Pn * Cz2 / (f - n) and B =  Po * Cz2 / (f - n)
+		// Then:
+		// k = sqrt(dot(A, W) - B)
+
+		const Mat4& vp = inf.m_viewProjMat;
+		Plane nearPlane;
+		Array<Plane*, U(FrustumPlaneType::COUNT)> planes = {};
+		planes[FrustumPlaneType::NEAR] = &nearPlane;
+		extractClipPlanes(vp, planes);
+
+		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);
+	}
 
 	//
 	// Issue parallel jobs
 	//
-	Array<UpdatePlanesPerspectiveCameraTask, ThreadPool::MAX_THREADS> jobs;
+	UpdatePlanesPerspectiveCameraTask job;
+	job.m_clusterer = this;
+	job.m_frustumChanged = frustumChanged;
 
 	for(U i = 0; i < threadPool.getThreadCount(); i++)
 	{
-		jobs[i].m_clusterer = this;
-		jobs[i].m_frustumChanged = frustumChanged;
-		threadPool.assignNewTask(i, &jobs[i]);
+		threadPool.assignNewTask(i, &job);
 	}
 
 	// Sync threads

+ 8 - 4
src/anki/renderer/Clusterer.h

@@ -124,7 +124,10 @@ class ClustererPrepareInfo
 public:
 	Mat4 m_viewMat;
 	Mat4 m_projMat; ///< Must be perspective projection.
+	Mat4 m_viewProjMat;
 	Transform m_camTrf;
+	F32 m_near;
+	F32 m_far;
 };
 
 /// Collection of clusters for visibility tests.
@@ -152,8 +155,9 @@ public:
 	/// Bin a frustum.
 	void binPerspectiveFrustum(const PerspectiveFrustum& fr, const Aabb& csBox, ClustererTestResult& rez) const;
 
-	/// A value that will be used in shaders to calculate the cluster index.
-	F32 getShaderMagicValue() const
+	/// 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
 	{
 		return m_shaderMagicVal;
 	}
@@ -207,8 +211,8 @@ private:
 	Vec4 m_unprojParams = Vec4(0.0);
 	F32 m_near = 0.0;
 	F32 m_far = 0.0;
-	F32 m_calcNearOpt = 0.0;
-	F32 m_shaderMagicVal = 0.0;
+	F32 m_calcNearOpt = 0.0f;
+	Vec4 m_shaderMagicVal = Vec4(0.0f);
 
 	F32 calcNear(U k) const;
 

+ 1 - 0
src/anki/renderer/ForwardShading.cpp

@@ -130,6 +130,7 @@ void ForwardShading::drawVolumetric(RenderingContext& ctx, RenderPassWorkContext
 
 void ForwardShading::drawUpscale(const RenderingContext& ctx, RenderPassWorkContext& rgraphCtx)
 {
+	return; // TODO
 	CommandBufferPtr& cmdb = rgraphCtx.m_commandBuffer;
 
 	// **WARNING** Remember to update the consumers of the render pass that calls this method

+ 10 - 10
src/anki/renderer/LightBin.cpp

@@ -374,7 +374,10 @@ Error LightBin::bin(const Mat4& viewMat,
 	ClustererPrepareInfo pinf;
 	pinf.m_viewMat = viewMat;
 	pinf.m_projMat = projMat;
+	pinf.m_viewProjMat = viewProjMat;
 	pinf.m_camTrf = Transform(camTrf);
+	pinf.m_near = rqueue.m_cameraNear;
+	pinf.m_far = rqueue.m_cameraFar;
 	m_clusterer.prepare(*m_threadPool, pinf);
 
 	//
@@ -653,9 +656,7 @@ void LightBin::writeAndBinPointLight(
 
 	ShaderPointLight& slight = ctx.m_pointLights[idx];
 
-	Vec4 pos = ctx.m_viewMat * lightEl.m_worldPosition.xyz1();
-
-	slight.m_posRadius = Vec4(pos.xyz(), 1.0f / (lightEl.m_radius * lightEl.m_radius));
+	slight.m_posRadius = Vec4(lightEl.m_worldPosition.xyz(), 1.0f / (lightEl.m_radius * lightEl.m_radius));
 	slight.m_diffuseColorTileSize = lightEl.m_diffuseColor.xyz0();
 
 	if(lightEl.m_shadowRenderQueues[0] == nullptr || !ctx.m_shadowsEnabled)
@@ -703,15 +704,15 @@ void LightBin::writeAndBinSpotLight(
 
 	if(lightEl.hasShadow() && ctx.m_shadowsEnabled)
 	{
-		// bias * proj_l * view_l * world_c
-		light.m_texProjectionMat = lightEl.m_textureMatrix * ctx.m_camTrf;
+		// bias * proj_l * view_l
+		light.m_texProjectionMat = lightEl.m_textureMatrix;
 
 		shadowmapIndex = 1.0f; // Just set a value
 	}
 
 	// Pos & dist
-	Vec4 pos = ctx.m_viewMat * lightEl.m_worldTransform.getTranslationPart().xyz1();
-	light.m_posRadius = Vec4(pos.xyz(), 1.0f / (lightEl.m_distance * lightEl.m_distance));
+	light.m_posRadius =
+		Vec4(lightEl.m_worldTransform.getTranslationPart().xyz(), 1.0f / (lightEl.m_distance * lightEl.m_distance));
 
 	// Diff color and shadowmap ID now
 	light.m_diffuseColorShadowmapId = Vec4(lightEl.m_diffuseColor, shadowmapIndex);
@@ -721,7 +722,6 @@ void LightBin::writeAndBinSpotLight(
 
 	// Light dir
 	Vec3 lightDir = -lightEl.m_worldTransform.getRotationPart().getZAxis();
-	lightDir = ctx.m_viewMat.getRotationPart() * lightDir;
 	light.m_lightDir = Vec4(lightDir, 0.0f);
 
 	// Angles
@@ -823,8 +823,8 @@ void LightBin::writeAndBinDecal(const DecalQueueElement& decalEl, LightBinContex
 		ctx.m_normalRoughnessDecalTexAtlas = atlas;
 	}
 
-	// bias * proj_l * view_l * world_c
-	decal.m_texProjectionMat = decalEl.m_textureMatrix * ctx.m_camTrf;
+	// bias * proj_l * view_
+	decal.m_texProjectionMat = decalEl.m_textureMatrix;
 
 	// Bin it
 	Obb obb(decalEl.m_obbCenter.xyz0(), Mat3x4(decalEl.m_obbRotation), decalEl.m_obbExtend.xyz0());

+ 13 - 7
src/anki/renderer/LightShading.cpp

@@ -15,15 +15,18 @@
 #include <anki/renderer/DepthDownscale.h>
 #include <anki/misc/ConfigSet.h>
 #include <anki/util/HighRezTimer.h>
+#include <anki/collision/Functions.h>
 
 namespace anki
 {
 
+/// @note Should match the shader
 struct ShaderCommonUniforms
 {
 	Vec4 m_projectionParams;
-	Vec4 m_rendererSizeTimePad1;
-	Vec4 m_nearFarClustererMagicPad1;
+	Vec4 m_rendererSizeTimeNear;
+	Vec4 m_cameraPosFar;
+	Vec4 m_clustererMagic;
 	Mat3x4 m_invViewRotation;
 	UVec4 m_tileCount;
 	Mat4 m_invViewProjMat;
@@ -84,6 +87,7 @@ Error LightShading::initInternal(const ConfigSet& config)
 	ShaderProgramResourceConstantValueInitList<4> consts(m_prog);
 	consts.add("CLUSTER_COUNT_X", U32(m_clusterCounts[0]))
 		.add("CLUSTER_COUNT_Y", U32(m_clusterCounts[1]))
+		.add("CLUSTER_COUNT_Z", U32(m_clusterCounts[2]))
 		.add("CLUSTER_COUNT", U32(m_clusterCount))
 		.add("IR_MIPMAP_COUNT", U32(m_r->getIndirect().getReflectionTextureMipmapCount()));
 
@@ -181,20 +185,22 @@ void LightShading::updateCommonBlock(RenderingContext& ctx)
 
 	// Start writing
 	blk->m_projectionParams = ctx.m_unprojParams;
-	blk->m_nearFarClustererMagicPad1 = Vec4(ctx.m_renderQueue->m_cameraNear,
-		ctx.m_renderQueue->m_cameraFar,
-		m_lightBin->getClusterer().getShaderMagicValue(),
-		0.0);
 
 	blk->m_invViewRotation = Mat3x4(ctx.m_renderQueue->m_viewMatrix.getInverse().getRotationPart());
 
-	blk->m_rendererSizeTimePad1 = Vec4(m_r->getWidth(), m_r->getHeight(), HighRezTimer::getCurrentTime(), 0.0);
+	blk->m_rendererSizeTimeNear =
+		Vec4(m_r->getWidth(), m_r->getHeight(), HighRezTimer::getCurrentTime(), ctx.m_renderQueue->m_cameraNear);
 
 	blk->m_tileCount = UVec4(m_clusterCounts[0], m_clusterCounts[1], m_clusterCounts[2], m_clusterCount);
 
 	blk->m_invViewProjMat = ctx.m_viewProjMatJitter.getInverse();
 	blk->m_prevViewProjMat = ctx.m_prevViewProjMat;
 	blk->m_invProjMat = ctx.m_projMatJitter.getInverse();
+
+	blk->m_cameraPosFar =
+		Vec4(ctx.m_renderQueue->m_cameraTransform.getTranslationPart().xyz(), ctx.m_renderQueue->m_cameraFar);
+
+	blk->m_clustererMagic = m_lightBin->getClusterer().getShaderMagicValue();
 }
 
 void LightShading::populateRenderGraph(RenderingContext& ctx)