|
@@ -54,7 +54,7 @@ Vec3 readRand()
|
|
|
return textureLod(u_noiseTex, uv, 0.0).rgb;
|
|
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
|
|
// Compute the cluster Z as float
|
|
|
F32 clusterKNear = g_globalInvocationID.z * (F32(FINAL_CLUSTER_Z + 1u) / F32(VOLUME_SIZE.z));
|
|
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);
|
|
F32 clusterK = mix(clusterKNear, clusterKFar, relativePos.z);
|
|
|
|
|
|
|
|
// Get a Z value
|
|
// Get a Z value
|
|
|
- F32 zVSpace = -computeClusterNearf(u_clustererMagic, clusterK);
|
|
|
|
|
|
|
+ negativeZViewSpace = computeClusterNearf(u_clustererMagic, clusterK);
|
|
|
|
|
+ F32 zVSpace = -negativeZViewSpace;
|
|
|
|
|
|
|
|
// Get a XY value
|
|
// Get a XY value
|
|
|
Vec2 uvMin = g_globalInvocationID.xy / Vec2(VOLUME_SIZE.xy);
|
|
Vec2 uvMin = g_globalInvocationID.xy / Vec2(VOLUME_SIZE.xy);
|
|
@@ -78,6 +79,12 @@ Vec3 worldPosInsideCluster(Vec3 relativePos)
|
|
|
return worldPos;
|
|
return worldPos;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+Vec3 worldPosInsideCluster(Vec3 relativePos)
|
|
|
|
|
+{
|
|
|
|
|
+ F32 unused;
|
|
|
|
|
+ return worldPosInsideClusterAndZViewSpace(relativePos, unused);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
// https://developer.nvidia.com/gpugems/GPUGems2/gpugems2_chapter16.html
|
|
// https://developer.nvidia.com/gpugems/GPUGems2/gpugems2_chapter16.html
|
|
|
F32 phaseFunction(Vec3 viewDir, Vec3 lightDir, F32 g)
|
|
F32 phaseFunction(Vec3 viewDir, Vec3 lightDir, F32 g)
|
|
|
{
|
|
{
|
|
@@ -91,7 +98,7 @@ F32 phaseFunction(Vec3 viewDir, Vec3 lightDir, F32 g)
|
|
|
return saturate(a * b);
|
|
return saturate(a * b);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-Vec4 accumulateLightsAndFog(U32 clusterIdx, Vec3 worldPos)
|
|
|
|
|
|
|
+Vec4 accumulateLightsAndFog(U32 clusterIdx, Vec3 worldPos, F32 linearDepth)
|
|
|
{
|
|
{
|
|
|
Vec3 color = Vec3(0.0);
|
|
Vec3 color = Vec3(0.0);
|
|
|
Vec3 viewDir = normalize(u_cameraPos - worldPos);
|
|
Vec3 viewDir = normalize(u_cameraPos - worldPos);
|
|
@@ -99,6 +106,23 @@ Vec4 accumulateLightsAndFog(U32 clusterIdx, Vec3 worldPos)
|
|
|
// Get ID offset
|
|
// Get ID offset
|
|
|
U32 idxOffset = u_clusters[clusterIdx];
|
|
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
|
|
// Point lights
|
|
|
U32 idx;
|
|
U32 idx;
|
|
|
ANKI_LOOP while((idx = u_lightIndices[idxOffset++]) != MAX_U32)
|
|
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;
|
|
U32 clusterIdx = clusterXYZ.z * (CLUSTER_COUNT.x * CLUSTER_COUNT.y) + clusterXYZ.y * CLUSTER_COUNT.x + clusterXYZ.x;
|
|
|
|
|
|
|
|
// Find a random pos inside the cluster
|
|
// Find a random pos inside the cluster
|
|
|
- Vec3 worldPos = worldPosInsideCluster(readRand());
|
|
|
|
|
|
|
+ F32 negativeZViewSpace;
|
|
|
|
|
+ Vec3 worldPos = worldPosInsideClusterAndZViewSpace(readRand(), negativeZViewSpace);
|
|
|
|
|
|
|
|
// Get lighting
|
|
// Get lighting
|
|
|
- Vec4 lightAndFog = accumulateLightsAndFog(clusterIdx, worldPos);
|
|
|
|
|
|
|
+ F32 linearDepth = negativeZViewSpace / (u_far - u_near);
|
|
|
|
|
+ Vec4 lightAndFog = accumulateLightsAndFog(clusterIdx, worldPos, linearDepth);
|
|
|
|
|
|
|
|
// Read the prev result
|
|
// Read the prev result
|
|
|
{
|
|
{
|