Просмотр исходного кода

Making clusters a bit more flexible. Also removed some weird bitshifts from light shaders

Panagiotis Christopoulos Charitos 9 лет назад
Родитель
Сommit
0dcc7c3994
5 измененных файлов с 67 добавлено и 96 удалено
  1. 3 1
      shaders/Common.glsl
  2. 9 15
      shaders/FsCommonFrag.glsl
  3. 23 27
      shaders/Is.frag.glsl
  4. 0 15
      shaders/IsFsCommon.glsl
  5. 32 38
      src/renderer/LightBin.cpp

+ 3 - 1
shaders/Common.glsl

@@ -30,7 +30,9 @@ precision DEFAULT_FLOAT_PRECISION int;
 
 const float EPSILON = 0.000001;
 const float PI = 3.14159265358979323846;
-const uint UBO_MAX_SIZE = 16384;
+const uint UBO_MAX_SIZE = 16384u;
+
+const uint MAX_U32 = 0xFFFFFFFFu;
 
 // Read from a render target texture
 //#define textureRt(tex_, texc_) texture(tex_, texc_)

+ 9 - 15
shaders/FsCommonFrag.glsl

@@ -138,9 +138,8 @@ vec3 computeLightColor(vec3 diffCol)
 	}
 
 	// Find the cluster and then the light counts
-	uint lightOffset;
-	uint pointLightCount;
-	uint spotLightCount;
+	uint idxOffset;
+	uint idx;
 	{
 		uint clusterIdx = computeClusterIndexUsingCustomFragCoord(
 			u_lightingUniforms.nearFarClustererMagicPad1.x,
@@ -150,19 +149,14 @@ vec3 computeLightColor(vec3 diffCol)
 			u_lightingUniforms.tileCountPad1.y,
 			gl_FragCoord.xy * 2.0);
 
-		uint probeCount;
-		getClusterInfo(clusterIdx,
-			lightOffset,
-			pointLightCount,
-			spotLightCount,
-			probeCount);
+		idxOffset = u_clusters[clusterIdx];
 	}
 
 	// Point lights
-	for(uint i = 0U; i < pointLightCount; ++i)
+	uint count = u_lightIndices[idxOffset++];
+	while(count-- != 0)
 	{
-		uint lightId = u_lightIndices[lightOffset++];
-		PointLight light = u_pointLights[lightId];
+		PointLight light = u_pointLights[u_lightIndices[idxOffset++]];
 
 		vec3 diffC =
 			computeDiffuseColor(diffCol, light.diffuseColorShadowmapId.rgb);
@@ -189,10 +183,10 @@ vec3 computeLightColor(vec3 diffCol)
 	}
 
 	// Spot lights
-	for(uint i = 0U; i < spotLightCount; ++i)
+	count = u_lightIndices[idxOffset++];
+	while(count-- != 0)
 	{
-		uint lightId = u_lightIndices[lightOffset++];
-		SpotLight light = u_spotLights[lightId];
+		SpotLight light = u_spotLights[u_lightIndices[idxOffset++]];
 
 		vec3 diffC =
 			computeDiffuseColor(diffCol, light.diffuseColorShadowmapId.rgb);

+ 23 - 27
shaders/Is.frag.glsl

@@ -69,8 +69,7 @@ void debugIncorrectColor(inout vec3 c)
 }
 
 //==============================================================================
