#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
