فهرست منبع

Move FW shading to the new clustered shading

Panagiotis Christopoulos Charitos 4 سال پیش
والد
کامیت
c571a643b8

+ 1 - 1
AnKi/Renderer/ClusterBinning.cpp

@@ -422,7 +422,7 @@ void ClusterBinning::writeClustererBuffersTask()
 		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_tileSize = m_r->getTileSize();
 		unis.m_lightVolumeLastCluster = m_r->getVolumetricLightingAccumulation().getFinalClusterInZ();
 
 		unis.m_pointLightCount = rqueue.m_pointLights.getSize();

+ 2 - 3
AnKi/Renderer/ForwardShading.cpp

@@ -40,18 +40,17 @@ void ForwardShading::run(const RenderingContext& ctx, RenderPassWorkContext& rgr
 		cmdb->setDepthWrite(false);
 		cmdb->setBlendFactors(0, BlendFactor::SRC_ALPHA, BlendFactor::ONE_MINUS_SRC_ALPHA);
 
-		const ClusterBinOut& rsrc = ctx.m_clusterBinOut;
+		const ClustererGpuObjects& rsrc = ctx.m_clusterShading;
 		cmdb->bindSampler(0, 0, m_r->getSamplers().m_trilinearClamp);
 
 		rgraphCtx.bindTexture(0, 1, m_r->getDepthDownscale().getHiZRt(), HIZ_HALF_DEPTH);
 		rgraphCtx.bindColorTexture(0, 2, m_r->getVolumetricLightingAccumulation().getRt());
 
-		bindUniforms(cmdb, 0, 3, ctx.m_lightShadingUniformsToken);
+		bindUniforms(cmdb, 0, 3, rsrc.m_clusteredShadingUniformsToken);
 		bindUniforms(cmdb, 0, 4, rsrc.m_pointLightsToken);
 		bindUniforms(cmdb, 0, 5, rsrc.m_spotLightsToken);
 		rgraphCtx.bindColorTexture(0, 6, m_r->getShadowMapping().getShadowmapRt());
 		bindStorage(cmdb, 0, 7, rsrc.m_clustersToken);
-		bindStorage(cmdb, 0, 8, rsrc.m_indicesToken);
 
 		// Start drawing
 		m_r->getSceneDrawer().drawRange(Pass::FS, ctx.m_matrices.m_view, ctx.m_matrices.m_viewProjectionJitter,

+ 1 - 1
AnKi/Renderer/LightShading.cpp

@@ -189,7 +189,7 @@ void LightShading::run(RenderPassWorkContext& rgraphCtx)
 	}
 
 	// Forward shading last
-	// TODO m_r->getForwardShading().run(ctx, rgraphCtx);
+	m_r->getForwardShading().run(ctx, rgraphCtx);
 }
 
 void LightShading::populateRenderGraph(RenderingContext& ctx)

+ 1 - 0
AnKi/Renderer/Renderer.cpp

@@ -295,6 +295,7 @@ Error Renderer::populateRenderGraph(RenderingContext& ctx)
 	ctx.m_matrices.m_viewProjectionJitter = ctx.m_matrices.m_projectionJitter * ctx.m_matrices.m_view;
 	ctx.m_matrices.m_invertedViewProjectionJitter = ctx.m_matrices.m_viewProjectionJitter.getInverse();
 	ctx.m_matrices.m_invertedViewProjection = ctx.m_matrices.m_viewProjection.getInverse();
+	ctx.m_matrices.m_invertedProjectionJitter = ctx.m_matrices.m_projectionJitter.getInverse();
 
 	ctx.m_matrices.m_unprojectionParameters = ctx.m_matrices.m_projection.extractPerspectiveUnprojectionParams();
 

+ 7 - 0
AnKi/Shaders/ClusteredShadingCommon2.glsl

@@ -180,5 +180,12 @@ Cluster getCluster(F32 depth, U32 tileSize, U32 tileCountX, U32 tileCountY, U32
 
 	return outCluster;
 }
+
+Cluster getCluster(F32 depth)
+{
+	return getCluster(depth, u_clusterShading.m_tileSize, u_clusterShading.m_tileCounts.x,
+					  u_clusterShading.m_tileCounts.y, u_clusterShading.m_zSplitCount, u_clusterShading.m_zSplitMagic.x,
+					  u_clusterShading.m_zSplitMagic.y);
+}
 #	endif
 #endif // defined(ANKI_FRAGMENT_SHADER)

