// 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.

shader SignedDistanceFieldFont : Texturing
{

    // Gets the median of 3 values
    float median(float r, float g, float b)
    {
        return max(min(r, g), min(max(r, g), b));
    }

    // Retrieves the pixel's color sampled from a signed distance field font texture, with font color, border and shadows
    stage float4 FontColor(float4 sampledColor, float4 textColor, float4 borderColor, float borderThickness)
    {
        // -0.5 to +0.5 is the maximum distance msdfgen can produce, but it's blurry so cap the border at 0.25
        borderThickness = clamp(borderThickness, 0, 0.2);

        // Higher (more than 1) - sharper
        // Lower (less than 1, more than 0) - blurry
        float sharpnessMagnitude = 0.5f;
        float axisDistance = 0.4 - borderThickness;

        // Get the median distance encoded in the signed distance field
        float medianDistance = median(sampledColor.r, sampledColor.g, sampledColor.b);

        float sigDist = medianDistance - axisDistance;

        float transition = fwidth(sigDist) * 0.85;
        float opacity = smoothstep(-transition, transition, sigDist);
        opacity *= opacity;

        // Detect edge
        if (borderThickness > 0)
        {
            float farDistance = axisDistance + borderThickness * 2;
            float sigDistBorder = medianDistance - farDistance;
            float borderLine = sharpnessMagnitude * sigDistBorder/fwidth(sigDistBorder) + farDistance;            
            float borderOpacity = smoothstep(0, 1, borderLine);

            textColor = lerp(borderColor, textColor, borderOpacity);
        }

        sampledColor = lerp(float4(0,0,0,0), textColor, opacity);
        
        return sampledColor;
    }
};
