Browse Source

Add directional lights to volumetric lighting accumulation. Some refactoring

Panagiotis Christopoulos Charitos 7 years ago
parent
commit
80f4961c45

+ 6 - 6
shaders/ClusteredShadingCommon.glsl

@@ -19,17 +19,17 @@ layout(ANKI_UBO_BINDING(LIGHT_SET, LIGHT_UBO_BINDING), std140, row_major) unifor
 	LightingUniforms u_lightingUniforms;
 };
 
-#	define u_near UNIFORM(u_lightingUniforms.m_rendererSizeTimeNear.w)
-#	define u_far UNIFORM(u_lightingUniforms.m_cameraPosFar.w)
-#	define u_cameraPos UNIFORM(u_lightingUniforms.m_cameraPosFar.xyz)
+#	define u_near UNIFORM(u_lightingUniforms.m_near)
+#	define u_far UNIFORM(u_lightingUniforms.m_far)
+#	define u_cameraPos UNIFORM(u_lightingUniforms.m_cameraPos)
 #	define u_clusterCountX UNIFORM(u_lightingUniforms.m_clusterCount.x)
 #	define u_clusterCountY UNIFORM(u_lightingUniforms.m_clusterCount.y)
 #	define u_clustererMagic u_lightingUniforms.m_clustererMagicValues
 #	define u_prevClustererMagic u_lightingUniforms.m_prevClustererMagicValues
-#	define u_time UNIFORM(u_lightingUniforms.m_rendererSizeTimeNear.z)
+#	define u_time UNIFORM(u_lightingUniforms.m_time)
 #	define u_unprojectionParams UNIFORM(u_lightingUniforms.m_unprojectionParams)
-#	define u_rendererSize u_lightingUniforms.m_rendererSizeTimeNear.xy
-#	define u_lightVolumeLastCluster UNIFORM(u_lightingUniforms.m_lightVolumeLastClusterPad3.x)
+#	define u_rendererSize u_lightingUniforms.m_rendererSize
+#	define u_lightVolumeLastCluster UNIFORM(u_lightingUniforms.m_lightVolumeLastCluster)
 
 #	define u_viewMat u_lightingUniforms.m_viewMat
 #	define u_invViewMat u_lightingUniforms.m_invViewMat

+ 31 - 5
shaders/VolumetricLightingAccumulation.glslp

@@ -54,7 +54,7 @@ Vec3 readRand()
 	return textureLod(u_noiseTex, uv, 0.0).rgb;
 }
 
-Vec3 worldPosInsideCluster(Vec3 relativePos)
+Vec3 worldPosInsideClusterAndZViewSpace(Vec3 relativePos, out F32 negativeZViewSpace)
 {
 	// Compute the cluster Z as float
 	F32 clusterKNear = g_globalInvocationID.z * (F32(FINAL_CLUSTER_Z + 1u) / F32(VOLUME_SIZE.z));
@@ -62,7 +62,8 @@ Vec3 worldPosInsideCluster(Vec3 relativePos)
 	F32 clusterK = mix(clusterKNear, clusterKFar, relativePos.z);
 
 	// Get a Z value
-	F32 zVSpace = -computeClusterNearf(u_clustererMagic, clusterK);
+	negativeZViewSpace = computeClusterNearf(u_clustererMagic, clusterK);
+	F32 zVSpace = -negativeZViewSpace;
 
 	// Get a XY value
 	Vec2 uvMin = g_globalInvocationID.xy / Vec2(VOLUME_SIZE.xy);
@@ -78,6 +79,12 @@ Vec3 worldPosInsideCluster(Vec3 relativePos)
 	return worldPos;
 }
 
+Vec3 worldPosInsideCluster(Vec3 relativePos)
+{
+	F32 unused;
+	return worldPosInsideClusterAndZViewSpace(relativePos, unused);
+}
+
 // https://developer.nvidia.com/gpugems/GPUGems2/gpugems2_chapter16.html
 F32 phaseFunction(Vec3 viewDir, Vec3 lightDir, F32 g)
 {
@@ -91,7 +98,7 @@ F32 phaseFunction(Vec3 viewDir, Vec3 lightDir, F32 g)
 	return saturate(a * b);
 }
 
