Browse Source

Increase the accuracy of cluster binning and optimize

Panagiotis Christopoulos Charitos 2 years ago
parent
commit
d4eac81a39

+ 0 - 2
AnKi/Renderer/ClusterBinning2.cpp

@@ -35,7 +35,6 @@ Error ClusterBinning2::init()
 	{
 		ShaderProgramResourceVariantInitInfo inf(m_binningProg);
 		inf.addMutation("OBJECT_TYPE", MutatorValue(type));
-		inf.addConstant("kTileSize", getRenderer().getTileSize());
 		inf.addConstant("kZSplitCount", getRenderer().getZSplitCount());
 		const ShaderProgramResourceVariant* variant;
 		m_binningProg->getOrCreateVariant(inf, variant);
@@ -307,7 +306,6 @@ void ClusterBinning2::writeClusterUniformsInternal()
 	unis.m_zSplitCountOverFrustumLength = F32(getRenderer().getZSplitCount()) / (ctx.m_cameraFar - ctx.m_cameraNear);
 	unis.m_zSplitMagic.x() = (ctx.m_cameraNear - ctx.m_cameraFar) / (ctx.m_cameraNear * F32(getRenderer().getZSplitCount()));
 	unis.m_zSplitMagic.y() = ctx.m_cameraFar / (ctx.m_cameraNear * F32(getRenderer().getZSplitCount()));
-	unis.m_tileSize = getRenderer().getTileSize();
 	unis.m_lightVolumeLastZSplit = getRenderer().getVolumetricLightingAccumulation().getFinalZSplit();
 
 	unis.m_reflectionProbesMipCount = F32(getRenderer().getProbeReflections().getReflectionTextureMipmapCount());

+ 0 - 1
AnKi/Renderer/GBufferPost.cpp

@@ -31,7 +31,6 @@ Error GBufferPost::initInternal()
 	ShaderProgramResourceVariantInitInfo variantInitInfo(m_prog);
 	variantInitInfo.addConstant("kTileCount", getRenderer().getTileCounts());
 	variantInitInfo.addConstant("kZSplitCount", getRenderer().getZSplitCount());
-	variantInitInfo.addConstant("kTileSize", getRenderer().getTileSize());
 
 	const ShaderProgramResourceVariant* variant;
 	m_prog->getOrCreateVariant(variantInitInfo, variant);

+ 0 - 1
AnKi/Renderer/LightShading.cpp

@@ -60,7 +60,6 @@ Error LightShading::initLightShading()
 	ShaderProgramResourceVariantInitInfo variantInitInfo(m_lightShading.m_prog);
 	variantInitInfo.addConstant("kTileCount", getRenderer().getTileCounts());
 	variantInitInfo.addConstant("kZSplitCount", getRenderer().getZSplitCount());
-	variantInitInfo.addConstant("kTileSize", getRenderer().getTileSize());
 	const ShaderProgramResourceVariant* variant;
 
 	m_lightShading.m_prog->getOrCreateVariant(variantInitInfo, variant);

+ 2 - 4
AnKi/Renderer/Renderer.cpp

@@ -51,7 +51,6 @@ static NumericCVar<F32> g_internalRenderScalingCVar(CVarSubsystem::kRenderer, "I
 													"A factor over the requested swapchain resolution. Applies to all passes up to TAA");
 NumericCVar<F32> g_renderScalingCVar(CVarSubsystem::kRenderer, "RenderScaling", 1.0f, 0.5f, 8.0f,
 									 "A factor over the requested swapchain resolution. Applies to post-processing and UI");
-static NumericCVar<U32> g_tileSizeCVar(CVarSubsystem::kRenderer, "TileSize", 64, 8, 256, "Tile lighting tile size");
 static NumericCVar<U32> g_zSplitCountCVar(CVarSubsystem::kRenderer, "ZSplitCount", 64, 8, kMaxZsplitCount, "Clusterer number of Z splits");
 static NumericCVar<U8> g_textureAnisotropyCVar(CVarSubsystem::kRenderer, "TextureAnisotropy", (ANKI_PLATFORM_MOBILE) ? 1 : 8, 1, 16,
 											   "Texture anisotropy for the main passes");
@@ -148,9 +147,8 @@ Error Renderer::initInternal(UVec2 swapchainResolution)
 	ANKI_R_LOGI("Initializing offscreen renderer. Resolution %ux%u. Internal resolution %ux%u", m_postProcessResolution.x(),
 				m_postProcessResolution.y(), m_internalResolution.x(), m_internalResolution.y());
 
-	m_tileSize = g_tileSizeCVar.get();
-	m_tileCounts.x() = (m_internalResolution.x() + m_tileSize - 1) / m_tileSize;
-	m_tileCounts.y() = (m_internalResolution.y() + m_tileSize - 1) / m_tileSize;
+	m_tileCounts.x() = (m_internalResolution.x() + kClusteredShadingTileSize - 1) / kClusteredShadingTileSize;
+	m_tileCounts.y() = (m_internalResolution.y() + kClusteredShadingTileSize - 1) / kClusteredShadingTileSize;
 	m_zSplitCount = g_zSplitCountCVar.get();
 
 	// A few sanity checks

+ 0 - 6
AnKi/Renderer/Renderer.h

@@ -159,11 +159,6 @@ public:
 		return m_samplers;
 	}
 