-void readIndirect(in uint indexOffset,
-	in uint probeCount,
+void readIndirect(in uint idxOffset,
 	in vec3 posVSpace,
 	in vec3 r,
 	in vec3 n,
@@ -82,10 +81,10 @@ void readIndirect(in uint indexOffset,
 	diffIndirect = vec3(0.0);
 
 	// Check proxy
-	for(uint i = 0; i < probeCount; ++i)
+	uint count = u_lightIndices[idxOffset++];
+	while(count-- != 0)
 	{
-		uint probeIndex = u_lightIndices[indexOffset++];
-		ReflectionProbe probe = u_reflectionProbes[probeIndex];
+		ReflectionProbe probe = u_reflectionProbes[u_lightIndices[idxOffset++]];
 
 		float R2 = probe.positionRadiusSq.w;
 		vec3 center = probe.positionRadiusSq.xyz;
@@ -116,6 +115,13 @@ void readIndirect(in uint indexOffset,
 	}
 }
 
+bool getNewIndex(inout uint idxOffset, out uint idx)
+{
+	idx = u_lightIndices[idxOffset];
+	++idxOffset;
+	return idx != MAX_U32;
+}
+
 //==============================================================================
 void main()
 {
@@ -156,22 +162,18 @@ void main()
 		TILE_COUNT_X,
 		TILE_COUNT_Y);
 
-	uint lightOffset;
-	uint pointLightCount;
-	uint spotLightCount;
-	uint probeCount;
-	getClusterInfo(
-		clusterIdx, lightOffset, pointLightCount, spotLightCount, probeCount);
+	uint idxOffset = u_clusters[clusterIdx];
+	uint idx;
 
 	// Shadowpass sample count
 	uint shadowSampleCount =
 		computeShadowSampleCount(SHADOW_SAMPLE_COUNT, fragPos.z);
 
 	// Point lights
-	for(uint i = 0U; i < pointLightCount; ++i)
+	uint count = u_lightIndices[idxOffset++];
+	while(count-- != 0)
 	{
-		uint lightId = u_lightIndices[lightOffset++];
-		PointLight light = u_pointLights[lightId];
+		PointLight light = u_pointLights[u_lightIndices[idxOffset++]];
 
 		LIGHTING_COMMON_BRDF();
 
@@ -193,10 +195,10 @@ void main()
 	}
 
 	// Spot lights
-	for(uint i = 0U; i < spotLightCount; ++i)
+	count = u_lightIndices[idxOffset++];
+	while(count-- != 0)
 	{
-		uint lightId = u_lightIndices[lightOffset++];
-		SpotLight light = u_spotLights[lightId];
+		SpotLight light = u_spotLights[u_lightIndices[idxOffset++]];
 
 		LIGHTING_COMMON_BRDF();
 
@@ -228,14 +230,8 @@ void main()
 	float reflLod = float(IR_MIPMAP_COUNT) * gbuffer.roughness;
 
 	vec3 specIndirect, diffIndirect;
-	readIndirect(lightOffset,
-		probeCount,
-		fragPos,
-		r,
-		normal,
-		reflLod,
-		specIndirect,
-		diffIndirect);
+	readIndirect(
+		idxOffset, fragPos, r, normal, reflLod, specIndirect, diffIndirect);
 
 	diffIndirect *= gbuffer.diffuse;
 
@@ -247,8 +243,8 @@ void main()
 	out_color += specIndirect + diffIndirect;
 #endif
 
-#if 0 && INDIRECT_ENABLED
-	uint count = probeCount;
+#if 0
+	uint count = scount;
 	if(count == 0)
 	{
 		out_color = vec3(1.0, 0.0, 0.0);

+ 0 - 15
shaders/IsFsCommon.glsl

@@ -102,21 +102,6 @@ layout(ANKI_TEX_BINDING(
 layout(ANKI_TEX_BINDING(
 	LIGHT_SET, LIGHT_TEX_BINDING + 4)) uniform sampler2D u_integrationLut;
 
-//==============================================================================
-// Get element count attached in a cluster
-void getClusterInfo(in uint clusterIdx,
-	out uint indexOffset,
-	out uint pointLightCount,
-	out uint spotLightCount,
-	out uint probeCount)
-{
-	uint cluster = u_clusters[clusterIdx];
-	indexOffset = cluster >> 16u;
-	probeCount = (cluster >> 8u) & 0xFu;
-	pointLightCount = (cluster >> 4u) & 0xFu;
-	spotLightCount = cluster & 0xFu;
-}
-
 #endif // FRAGMENT_SHADER
 
 #endif

+ 32 - 38
src/renderer/LightBin.cpp

@@ -19,16 +19,17 @@ namespace anki
 // Misc                                                                        =
 //==============================================================================
 
+/// This should be the number of light types. For now it's spots & points & 
+/// probes.
+const U SIZE_IDX_COUNT = 3;
+
 // Shader structs and block representations. All positions and directions in
 // viewspace
 // For documentation see the shaders
 
 struct ShaderCluster
 {
-	/// If m_combo = 0xFFFF?CAB then FFFF is the light index offset, A the
-	/// number of point lights and B the number of spot lights, C the number
-	/// of probes
-	U32 m_combo;
+	U32 m_firstIdx;
 };
 
 struct ShaderLight
@@ -456,6 +457,14 @@ Error LightBin::bin(FrustumComponent& frc,
 
 	ctx.m_lightIds = WeakArray<U32>(data2, maxLightIndices);
 
+	// Fill the first part of light ids with invalid indices. Will be used
+	// for empty clusters
+	for(U i = 0; i < SIZE_IDX_COUNT; ++i)
+	{
+		ctx.m_lightIds[i] = 0;
+	}
+	ctx.m_lightIdsCount.set(SIZE_IDX_COUNT);
+
 	// Fire the async job
 	for(U i = 0; i < m_threadPool->getThreadsCount(); i++)
 	{
@@ -571,7 +580,7 @@ void LightBin::binLights(
 			const U count = countP + countS + countProbe;
 
 			auto& c = ctx.m_clusters[i];
-			c.m_combo = 0;
+			c.m_firstIdx = 0; // Point to the first empty indices
 
 			// Early exit
 			if(ANKI_UNLIKELY(count == 0))
@@ -589,53 +598,38 @@ void LightBin::binLights(
 
 				if(cluster == clusterB)
 				{
-					c.m_combo = ctx.m_clusters[i - 1].m_combo;
+					c.m_firstIdx = ctx.m_clusters[i - 1].m_firstIdx;
 					continue;
 				}
 			}
 
-			U offset = ctx.m_lightIdsCount.fetchAdd(count);
+			U offset = ctx.m_lightIdsCount.fetchAdd(count + SIZE_IDX_COUNT);
+			U initialOffset = offset;
+			(void)initialOffset;
 
-			if(offset + count <= ctx.m_maxLightIndices)
+			if(offset + count + SIZE_IDX_COUNT <= ctx.m_maxLightIndices)
 			{
-				ANKI_ASSERT(offset <= 0xFFFF);
-				c.m_combo = offset << 16;
+				c.m_firstIdx = offset;
 
-				if(countP > 0)
+				ctx.m_lightIds[offset++] = countP;
+				for(U i = 0; i < countP; ++i)
 				{
-					ANKI_ASSERT(countP <= 0xF);
-					c.m_combo |= countP << 4;
-
-					for(U i = 0; i < countP; ++i)
-					{
-						ctx.m_lightIds[offset++] =
-							cluster.m_pointIds[i].getIndex();
-					}
+					ctx.m_lightIds[offset++] = cluster.m_pointIds[i].getIndex();
 				}
 
-				if(countS > 0)
+				ctx.m_lightIds[offset++] = countS;
+				for(U i = 0; i < countS; ++i)
 				{
-					ANKI_ASSERT(countS <= 0xF);
-					c.m_combo |= countS;
-
-					for(U i = 0; i < countS; ++i)
-					{
-						ctx.m_lightIds[offset++] =
-							cluster.m_spotIds[i].getIndex();
-					}
+					ctx.m_lightIds[offset++] = cluster.m_spotIds[i].getIndex();
 				}
 
-				if(countProbe > 0)
+				ctx.m_lightIds[offset++] = countProbe;
+				for(U i = 0; i < countProbe; ++i)
 				{
-					ANKI_ASSERT(countProbe <= 0xF);
-					c.m_combo |= countProbe << 8;
-
-					for(U i = 0; i < countProbe; ++i)
-					{
-						ctx.m_lightIds[offset++] =
-							cluster.m_probeIds[i].getIndex();
-					}
+					ctx.m_lightIds[offset++] = cluster.m_probeIds[i].getIndex();
 				}
+
+				ANKI_ASSERT(offset - initialOffset == count + SIZE_IDX_COUNT);
 			}
 			else
 			{
@@ -716,7 +710,7 @@ I LightBin::writeSpotLight(const LightComponent& lightc,
 			* lightFrc->getViewProjectionMatrix()
 			* Mat4(camMove.getWorldTransform());
 
-		shadowmapIndex = (F32)lightc.getShadowMapIndex();
+		shadowmapIndex = F32(lightc.getShadowMapIndex());
 	}
 
 	// Pos & dist