+ 27 - 25
AnKi/Shaders/ForwardShadingCommonFrag.glsl

@@ -13,14 +13,11 @@
 layout(set = 0, binding = 0) uniform sampler u_linearAnyClampSampler;
 layout(set = 0, binding = 1) uniform texture2D u_gbufferDepthRt;
 layout(set = 0, binding = 2) uniform texture3D u_lightVol;
-#define LIGHT_SET 0
-#define LIGHT_COMMON_UNIS_BINDING 3
-#define LIGHT_LIGHTS_BINDING 4
-#define LIGHT_CLUSTERS_BINDING 7
-#include <AnKi/Shaders/ClusteredShadingCommon.glsl>
-
-#define anki_u_time u_time
-#define RENDERER_SIZE (u_rendererSize)
+#define CLUSTERED_SHADING_SET 0
+#define CLUSTERED_SHADING_UNIFORMS_BINDING 3
+#define CLUSTERED_SHADING_LIGHTS_BINDING 4
+#define CLUSTERED_SHADING_CLUSTERS_BINDING 7
+#include <AnKi/Shaders/ClusteredShadingCommon2.glsl>
 
 layout(location = 0) out Vec4 out_color;
 
@@ -43,16 +40,14 @@ Vec3 computeLightColorHigh(Vec3 diffCol, Vec3 worldPos)
 	Vec3 outColor = Vec3(0.0);
 
 	// Find the cluster and then the light counts
-	const U32 clusterIdx = computeClusterIndex(u_clustererMagic, gl_FragCoord.xy / RENDERER_SIZE, worldPos,
-											   u_clusterCountX, u_clusterCountY);
-
-	U32 idxOffset = u_clusters[clusterIdx];
+	Cluster cluster = getCluster(gl_FragCoord.z);
 
 	// Point lights
-	U32 idx;
-	ANKI_LOOP while((idx = u_lightIndices[idxOffset++]) != MAX_U32)
+	ANKI_LOOP while(cluster.m_pointLightsMask != 0u)
 	{
-		const PointLight light = u_pointLights[idx];
+		const I32 idx = findLSB64(cluster.m_pointLightsMask);
+		cluster.m_pointLightsMask &= ~(1ul << U64(idx));
+		const PointLight2 light = u_pointLights2[idx];
 
 		const Vec3 diffC = diffCol * light.m_diffuseColor;
 
@@ -65,7 +60,7 @@ Vec3 computeLightColorHigh(Vec3 diffCol, Vec3 worldPos)
 		F32 shadow = 1.0;
 		if(light.m_shadowAtlasTileScale >= 0.0)
 		{
-			shadow = computeShadowFactorPointLight(light, frag2Light, u_shadowTex, u_linearAnyClampSampler);
+			shadow = computeShadowFactorPointLight(light, frag2Light, u_shadowAtlasTex, u_linearAnyClampSampler);
 		}
 #endif
 
@@ -73,9 +68,11 @@ Vec3 computeLightColorHigh(Vec3 diffCol, Vec3 worldPos)
 	}
 
 	// Spot lights