-	U32 getTileSize() const
-	{
-		return m_tileSize;
-	}
-
 	const UVec2& getTileCounts() const
 	{
 		return m_tileCounts;
@@ -215,7 +210,6 @@ private:
 #undef ANKI_RENDERER_OBJECT_DEF
 	/// @}
 
-	U32 m_tileSize = 0;
 	UVec2 m_tileCounts = UVec2(0u);
 	U32 m_zSplitCount = 0;
 

+ 0 - 1
AnKi/Renderer/ShadowmapsResolve.cpp

@@ -51,7 +51,6 @@ Error ShadowmapsResolve::initInternal()
 	variantInitInfo.addConstant("kFramebufferSize", UVec2(width, height));
 	variantInitInfo.addConstant("kTileCount", getRenderer().getTileCounts());
 	variantInitInfo.addConstant("kZSplitCount", getRenderer().getZSplitCount());
-	variantInitInfo.addConstant("kTileSize", getRenderer().getTileSize());
 	variantInitInfo.addMutation("PCF", g_shadowMappingPcfCVar.get() != 0);
 	variantInitInfo.addMutation("DIRECTIONAL_LIGHT_SHADOW_RESOLVED", getRenderer().getRtShadowsEnabled());
 	const ShaderProgramResourceVariant* variant;

+ 39 - 73
AnKi/Shaders/ClusterBinning2.ankiprog

@@ -12,7 +12,6 @@
 #include <AnKi/Shaders/Include/ClusteredShadingTypes.h>
 #include <AnKi/Shaders/CollisionFunctions.hlsl>
 
-ANKI_SPECIALIZATION_CONSTANT_U32(kTileSize, 0u);
 ANKI_SPECIALIZATION_CONSTANT_U32(kZSplitCount, 1u);
 
 #if OBJECT_TYPE == ANKI_GPU_SCENE_NON_RENDERABLE_OBJECT_TYPE_LIGHT
@@ -52,32 +51,24 @@ struct ClusterBinningUniforms
 
 #define THREADGROUP_SIZE 64
 
-// DX Sample locations
-constexpr U32 kSampleCount = 4u;
-#define LOCATION(x, y) UVec2(Vec2(IVec2(x, y) + 8) / 16.0 * F32(kTileSize))
-constexpr UVec2 kSampleLocations[kSampleCount] = {LOCATION(-2, -6), LOCATION(6, -2), LOCATION(-6, 2), LOCATION(2, 6)};
+// ALMOST like DX Sample locations (https://learn.microsoft.com/en-us/windows/win32/api/d3d11/ne-d3d11-d3d11_standard_multisample_quality_levels)
+constexpr U32 kSampleCount = 8u;
+#define LOCATION(x, y) UVec2(Vec2(IVec2(x, y) + 8) / 16.0 * F32(kClusteredShadingTileSize))
+constexpr UVec2 kSampleLocations[kSampleCount] = {LOCATION(1, -3), LOCATION(-1, 3),  LOCATION(5, 1), LOCATION(-6, -6),
+												  LOCATION(-6, 6), LOCATION(-7, -1), LOCATION(6, 7), LOCATION(7, -7)};
 #undef LOCATION
 
-constexpr U32 kTilesPerThreadgroup = THREADGROUP_SIZE / kSampleCount;
-
-// A mask per tile of this threadgroup for the clusterer object being processed by this workgroup
-groupshared ExtendedClusterObjectMask s_tileMasks[kTilesPerThreadgroup];
-
-// A mask for each Z split for a specific clusterer object
-groupshared ExtendedClusterObjectMask s_zSplitMasks[kMaxZsplitCount];
-
-[numthreads(THREADGROUP_SIZE, 1, 1)] void main(UVec2 svDispatchThreadId : SV_DISPATCHTHREADID, U32 svGroupIdx : SV_GROUPINDEX)
+[numthreads(THREADGROUP_SIZE, 1, 1)] void main(UVec2 svDispatchThreadId : SV_DISPATCHTHREADID)
 {
 	const U32 dispatchThreadIdX = min(svDispatchThreadId.x, g_unis.m_tileCount * kSampleCount);
 	const U32 tileIdx = dispatchThreadIdX / kSampleCount;
 	const U32 sampleIdx = dispatchThreadIdX % kSampleCount;
-	const U32 localTileIdx = svGroupIdx / kSampleCount;
 	const U32 visibleObjectIdx = svDispatchThreadId.y;
 
 	const UVec2 tileXY = UVec2(tileIdx % g_unis.m_tileCountX, tileIdx / g_unis.m_tileCountX);
 
 	// This is a pixel in one of the main framebuffers of the renderer, eg the gbuffer's framebuffers
-	const UVec2 pixel = tileXY * kTileSize + kSampleLocations[sampleIdx];
+	const UVec2 pixel = tileXY * kClusteredShadingTileSize + kSampleLocations[sampleIdx];
 	const Vec2 uv = Vec2(pixel) / g_unis.m_renderingSize;
 	const Vec2 ndc = uvToNdc(uv);
 
@@ -89,16 +80,6 @@ groupshared ExtendedClusterObjectMask s_zSplitMasks[kMaxZsplitCount];
 	const Vec3 rayOrigin = g_unis.m_cameraOrigin;
 	const Vec3 rayDir = normalize(farWorldPos - rayOrigin);
 
-	// Zero shared memory
-	s_tileMasks[localTileIdx] = 0;
-	const U32 splitsPerInvocation = max(1u, kZSplitCount / THREADGROUP_SIZE);
-	for(U32 i = svGroupIdx * splitsPerInvocation; i < (svGroupIdx + 1u) * splitsPerInvocation && i < kZSplitCount; ++i)
-	{
-		s_zSplitMasks[i] = 0;
-	}
-
-	GroupMemoryBarrierWithGroupSync();
-
 	// Do collision
 	F32 t0, t1;
 	Bool collides;
@@ -170,7 +151,26 @@ groupshared ExtendedClusterObjectMask s_zSplitMasks[kMaxZsplitCount];
 	{
 		// Set the tile
 		const ExtendedClusterObjectMask mask = ExtendedClusterObjectMask(1) << ExtendedClusterObjectMask(visibleObjectIdx);
-		InterlockedOr(s_tileMasks[localTileIdx], mask);
+#if OBJECT_TYPE == ANKI_GPU_SCENE_NON_RENDERABLE_OBJECT_TYPE_LIGHT
+		if((U32)obj.m_flags & (U32)GpuSceneLightFlag::kPointLight)
+		{
+			InterlockedOr(g_clusters[tileIdx].m_pointLightsMask, mask);
+		}
+		else
+		{
+			InterlockedOr(g_clusters[tileIdx].m_spotLightsMask, mask);
+		}
+#elif OBJECT_TYPE == ANKI_GPU_SCENE_NON_RENDERABLE_OBJECT_TYPE_DECAL
+		InterlockedOr(g_clusters[tileIdx].m_decalsMask, mask);
+#elif OBJECT_TYPE == ANKI_GPU_SCENE_NON_RENDERABLE_OBJECT_TYPE_FOG_DENSITY_VOLUME
+		InterlockedOr(g_clusters[tileIdx].m_fogDensityVolumesMask, U32(mask));
+#elif OBJECT_TYPE == ANKI_GPU_SCENE_NON_RENDERABLE_OBJECT_TYPE_REFLECTION_PROBE
+		InterlockedOr(g_clusters[tileIdx].m_reflectionProbesMask, U32(mask));
+#elif OBJECT_TYPE == ANKI_GPU_SCENE_NON_RENDERABLE_OBJECT_TYPE_GLOBAL_ILLUMINATION_PROBE
+		InterlockedOr(g_clusters[tileIdx].m_giProbesMask, U32(mask));
+#else
+#	error See file
+#endif
 
 		// Compute and set the Z splits
 		const Vec3 hitpointA = rayDir * t0 + rayOrigin;
@@ -195,61 +195,27 @@ groupshared ExtendedClusterObjectMask s_zSplitMasks[kMaxZsplitCount];
 		const I32 endZSplit = clamp(I32(maxDistFromNearPlane * g_unis.m_zSplitCountOverFrustumLength), 0, I32(kZSplitCount) - 1);
 		for(I32 i = startZSplit; i <= endZSplit; ++i)
 		{
-			InterlockedOr(s_zSplitMasks[i], mask);
-		}
-	}
-
-	// Sync
-	GroupMemoryBarrierWithGroupSync();
-
-	// First sample writes the tile mask
-	if(sampleIdx == 0u && s_tileMasks[localTileIdx] != 0)
-	{
 #if OBJECT_TYPE == ANKI_GPU_SCENE_NON_RENDERABLE_OBJECT_TYPE_LIGHT
-		if((U32)obj.m_flags & (U32)GpuSceneLightFlag::kPointLight)
-		{
-			InterlockedOr(g_clusters[tileIdx].m_pointLightsMask, s_tileMasks[localTileIdx]);
-		}
-		else
-		{
-			InterlockedOr(g_clusters[tileIdx].m_spotLightsMask, s_tileMasks[localTileIdx]);
-		}
+			if((U32)obj.m_flags & (U32)GpuSceneLightFlag::kPointLight)
+			{
+				InterlockedOr(g_clusters[g_unis.m_tileCount + i].m_pointLightsMask, mask);
+			}
+			else
+			{
+				InterlockedOr(g_clusters[g_unis.m_tileCount + i].m_spotLightsMask, mask);
+			}
 #elif OBJECT_TYPE == ANKI_GPU_SCENE_NON_RENDERABLE_OBJECT_TYPE_DECAL
-		InterlockedOr(g_clusters[tileIdx].m_decalsMask, s_tileMasks[localTileIdx]);
+			InterlockedOr(g_clusters[g_unis.m_tileCount + i].m_decalsMask, mask);
 #elif OBJECT_TYPE == ANKI_GPU_SCENE_NON_RENDERABLE_OBJECT_TYPE_FOG_DENSITY_VOLUME
-		InterlockedOr(g_clusters[tileIdx].m_fogDensityVolumesMask, U32(s_tileMasks[localTileIdx]));
+			InterlockedOr(g_clusters[g_unis.m_tileCount + i].m_fogDensityVolumesMask, U32(mask));
 #elif OBJECT_TYPE == ANKI_GPU_SCENE_NON_RENDERABLE_OBJECT_TYPE_REFLECTION_PROBE
-		InterlockedOr(g_clusters[tileIdx].m_reflectionProbesMask, U32(s_tileMasks[localTileIdx]));
+			InterlockedOr(g_clusters[g_unis.m_tileCount + i].m_reflectionProbesMask, U32(mask));
 #elif OBJECT_TYPE == ANKI_GPU_SCENE_NON_RENDERABLE_OBJECT_TYPE_GLOBAL_ILLUMINATION_PROBE
-		InterlockedOr(g_clusters[tileIdx].m_giProbesMask, U32(s_tileMasks[localTileIdx]));
+			InterlockedOr(g_clusters[g_unis.m_tileCount + i].m_giProbesMask, U32(mask));
 #else
 #	error See file
 #endif
-	}
-
-	// All invocations write at least one Z split
-	for(U32 i = svGroupIdx * splitsPerInvocation; i < (svGroupIdx + 1u) * splitsPerInvocation && i < kZSplitCount; ++i)
-	{
-#if OBJECT_TYPE == ANKI_GPU_SCENE_NON_RENDERABLE_OBJECT_TYPE_LIGHT
-		if((U32)obj.m_flags & (U32)GpuSceneLightFlag::kPointLight)
-		{
-			InterlockedOr(g_clusters[g_unis.m_tileCount + i].m_pointLightsMask, s_zSplitMasks[i]);
 		}
-		else
-		{
-			InterlockedOr(g_clusters[g_unis.m_tileCount + i].m_spotLightsMask, s_zSplitMasks[i]);
-		}
-#elif OBJECT_TYPE == ANKI_GPU_SCENE_NON_RENDERABLE_OBJECT_TYPE_DECAL
-		InterlockedOr(g_clusters[g_unis.m_tileCount + i].m_decalsMask, s_zSplitMasks[i]);
-#elif OBJECT_TYPE == ANKI_GPU_SCENE_NON_RENDERABLE_OBJECT_TYPE_FOG_DENSITY_VOLUME
-		InterlockedOr(g_clusters[g_unis.m_tileCount + i].m_fogDensityVolumesMask, U32(s_zSplitMasks[i]));
-#elif OBJECT_TYPE == ANKI_GPU_SCENE_NON_RENDERABLE_OBJECT_TYPE_REFLECTION_PROBE
-		InterlockedOr(g_clusters[g_unis.m_tileCount + i].m_reflectionProbesMask, U32(s_zSplitMasks[i]));
-#elif OBJECT_TYPE == ANKI_GPU_SCENE_NON_RENDERABLE_OBJECT_TYPE_GLOBAL_ILLUMINATION_PROBE
-		InterlockedOr(g_clusters[g_unis.m_tileCount + i].m_giProbesMask, U32(s_zSplitMasks[i]));
-#else
-#	error See file
-#endif
 	}
 }
 

+ 1 - 1
AnKi/Shaders/ClusterBinning2Setup.ankiprog

@@ -25,7 +25,7 @@ struct Uniforms
 };
 [[vk::push_constant]] ConstantBuffer<Uniforms> g_unis;
 
