#ifndef INCLUDE_SHADOW_MAINLIT #define INCLUDE_SHADOW_MAINLIT #include "include/shadow_common.hlsli" Texture2D gShadowMap : register(t8); SamplerComparisonState gShadowSampler : register(s2); float CalculateMainLightShadow(float4 shadowPosition,float3 worldNormal) { // 默认完全受光。 float shadowVisibility = 1.0f; // 只处理位于光源相机前方的像素。 if (shadowPosition.w > 0.0f) { float3 projected = shadowPosition.xyz / shadowPosition.w; float2 shadowUV = projected.xy * float2(0.5f, -0.5f) + 0.5f; float currentDepth = projected.z; bool insideShadowMap = all(shadowUV >= 0.0f) && all(shadowUV <= 1.0f) && currentDepth > 0.0f && currentDepth < 1.0f; if (insideShadowMap) { // cbMainLightDirection 是光线传播方向, // 因此表面指向光源的方向需要取反。 float3 lightToSurface = normalize(-cbMainLightDirection.xyz); float normalDotLight = saturate(dot(normalize(worldNormal), lightToSurface)); float bias = max(cbShadowParams.z, cbShadowParams.w * (1.0f - normalDotLight)); float shadowSum = 0.0f; [unroll] for (int y = -1; y <= 1; ++y) { [unroll] for (int x = -1; x <= 1; ++x) { float2 offset = float2((float)x, (float)y) * cbShadowParams.xy; shadowSum += gShadowMap.SampleCmpLevelZero(gShadowSampler, shadowUV + offset, currentDepth - bias); } } shadowVisibility = shadowSum / 9.0f; } } return shadowVisibility; } #endif //INCLUDE_SHADOW_MAINLIT