-Vec4 accumulateLightsAndFog(U32 clusterIdx, Vec3 worldPos)
+Vec4 accumulateLightsAndFog(U32 clusterIdx, Vec3 worldPos, F32 linearDepth)
 {
 	Vec3 color = Vec3(0.0);
 	Vec3 viewDir = normalize(u_cameraPos - worldPos);
@@ -99,6 +106,23 @@ Vec4 accumulateLightsAndFog(U32 clusterIdx, Vec3 worldPos)
 	// Get ID offset
 	U32 idxOffset = u_clusters[clusterIdx];
 
+	// Dir light
+	if(u_dirLight.m_cascadeCount > 0u)
+	{
+		F32 cascadeCountf = F32(u_dirLight.m_cascadeCount);
+		U32 cascadeIdx = min(U32(linearDepth * cascadeCountf), u_dirLight.m_cascadeCount - 1u);
+
+#if ENABLE_SHADOWS
+		F32 factor = computeShadowFactorDirLight(u_dirLight, cascadeIdx, worldPos, u_shadowTex);
+#else
+		F32 factor = 1.0;
+#endif
+
+		factor *= phaseFunction(viewDir, u_dirLight.m_dir, PHASE_FUNCTION_ANISOTROPY);
+
+		color += u_dirLight.m_diffuseColor * factor;
+	}
+
 	// Point lights
 	U32 idx;
 	ANKI_LOOP while((idx = u_lightIndices[idxOffset++]) != MAX_U32)
@@ -207,10 +231,12 @@ void main()
 	U32 clusterIdx = clusterXYZ.z * (CLUSTER_COUNT.x * CLUSTER_COUNT.y) + clusterXYZ.y * CLUSTER_COUNT.x + clusterXYZ.x;
 
 	// Find a random pos inside the cluster
-	Vec3 worldPos = worldPosInsideCluster(readRand());
+	F32 negativeZViewSpace;
+	Vec3 worldPos = worldPosInsideClusterAndZViewSpace(readRand(), negativeZViewSpace);
 
 	// Get lighting
-	Vec4 lightAndFog = accumulateLightsAndFog(clusterIdx, worldPos);
+	F32 linearDepth = negativeZViewSpace / (u_far - u_near);
+	Vec4 lightAndFog = accumulateLightsAndFog(clusterIdx, worldPos, linearDepth);
 
 	// Read the prev result
 	{

+ 11 - 3
shaders/glsl_cpp_common/ClusteredShading.h

@@ -3,6 +3,8 @@
 // Code licensed under the BSD License.
 // http://www.anki3d.org/LICENSE
 
+// Mainly contains light related structures. Everything is packed to align with std140
+
 #pragma once
 
 #include <shaders/glsl_cpp_common/Common.h>
@@ -105,12 +107,16 @@ ANKI_SHADER_STATIC_ASSERT(sizeof(FogDensityVolume) == SIZEOF_FOG_DENSITY_VOLUME)
 struct LightingUniforms
 {
 	Vec4 m_unprojectionParams;
-	Vec4 m_rendererSizeTimeNear;
-	Vec4 m_cameraPosFar;
+	Vec2 m_rendererSize;
+	F32 m_time;
+	F32 m_near;
+	Vec3 m_cameraPos;
+	F32 m_far;
 	ClustererMagicValues m_clustererMagicValues;
 	ClustererMagicValues m_prevClustererMagicValues;
 	UVec4 m_clusterCount;
-	UVec4 m_lightVolumeLastClusterPad3;
+	Vec3 m_padding;
+	U32 m_lightVolumeLastCluster;
 	Mat4 m_viewMat;
 	Mat4 m_invViewMat;
 	Mat4 m_projMat;
@@ -121,6 +127,8 @@ struct LightingUniforms
 	Mat4 m_prevViewProjMatMulInvViewProjMat; // Used to re-project previous frames
 	DirectionalLight m_dirLight;
 };
+const U32 SIZEOF_LIGHTING_UNIFORMS = 9 * SIZEOF_VEC4 + 8 * SIZEOF_MAT4 + SIZEOF_DIR_LIGHT;
+ANKI_SHADER_STATIC_ASSERT(sizeof(LightingUniforms) == SIZEOF_LIGHTING_UNIFORMS)
 
 ANKI_SHADER_FUNC_INLINE F32 computeClusterKf(ClustererMagicValues magic, Vec3 worldPos)
 {

+ 6 - 5
src/anki/renderer/Renderer.cpp

@@ -537,18 +537,19 @@ void Renderer::updateLightShadingUniforms(RenderingContext& ctx) const
 	// Start writing
 	blk->m_unprojectionParams = ctx.m_unprojParams;
 
-	blk->m_rendererSizeTimeNear =
-		Vec4(m_width, m_height, HighRezTimer::getCurrentTime(), ctx.m_renderQueue->m_cameraNear);
+	blk->m_rendererSize = Vec2(m_width, m_height);
+	blk->m_time = HighRezTimer::getCurrentTime();
+	blk->m_near = ctx.m_renderQueue->m_cameraNear;
 
 	blk->m_clusterCount = UVec4(m_clusterCount[0], m_clusterCount[1], m_clusterCount[2], m_clusterCount[3]);
 
-	blk->m_cameraPosFar =
-		Vec4(ctx.m_renderQueue->m_cameraTransform.getTranslationPart().xyz(), ctx.m_renderQueue->m_cameraFar);
+	blk->m_cameraPos = ctx.m_renderQueue->m_cameraTransform.getTranslationPart().xyz();
+	blk->m_far = ctx.m_renderQueue->m_cameraFar;
 
 	blk->m_clustererMagicValues = ctx.m_clusterBinOut.m_shaderMagicValues;
 	blk->m_prevClustererMagicValues = ctx.m_prevClustererMagicValues;
 
-	blk->m_lightVolumeLastClusterPad3 = UVec4(m_volLighting->getFinalClusterInZ());
+	blk->m_lightVolumeLastCluster = m_volLighting->getFinalClusterInZ();
 
 	// Matrices
 	blk->m_viewMat = ctx.m_renderQueue->m_viewMatrix;