-constexpr U32 kSampleCount = 4;
+constexpr U32 kSampleCount = 8;
 constexpr U32 kClusterBinningThreadgroupSize = 64;
 constexpr U32 kPackVisiblesThreadgroupSize = 64;
 

+ 5 - 6
AnKi/Shaders/ClusteredShadingFunctions.hlsl

@@ -56,9 +56,9 @@ U32 computeZSplitClusterIndex(F32 depth, U32 zSplitCount, F32 a, F32 b)
 }
 
 /// Return the tile index.
-U32 computeTileClusterIndexFragCoord(Vec2 fragCoord, U32 tileSize, U32 tileCountX)
+U32 computeTileClusterIndexFragCoord(Vec2 fragCoord, U32 tileCountX)
 {
-	const UVec2 tileXY = UVec2(fragCoord / F32(tileSize));
+	const UVec2 tileXY = UVec2(fragCoord / F32(kClusteredShadingTileSize));
 	return tileXY.y * tileCountX + tileXY.x;
 }
 
@@ -82,15 +82,14 @@ Cluster mergeClusters(Cluster tileCluster, Cluster zCluster)
 }
 
 /// Get the final cluster after ORing and ANDing the masks.
-Cluster getClusterFragCoord(StructuredBuffer<Cluster> clusters, Vec3 fragCoord, U32 tileSize, UVec2 tileCounts, U32 zSplitCount, F32 a, F32 b)
+Cluster getClusterFragCoord(StructuredBuffer<Cluster> clusters, Vec3 fragCoord, UVec2 tileCounts, U32 zSplitCount, F32 a, F32 b)
 {
-	const Cluster tileCluster = clusters[computeTileClusterIndexFragCoord(fragCoord.xy, tileSize, tileCounts.x)];
+	const Cluster tileCluster = clusters[computeTileClusterIndexFragCoord(fragCoord.xy, tileCounts.x)];
 	const Cluster zCluster = clusters[computeZSplitClusterIndex(fragCoord.z, zSplitCount, a, b) + tileCounts.x * tileCounts.y];
 	return mergeClusters(tileCluster, zCluster);
 }
 
 Cluster getClusterFragCoord(StructuredBuffer<Cluster> clusters, ClusteredShadingUniforms unis, Vec3 fragCoord)
 {
-	return getClusterFragCoord(clusters, fragCoord, unis.m_tileSize, unis.m_tileCounts, unis.m_zSplitCount, unis.m_zSplitMagic.x,
-							   unis.m_zSplitMagic.y);
+	return getClusterFragCoord(clusters, fragCoord, unis.m_tileCounts, unis.m_zSplitCount, unis.m_zSplitMagic.x, unis.m_zSplitMagic.y);
 }

