59 lines
1.8 KiB
HLSL
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
|