Skip to content

Commit

Permalink
fix: shadow cascade sampling (#520)
Browse files Browse the repository at this point in the history
* fix: shadow cascade sampling

* fix: tree LOD ambient brightness

* style: 🎨 apply clang-format changes

---------

Co-authored-by: doodlum <doodlum@users.noreply.github.com>
  • Loading branch information
doodlum and doodlum authored Sep 11, 2024
1 parent 8c8c2d1 commit 9dbfc1d
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 19 deletions.
31 changes: 14 additions & 17 deletions package/Shaders/Common/ShadowSampling.hlsli
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,18 @@ struct PerGeometry

StructuredBuffer<PerGeometry> SharedPerShadow : register(t26);

float GetShadowDepth(float3 positionWS, uint eyeIndex)
{
float4 positionCSShifted = mul(CameraViewProj[eyeIndex], float4(positionWS, 1));
return positionCSShifted.z / positionCSShifted.w;
}

float3 Get3DFilteredShadow(float3 positionWS, float3 viewDirection, float2 screenPosition, uint eyeIndex)
{
PerGeometry sD = SharedPerShadow[0];
sD.EndSplitDistances.x = GetScreenDepth(sD.EndSplitDistances.x);
sD.EndSplitDistances.z = GetScreenDepth(sD.EndSplitDistances.z);
sD.StartSplitDistances.y = GetScreenDepth(sD.StartSplitDistances.y);

float shadowMapDepth = length(positionWS.xyz);

float fadeFactor = 1.0 - pow(saturate(dot(positionWS.xyz, positionWS.xyz) / sD.ShadowLightParam.z), 8);
uint sampleCount = ceil(8.0 * (1.0 - saturate(shadowMapDepth / sqrt(sD.ShadowLightParam.z))));
float fadeFactor = 1.0 - pow(saturate(dot(positionWS, positionWS) / sD.ShadowLightParam.z), 8);
uint sampleCount = ceil(8.0 * (1.0 - saturate(length(positionWS) / sqrt(sD.ShadowLightParam.z))));

if (sampleCount == 0)
return 1.0;
Expand All @@ -43,9 +44,8 @@ float3 Get3DFilteredShadow(float3 positionWS, float3 viewDirection, float2 scree
compareValue.y = mul(transpose(sD.ShadowMapProj[eyeIndex][1]), float4(positionWS, 1)).z;

float shadow = 0.0;
[unroll] for (int i = 0; i < sampleCount; i++)
{
if (sD.EndSplitDistances.z >= shadowMapDepth) {
if (sD.EndSplitDistances.z >= GetShadowDepth(positionWS, eyeIndex)) {
for (int i = 0; i < sampleCount; i++) {
float3 rnd = R3Modified(i + FrameCount * sampleCount, seed / 4294967295.f);

// https://stats.stackexchange.com/questions/8021/how-to-generate-uniformly-distributed-points-in-the-3-d-unit-ball
Expand All @@ -58,14 +58,14 @@ float3 Get3DFilteredShadow(float3 positionWS, float3 viewDirection, float2 scree
float3 sampleOffset = viewDirection * i * 256 * rcpSampleCount;
sampleOffset += float3(r * sin_theta * sincos_phi.x, r * sin_theta * sincos_phi.y, r * cos_theta) * 32;

uint cascadeIndex = (sD.EndSplitDistances.x < shadowMapDepth + dot(sampleOffset, float2(1, 1))); // Stochastic cascade sampling
uint cascadeIndex = sD.EndSplitDistances.x < GetShadowDepth(positionWS.xyz + viewDirection * dot(sampleOffset, float2(1, 1)), eyeIndex); // Stochastic cascade sampling
float3 positionLS = mul(transpose(sD.ShadowMapProj[eyeIndex][cascadeIndex]), float4(positionWS + sampleOffset, 1));

float4 depths = SharedTexShadowMapSampler.GatherRed(LinearSampler, float3(saturate(positionLS.xy), cascadeIndex), 0);
shadow += dot(depths > compareValue[cascadeIndex], 0.25);
} else {
shadow++;
}
} else {
shadow = 1.0;
}

return lerp(1.0, shadow * rcpSampleCount, fadeFactor);
Expand Down Expand Up @@ -100,10 +100,7 @@ float3 Get2DFilteredShadow(float noise, float2x2 rotationMatrix, float3 position
{
PerGeometry sD = SharedPerShadow[0];

float4 positionCSShifted = mul(transpose(CameraViewProj[eyeIndex]), float4(positionWS, 1));
positionCSShifted /= positionCSShifted.w;

float shadowMapDepth = positionCSShifted.z;
float shadowMapDepth = GetShadowDepth(positionWS, eyeIndex);

if (sD.EndSplitDistances.z >= shadowMapDepth) {
float fadeFactor = 1 - pow(saturate(dot(positionWS.xyz, positionWS.xyz) / sD.ShadowLightParam.z), 8);
Expand Down
4 changes: 2 additions & 2 deletions package/Shaders/DistantTree.hlsl
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ PS_OUTPUT main(PS_INPUT input)
float dirShadow = 1;

# if defined(SCREEN_SPACE_SHADOWS)
dirShadow = lerp(0.5, 1.0, ScreenSpaceShadows::GetScreenSpaceShadow(input.Position, screenUV, screenNoise, viewPosition, eyeIndex));
dirShadow = ScreenSpaceShadows::GetScreenSpaceShadow(input.Position, screenUV, screenNoise, viewPosition, eyeIndex);
# endif

# if defined(TERRA_OCC)
Expand Down Expand Up @@ -252,7 +252,7 @@ PS_OUTPUT main(PS_INPUT input)
psout.Normal.xy = EncodeNormal(WorldToView(normal, false, eyeIndex));
psout.Normal.zw = 0;

psout.Albedo = float4(baseColor.xyz * 0.5, 1);
psout.Albedo = float4(baseColor.xyz, 1);
psout.Masks = float4(0, 0, 1, 0);
# else
float3 ddx = ddx_coarse(input.WorldPosition);
Expand Down

0 comments on commit 9dbfc1d

Please sign in to comment.