// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
namespace Stride.Rendering.Shadows
{
    /// <summary>
    /// Performs default filtering: no filtering.
    /// </summary>
    shader ShadowMapFilterDefault<MemberName PerLighting> : ShadowMapFilterBase<PerLighting>
    {
        /// <summary>
        /// Calculate the shadow factor based on the shadow map texture, the position, a sampler
        /// </summary>
        float FilterShadow(float2 position, float positionDepth)
        {
            return ShadowMapTexture.SampleCmpLevelZero(LinearClampCompareLessEqualSampler, position, positionDepth);
        }
        
        float FilterThickness(float3 pixelPositionWS,
                              float3 meshNormalWS,
                              float2 depthRanges,
                              float4x4 worldToShadowCascadeUV,    // Transforms from world space to shadow cascade UV.
                              float4x4 inverseWorldToShadowCascadeUV,  // Transforms from shadow cascade UV to world space.
                              bool isOrthographic)
        {
            //const float filterRadiusInPixels = 1.0;    // 1 pixel filter radius
            const float filterRadiusInPixels = 1.5;    // 1.5 pixel filter radius

            float3 adjustedPixelPositionWS;
            float3 adjustedPixelPositionShadowSpace;

            if(isOrthographic)
            {
                CalculateAdjustedShadowSpacePixelPosition(filterRadiusInPixels, pixelPositionWS, meshNormalWS, worldToShadowCascadeUV, inverseWorldToShadowCascadeUV,
                                                          adjustedPixelPositionWS, adjustedPixelPositionShadowSpace);
            }
            else
            {
                CalculateAdjustedShadowSpacePixelPositionPerspective(filterRadiusInPixels, pixelPositionWS, meshNormalWS, worldToShadowCascadeUV, inverseWorldToShadowCascadeUV,
                                                                     adjustedPixelPositionWS, adjustedPixelPositionShadowSpace);
            }

            return SampleThickness(adjustedPixelPositionShadowSpace, adjustedPixelPositionWS, depthRanges, inverseWorldToShadowCascadeUV, isOrthographic);
        }
    };
}