-	ANKI_LOOP while((idx = u_lightIndices[idxOffset++]) != MAX_U32)
+	ANKI_LOOP while(cluster.m_spotLightsMask != 0u)
 	{
-		const SpotLight light = u_spotLights[idx];
+		const I32 idx = findLSB64(cluster.m_spotLightsMask);
+		cluster.m_spotLightsMask &= ~(1ul << U64(idx));
+		const SpotLight2 light = u_spotLights2[idx];
 
 		const Vec3 diffC = diffCol * light.m_diffuseColor;
 
@@ -84,16 +81,15 @@ Vec3 computeLightColorHigh(Vec3 diffCol, Vec3 worldPos)
 
 		const Vec3 l = normalize(frag2Light);
 
-		const F32 spot = computeSpotFactor(l, light.m_outerCos, light.m_innerCos, light.m_dir);
+		const F32 spot = computeSpotFactor(l, light.m_outerCos, light.m_innerCos, light.m_direction);
 
 #if LOD > 1
 		const F32 shadow = 1.0;
 #else
 		F32 shadow = 1.0;
-		const F32 shadowmapLayerIdx = light.m_shadowmapId;
-		if(shadowmapLayerIdx >= 0.0)
+		ANKI_BRANCH if(light.m_shadowLayer != MAX_U32)
 		{
-			shadow = computeShadowFactorSpotLight(light, worldPos, u_shadowTex, u_linearAnyClampSampler);
+			shadow = computeShadowFactorSpotLight(light, worldPos, u_shadowAtlasTex, u_linearAnyClampSampler);
 		}
 #endif
 
@@ -106,11 +102,16 @@ Vec3 computeLightColorHigh(Vec3 diffCol, Vec3 worldPos)
 // Just read the light color from the vol texture
 Vec3 computeLightColorLow(Vec3 diffCol, Vec3 worldPos)
 {
-	const Vec2 uv = gl_FragCoord.xy / RENDERER_SIZE;
+	// TODO
+#if 0
+	const Vec2 uv = gl_FragCoord.xy / u_clusterShading.m_renderingSize;
 	const Vec3 uv3d = computeClustererVolumeTextureUvs(u_clustererMagic, uv, worldPos, u_lightVolumeLastCluster + 1u);
 
 	const Vec3 light = textureLod(u_lightVol, u_linearAnyClampSampler, uv3d, 0.0).rgb;
 	return diffuseLambert(diffCol) * light;
+#else
+	return Vec3(diffCol);
+#endif
 }
 
 void particleAlpha(Vec4 color, Vec4 scaleColor, Vec4 biasColor)
@@ -120,13 +121,14 @@ void particleAlpha(Vec4 color, Vec4 scaleColor, Vec4 biasColor)
 
 void fog(Vec3 color, F32 fogAlphaScale, F32 fogDistanceOfMaxThikness, F32 zVSpace)
 {
-	const Vec2 screenSize = 1.0 / RENDERER_SIZE;
+	const Vec2 screenSize = 1.0 / u_clusterShading.m_renderingSize;
 
 	const Vec2 texCoords = gl_FragCoord.xy * screenSize;
 	const F32 depth = textureLod(u_gbufferDepthRt, u_linearAnyClampSampler, texCoords, 0.0).r;
 	F32 zFeatherFactor;
 
-	const Vec4 fragPosVspace4 = u_invProjMat * Vec4(Vec3(UV_TO_NDC(texCoords), depth), 1.0);
+	const Vec4 fragPosVspace4 =
+		u_clusterShading.m_matrices.m_invertedProjectionJitter * Vec4(Vec3(UV_TO_NDC(texCoords), depth), 1.0);
 	const F32 sceneZVspace = fragPosVspace4.z / fragPosVspace4.w;
 
 	const F32 diff = max(0.0, zVSpace - sceneZVspace);

+ 1 - 1
AnKi/Shaders/ForwardShadingParticles.ankiprog

@@ -62,7 +62,7 @@ void main()
 {
 #if ANIMATED_TEXTURE == 1
 	Vec4 texCol = readAnimatedTextureRgba(u_diffuseMapArr, u_ankiGlobalSampler, u_ankiPerDraw.m_animationPeriod, in_uv,
-										  anki_u_time);
+										  u_clusterShading.m_time);
 #else
 	Vec4 texCol = texture(u_diffuseMap, u_ankiGlobalSampler, in_uv);
 #endif

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

@@ -160,10 +160,11 @@ struct CommonMatrices
 
 	Mat4 m_invertedViewProjectionJitter ANKI_CPP_CODE(= Mat4::getIdentity()); ///< To unproject in world space.
 	Mat4 m_invertedViewProjection ANKI_CPP_CODE(= Mat4::getIdentity());
+	Mat4 m_invertedProjectionJitter ANKI_CPP_CODE(= Mat4::getIdentity()); ///< To unproject in view space.
 
 	Vec4 m_unprojectionParameters ANKI_CPP_CODE(= Vec4(0.0f)); ///< To unproject to view space. Jitter not considered.
 };
-const U32 _ANKI_SIZEOF_CommonMatrices = 9u * ANKI_SIZEOF(Mat4) + ANKI_SIZEOF(Vec4);
+const U32 _ANKI_SIZEOF_CommonMatrices = 10u * ANKI_SIZEOF(Mat4) + ANKI_SIZEOF(Vec4);
 ANKI_SHADER_STATIC_ASSERT(sizeof(CommonMatrices) == _ANKI_SIZEOF_CommonMatrices);
 
 /// Common uniforms for light shading passes.
@@ -183,7 +184,7 @@ struct ClusteredShadingUniforms
 	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_tileSize;
 	U32 m_lightVolumeLastCluster;
 
 	U32 m_pointLightCount;

+ 55 - 0
AnKi/Shaders/LightFunctions.glsl

@@ -164,6 +164,7 @@ U32 computeShadowSampleCount(const U32 COUNT, F32 zVSpace)
 	return sampleCount;
 }
 
