Browse Source

More work

Panagiotis Christopoulos Charitos 4 years ago
parent
commit
e70fec48fa

+ 8 - 4
AnKi/Renderer/ClusterBinning.cpp

@@ -411,16 +411,17 @@ void ClusterBinning::writeClustererBuffersTask()
 		unis.m_nearPlaneWSpace = Vec4(nearPlane.getNormal().xyz(), nearPlane.getOffset());
 		unis.m_nearPlaneWSpace = Vec4(nearPlane.getNormal().xyz(), nearPlane.getOffset());
 		unis.m_near = rqueue.m_cameraNear;
 		unis.m_near = rqueue.m_cameraNear;
 		unis.m_far = rqueue.m_cameraFar;
 		unis.m_far = rqueue.m_cameraFar;
-		unis.m_zSplitCountOverFrustumLength = F32(m_r->getZSplitCount()) / (rqueue.m_cameraFar - rqueue.m_cameraNear);
 		unis.m_cameraPosition = rqueue.m_cameraTransform.getTranslationPart().xyz();
 		unis.m_cameraPosition = rqueue.m_cameraTransform.getTranslationPart().xyz();
 
 
 		unis.m_tileCounts = m_r->getTileCounts();
 		unis.m_tileCounts = m_r->getTileCounts();
 		unis.m_zSplitCount = m_r->getZSplitCount();
 		unis.m_zSplitCount = m_r->getZSplitCount();
+		unis.m_zSplitCountOverFrustumLength = F32(m_r->getZSplitCount()) / (rqueue.m_cameraFar - rqueue.m_cameraNear);
+		unis.m_zSplitMagic.x() =
+			(rqueue.m_cameraNear - rqueue.m_cameraFar) / (rqueue.m_cameraNear * F32(m_r->getZSplitCount()));
+		unis.m_zSplitMagic.y() = rqueue.m_cameraFar / (rqueue.m_cameraNear * F32(m_r->getZSplitCount()));
+		unis.m_tileSize = F32(m_r->getTileSize());
 		unis.m_lightVolumeLastCluster = m_r->getVolumetricLightingAccumulation().getFinalClusterInZ();
 		unis.m_lightVolumeLastCluster = m_r->getVolumetricLightingAccumulation().getFinalClusterInZ();
 
 
-		unis.m_matrices = ctx.m_matrices;
-		unis.m_previousMatrices = ctx.m_prevMatrices;
-
 		unis.m_pointLightCount = rqueue.m_pointLights.getSize();
 		unis.m_pointLightCount = rqueue.m_pointLights.getSize();
 		unis.m_spotLightCount = rqueue.m_spotLights.getSize();
 		unis.m_spotLightCount = rqueue.m_spotLights.getSize();
 		unis.m_decalCount = rqueue.m_decals.getSize();
 		unis.m_decalCount = rqueue.m_decals.getSize();
@@ -428,6 +429,9 @@ void ClusterBinning::writeClustererBuffersTask()
 		unis.m_reflectionProbeCount = rqueue.m_reflectionProbes.getSize();
 		unis.m_reflectionProbeCount = rqueue.m_reflectionProbes.getSize();
 		unis.m_giProbeCount = rqueue.m_giProbes.getSize();
 		unis.m_giProbeCount = rqueue.m_giProbes.getSize();
 
 
