Files
2026-08-17 06:31:43 +09:00

59 lines
1.8 KiB
HLSL

#ifndef INCLUDE_SHADOW_MAINLIT
#define INCLUDE_SHADOW_MAINLIT
#include "include/shadow_common.hlsli"
Texture2D<float> 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