rendering: formalize main light shadow params

This commit is contained in:
2026-04-13 01:06:09 +08:00
parent 64212a53c7
commit 2ee74e7761
8 changed files with 94 additions and 61 deletions

View File

@@ -65,6 +65,21 @@ Shader "XC Character Toon"
float4 spotAnglesAndFlags;
};
struct ShadowMapMetrics
{
float2 inverseMapSize;
float worldTexelSize;
float padding;
};
struct ShadowSamplingData
{
float enabled;
float receiverDepthBias;
float normalBiasScale;
float shadowStrength;
};
cbuffer LightingConstants
{
float4 gMainLightDirectionAndIntensity;
@@ -116,8 +131,8 @@ Shader "XC Character Toon"
cbuffer ShadowReceiverConstants
{
float4x4 gWorldToShadowMatrix;
float4 gShadowBiasAndTexelSize;
float4 gShadowOptions;
ShadowMapMetrics gShadowMapMetrics;
ShadowSamplingData gShadowSampling;
};
Texture2D BaseColorTexture;
@@ -250,7 +265,7 @@ Shader "XC Character Toon"
#ifndef XC_MAIN_LIGHT_SHADOWS
return 1.0f;
#else
if (gShadowOptions.x < 0.5f) {
if (gShadowSampling.enabled < 0.5f) {
return 1.0f;
}
@@ -258,7 +273,8 @@ Shader "XC Character Toon"
const float3 resolvedLightDirectionWS =
NormalizeSafe(lightDirectionWS, float3(0.0f, -1.0f, 0.0f));
const float nDotL = saturate(dot(resolvedNormalWS, resolvedLightDirectionWS));
const float normalBiasWorld = gShadowOptions.y * gShadowOptions.z * (1.0f - nDotL);
const float normalBiasWorld =
gShadowMapMetrics.worldTexelSize * gShadowSampling.normalBiasScale * (1.0f - nDotL);
const float3 shadowPositionWS = positionWS + resolvedNormalWS * normalBiasWorld;
const float4 shadowClip = mul(gWorldToShadowMatrix, float4(shadowPositionWS, 1.0f));
if (shadowClip.w <= 0.0f) {
@@ -279,7 +295,7 @@ Shader "XC Character Toon"
return 1.0f;
}
const float receiverDepth = shadowNdc.z * 0.5f + 0.5f - gShadowBiasAndTexelSize.x;
const float receiverDepth = shadowNdc.z * 0.5f + 0.5f - gShadowSampling.receiverDepthBias;
#else
if (shadowUv.x < 0.0f || shadowUv.x > 1.0f ||
shadowUv.y < 0.0f || shadowUv.y > 1.0f ||
@@ -287,9 +303,9 @@ Shader "XC Character Toon"
return 1.0f;
}
const float receiverDepth = shadowNdc.z - gShadowBiasAndTexelSize.x;
const float receiverDepth = shadowNdc.z - gShadowSampling.receiverDepthBias;
#endif
const float2 shadowTexelSize = gShadowBiasAndTexelSize.yz;
const float2 shadowTexelSize = gShadowMapMetrics.inverseMapSize;
float visibility = 0.0f;
[unroll]
for (int offsetY = -1; offsetY <= 1; ++offsetY) {
@@ -309,7 +325,7 @@ Shader "XC Character Toon"
}
visibility *= (1.0f / 9.0f);
const float shadowStrength = saturate(gShadowBiasAndTexelSize.w);
const float shadowStrength = saturate(gShadowSampling.shadowStrength);
return lerp(1.0f - shadowStrength, 1.0f, visibility);
#endif
}