+ 2 - 3
AnKi/Shaders/GBufferPost.ankiprog

@@ -14,7 +14,6 @@
 
 ANKI_SPECIALIZATION_CONSTANT_UVEC2(kTileCount, 0u);
 ANKI_SPECIALIZATION_CONSTANT_U32(kZSplitCount, 2u);
-ANKI_SPECIALIZATION_CONSTANT_U32(kTileSize, 3u);
 
 [[vk::binding(0)]] SamplerState g_nearestAnyClampSampler;
 [[vk::binding(1)]] Texture2D g_depthTex;
@@ -51,8 +50,8 @@ FragOut main([[vk::location(0)]] Vec2 uv : TEXCOORD, Vec4 svPosition : SV_POSITI
 	const Vec3 worldPos = worldPos4.xyz / worldPos4.w;
 
 	// Get the cluster
-	const Cluster cluster = getClusterFragCoord(g_clusters, Vec3(svPosition.xy, depth), kTileSize, kTileCount, kZSplitCount,
-												g_clusteredShading.m_zSplitMagic.x, g_clusteredShading.m_zSplitMagic.y);
+	const Cluster cluster = getClusterFragCoord(g_clusters, Vec3(svPosition.xy, depth), kTileCount, kZSplitCount, g_clusteredShading.m_zSplitMagic.x,
+												g_clusteredShading.m_zSplitMagic.y);
 
 	// Make the decalsMask uniform across the wave because we are accessing bindless textures later on
 	ExtendedClusterObjectMask decalsMask = WaveActiveBitAnd(cluster.m_decalsMask);

+ 2 - 1
AnKi/Shaders/Include/ClusteredShadingTypes.h

@@ -27,6 +27,7 @@ constexpr U32 kMaxVisibleGlobalIlluminationProbes = 8u;
 constexpr RF32 kClusterObjectFrustumNearPlane = 0.1f / 4.0f; ///< Near plane of all clusterer object frustums.
 constexpr RF32 kSubsurfaceMin = 0.01f;
 constexpr U32 kMaxZsplitCount = 128u;
+constexpr U32 kClusteredShadingTileSize = 64; ///< The size of the tile in clustered shading.
 
 /// A union of all fields of spot and point lights. Since we don't have unions in HLSL we had to get creative.
 struct LightUnion
@@ -175,8 +176,8 @@ struct ClusteredShadingUniforms
 	F32 m_zSplitCountOverFrustumLength; ///< m_zSplitCount/(far-near)
 
 	Vec2 m_zSplitMagic; ///< It's the "a" and "b" of computeZSplitClusterIndex(). See there for details.
-	U32 m_tileSize;
 	U32 m_lightVolumeLastZSplit;
+	U32 m_padding1;
 
 	UVec2 m_padding0;
 	F32 m_near;

+ 2 - 3
AnKi/Shaders/LightShading.ankiprog

@@ -15,7 +15,6 @@
 
 ANKI_SPECIALIZATION_CONSTANT_UVEC2(kTileCount, 0u);
 ANKI_SPECIALIZATION_CONSTANT_U32(kZSplitCount, 2u);
-ANKI_SPECIALIZATION_CONSTANT_U32(kTileSize, 3u);
 
 [[vk::binding(0)]] ConstantBuffer<ClusteredShadingUniforms> g_clusteredShading;
 [[vk::binding(1)]] StructuredBuffer<PointLight> g_pointLights;
@@ -56,8 +55,8 @@ RVec3 main(Vec4 svPosition : SV_POSITION, Vec2 uv : TEXCOORD) : SV_TARGET0
 	const Vec3 worldPos = worldPos4.xyz / worldPos4.w;
 
 	// Get the cluster
-	Cluster cluster = getClusterFragCoord(g_clusters, Vec3(svPosition.xy, depth), kTileSize, kTileCount, kZSplitCount,
-										  g_clusteredShading.m_zSplitMagic.x, g_clusteredShading.m_zSplitMagic.y);
+	Cluster cluster = getClusterFragCoord(g_clusters, Vec3(svPosition.xy, depth), kTileCount, kZSplitCount, g_clusteredShading.m_zSplitMagic.x,
+										  g_clusteredShading.m_zSplitMagic.y);
 
 	// return clusterHeatmap(cluster, 1u << (U32)ClusteredObjectType::kPointLight);
 

+ 1 - 2
AnKi/Shaders/ShadowmapsResolve.hlsl

@@ -11,7 +11,6 @@
 ANKI_SPECIALIZATION_CONSTANT_UVEC2(kFramebufferSize, 0u);
 ANKI_SPECIALIZATION_CONSTANT_UVEC2(kTileCount, 2u);
 ANKI_SPECIALIZATION_CONSTANT_U32(kZSplitCount, 4u);
-ANKI_SPECIALIZATION_CONSTANT_U32(kTileSize, 5u);
 
 #define DEBUG_CASCADES 0
 
@@ -87,7 +86,7 @@ RVec4 main(Vec2 uv : TEXCOORD) : SV_TARGET0
 
 	// Cluster
 	const Vec2 fragCoord = uv * g_clusteredShading.m_renderingSize;
-	Cluster cluster = getClusterFragCoord(g_clusters, Vec3(fragCoord, depth), kTileSize, kTileCount, kZSplitCount, g_clusteredShading.m_zSplitMagic.x,
+	Cluster cluster = getClusterFragCoord(g_clusters, Vec3(fragCoord, depth), kTileCount, kZSplitCount, g_clusteredShading.m_zSplitMagic.x,
 										  g_clusteredShading.m_zSplitMagic.y);
 
 	// Layers