+// TODO rm
 F32 computeShadowFactorSpotLight(SpotLight light, Vec3 worldPos, texture2D spotMap, sampler spotMapSampler)
 {
 	const Vec4 texCoords4 = light.m_texProjectionMat * Vec4(worldPos, 1.0);
@@ -174,7 +175,18 @@ F32 computeShadowFactorSpotLight(SpotLight light, Vec3 worldPos, texture2D spotM
 	return evsmComputeShadowFactor(texCoords3.z, shadowMoments);
 }
 
+F32 computeShadowFactorSpotLight(SpotLight2 light, Vec3 worldPos, texture2D spotMap, sampler spotMapSampler)
+{
+	const Vec4 texCoords4 = light.m_textureMatrix * Vec4(worldPos, 1.0);
+	const Vec3 texCoords3 = texCoords4.xyz / texCoords4.w;
+
+	const Vec4 shadowMoments = textureLod(spotMap, spotMapSampler, texCoords3.xy, 0.0);
+
+	return evsmComputeShadowFactor(texCoords3.z, shadowMoments);
+}
+
 // Compute the shadow factor of point (omni) lights.
+// TODO rm
 F32 computeShadowFactorPointLight(PointLight light, Vec3 frag2Light, texture2D shadowMap, sampler shadowMapSampler)
 {
 	const Vec3 dir = -frag2Light;
@@ -217,6 +229,49 @@ F32 computeShadowFactorPointLight(PointLight light, Vec3 frag2Light, texture2D s
 	return shadowFactor;
 }
 
+// Compute the shadow factor of point (omni) lights.
+F32 computeShadowFactorPointLight(PointLight2 light, Vec3 frag2Light, texture2D shadowMap, sampler shadowMapSampler)
+{
+	const Vec3 dir = -frag2Light;
+	const Vec3 dirabs = abs(dir);
+	const F32 dist = max(dirabs.x, max(dirabs.y, dirabs.z));
+
+	// 1) Project the dist to light's proj mat
+	//
+	const F32 near = LIGHT_FRUSTUM_NEAR_PLANE;
+	const F32 far = light.m_radius;
+	const F32 g = near - far;
+
+	const F32 zVSpace = -dist;
+	const F32 w = -zVSpace;
+	F32 z = (far * zVSpace + far * near) / g;
+	z /= w;
+
+	// 2) Read shadow tex
+	//
+
+	// Convert cube coords
+	U32 faceIdxu;
+	Vec2 uv = convertCubeUvsu(dir, faceIdxu);
+
+	// Get the atlas offset
+	Vec2 atlasOffset;
+	atlasOffset.x = light.m_shadowAtlasTileOffsets[faceIdxu >> 1u][(faceIdxu & 1u) << 1u];
+	atlasOffset.y = light.m_shadowAtlasTileOffsets[faceIdxu >> 1u][((faceIdxu & 1u) << 1u) + 1u];
+
+	// Compute UV
+	uv = fma(uv, Vec2(light.m_shadowAtlasTileScale), atlasOffset);
+
+	// Sample
+	const Vec4 shadowMoments = textureLod(shadowMap, shadowMapSampler, uv, 0.0);
+
+	// 3) Compare
+	//
+	const F32 shadowFactor = evsmComputeShadowFactor(z, shadowMoments);
+
+	return shadowFactor;
+}
+
 // Compute the shadow factor of a directional light
 F32 computeShadowFactorDirLight(DirectionalLight light, U32 cascadeIdx, Vec3 worldPos, texture2D shadowMap,
 								sampler shadowMapSampler)