+		unis.m_matrices = ctx.m_matrices;
+		unis.m_previousMatrices = ctx.m_prevMatrices;
+
 		// Directional light
 		// Directional light
 		if(rqueue.m_directionalLight.m_uuid != 0)
 		if(rqueue.m_directionalLight.m_uuid != 0)
 		{
 		{

+ 56 - 15
AnKi/Shaders/ClusteredShadingCommon2.glsl

@@ -99,41 +99,82 @@ layout(set = CLUSTERED_SHADING_SET, binding = CLUSTER_SHADING_CLUSTERS_BINDING,
 #endif
 #endif
 
 
 // Debugging function
 // Debugging function
-Vec3 lightHeatmap2(U32 firstIndex, U32 maxObjects, U32 typeMask)
+Vec3 clusterHeatmap(Cluster cluster, U32 objectTypeMask)
 {
 {
-	U32 count = 0;
-	U32 idx;
+	U32 maxObjects = 0u;
+	U32 count = 0u;
 
 
-	while((idx = u_lightIndices[firstIndex++]) != MAX_U32)
+	if((objectTypeMask & (1u << CLUSTER_OBJECT_TYPE_POINT_LIGHT)) != 0)
 	{
 	{
-		count += ((typeMask & (1u << 0u)) != 0u) ? 1u : 0u;
+		maxObjects += MAX_VISIBLE_POINT_LIGHTS;
+		count += bitCount(cluster.m_pointLightsMask);
 	}
 	}
 
 
-	while((idx = u_lightIndices[firstIndex++]) != MAX_U32)
+	if((objectTypeMask & (1u << CLUSTER_OBJECT_TYPE_SPOT_LIGHT)) != 0)
 	{
 	{
-		count += ((typeMask & (1u << 1u)) != 0u) ? 1u : 0u;
+		maxObjects += MAX_VISIBLE_SPOT_LIGHTS;
+		count += bitCount(cluster.m_spotLightsMask);
 	}
 	}
 
 
-	while((idx = u_lightIndices[firstIndex++]) != MAX_U32)
+	if((objectTypeMask & (1u << CLUSTER_OBJECT_TYPE_DECAL)) != 0)
 	{
 	{
-		count += ((typeMask & (1u << 2u)) != 0u) ? 1u : 0u;
+		maxObjects += MAX_VISIBLE_DECALS;
+		count += bitCount(cluster.m_decalsMask);
 	}
 	}
 
 
-	while((idx = u_lightIndices[firstIndex++]) != MAX_U32)
+	if((objectTypeMask & (1u << CLUSTER_OBJECT_TYPE_FOG_DENSITY_VOLUME)) != 0)
 	{
 	{
-		count += ((typeMask & (1u << 3u)) != 0u) ? 1u : 0u;
+		maxObjects += MAX_VISIBLE_FOG_DENSITY_VOLUMES;
+		count += bitCount(cluster.m_fogDensityVolumesMask);
 	}
 	}
 
 
-	while((idx = u_lightIndices[firstIndex++]) != MAX_U32)
+	if((objectTypeMask & (1u << CLUSTER_OBJECT_TYPE_REFLECTION_PROBE)) != 0)
 	{
 	{
-		count += ((typeMask & (1u << 4u)) != 0u) ? 1u : 0u;
+		maxObjects += MAX_VISIBLE_REFLECTION_PROBES;
+		count += bitCount(cluster.m_reflectionProbesMask);
 	}
 	}
 
 
-	while((idx = u_lightIndices[firstIndex++]) != MAX_U32)
+	if((objectTypeMask & (1u << CLUSTER_OBJECT_TYPE_GLOBAL_ILLUMINATION_PROBE)) != 0)
 	{
 	{
-		count += ((typeMask & (1u << 5u)) != 0u) ? 1u : 0u;
+		maxObjects += MAX_VISIBLE_GLOBAL_ILLUMINATION_PROBES;
+		count += bitCount(cluster.m_giProbesMask);
 	}
 	}
 
 
 	const F32 factor = min(1.0, F32(count) / F32(maxObjects));
 	const F32 factor = min(1.0, F32(count) / F32(maxObjects));
 	return heatmap(factor);
 	return heatmap(factor);
 }
 }
+
+/// Returns the index of the zSplit or linearizeDepth(n, f, depth)*zSplitCount
+/// Simplifying this equation is 1/(a+b/depth) where a=(n-f)/(n*zSplitCount) and b=f/(n*zSplitCount)
+U32 computeZSplitClusterIndex(F32 depth, U32 zSplitCount, F32 a, F32 b)
+{
+	const F32 fSplitIdx = 1.0 / (a + b / depth);
+	return min(zSplitCount - 1u, U32(fSplitIdx));
+}
+
+/// Return the tile index.
+U32 computeTileClusterIndex(Vec2 uv, U32 tileCountX, U32 tileCountY)
+{
+	return U32(uv.y * F32(tileCountY * tileCountX) + uv.x * F32(tileCountX));
+}
+
+#if defined(CLUSTER_SHADING_CLUSTERS_BINDING)
+/// Get the final cluster after ORing and ANDing the masks.
+Cluster getCluster(F32 uv, F32 depth, U32 tileCountX, U32 tileCountY, U32 zSplitCount, F32 a, F32 b)
+{
+	const Cluster tileCluster = u_clusters2[computeTileClusterIndex(uv, tileCountX, tileCountY)];
+	const Cluster zCluster = u_clusters2[computeZSplitClusterIndex(depth, zSplitCount, a, b) + tileCountX * tileCountY];
+
+	Cluster outCluster;
+	outCluster.m_pointLightsMask = subgroupOr(tileCluster.m_pointLightsMask & zCluster.m_pointLightsMask);
+	outCluster.m_spotLightsMask = subgroupOr(tileCluster.m_spotLightsMask & zCluster.m_spotLightsMask);
+	outCluster.m_decalsMask = subgroupOr(tileCluster.m_decalsMask & zCluster.m_decalsMask);
+	outCluster.m_fogDensityVolumesMask =
+		subgroupOr(tileCluster.m_fogDensityVolumesMask & zCluster.m_fogDensityVolumesMask);
+	outCluster.m_reflectionProbesMask =
+		subgroupOr(tileCluster.m_reflectionProbesMask & zCluster.m_reflectionProbesMask);
+	outCluster.m_giProbesMask = subgroupOr(tileCluster.m_giProbesMask & zCluster.m_giProbesMask);
+
+	return outCluster;
+}
+#endif

+ 6 - 2
AnKi/Shaders/Include/ClusteredShadingTypes2.h

@@ -177,11 +177,13 @@ struct ClusteredShadingUniforms
 	Vec4 m_nearPlaneWSpace;
 	Vec4 m_nearPlaneWSpace;
 	F32 m_near;
 	F32 m_near;
 	F32 m_far;
 	F32 m_far;
-	F32 m_zSplitCountOverFrustumLength; ///< m_zSplitCount/(far-near)
 	Vec3 m_cameraPosition;
 	Vec3 m_cameraPosition;
 
 
 	UVec2 m_tileCounts;
 	UVec2 m_tileCounts;
 	U32 m_zSplitCount;
 	U32 m_zSplitCount;
+	F32 m_zSplitCountOverFrustumLength; ///< m_zSplitCount/(far-near)
+	Vec2 m_zSplitMagic; ///< It's the "a" and "b" of computeZSplitClusterIndex(). See there for details.
+	F32 m_tileSize;
 	U32 m_lightVolumeLastCluster;
 	U32 m_lightVolumeLastCluster;
 
 
 	U32 m_pointLightCount;
 	U32 m_pointLightCount;
@@ -191,13 +193,15 @@ struct ClusteredShadingUniforms
 	U32 m_reflectionProbeCount;
 	U32 m_reflectionProbeCount;
 	U32 m_giProbeCount;
 	U32 m_giProbeCount;
 
 
+	U32 m_padding;
+
 	CommonMatrices m_matrices;
 	CommonMatrices m_matrices;
 	CommonMatrices m_previousMatrices;
 	CommonMatrices m_previousMatrices;
 
 
 	DirectionalLight2 m_directionalLight;
 	DirectionalLight2 m_directionalLight;
 };
 };
 const U32 _ANKI_SIZEOF_ClusteredShadingUniforms =
 const U32 _ANKI_SIZEOF_ClusteredShadingUniforms =
-	24u * ANKI_SIZEOF(U32) + 2u * ANKI_SIZEOF(CommonMatrices) + ANKI_SIZEOF(DirectionalLight2);
+	28u * ANKI_SIZEOF(U32) + 2u * ANKI_SIZEOF(CommonMatrices) + ANKI_SIZEOF(DirectionalLight2);
 ANKI_SHADER_STATIC_ASSERT(sizeof(ClusteredShadingUniforms) == _ANKI_SIZEOF_ClusteredShadingUniforms);
 ANKI_SHADER_STATIC_ASSERT(sizeof(ClusteredShadingUniforms) == _ANKI_SIZEOF_ClusteredShadingUniforms);
 
 
 /// Information that a tile or a Z-split will contain.
 /// Information that a tile or a Z-split will contain.