// 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.Images
{
    /// <summary>
    /// Makes front-objects transparent for the back out-of-focus area.
    /// </summary>
    shader ThresholdAlphaCoC: ImageEffectShader
    {
        // Previous CoC value (lower level)
        float CoCReference;

        // Current CoC value
        float CoCCurrent;

        // the epsilon is 0.5% of the -1;1 range of the CoC, which is enough to fix the problem of largely foreground objects getting selected as background.
        static const float CoCCompareEpsilon = 0.01;

        stage override float4 Shading()
        {
            float4 color = Texture0.Sample(Sampler, streams.TexCoord).rgba;

            float4 result = color;

            float minCoC = Texture1.Sample(Sampler, streams.TexCoord).x;

            // To sample multiple neighbors
            /*
            float neighborCoC[5];

            neighborCoC[0] =  Texture1.Sample(Sampler, streams.TexCoord).x;
            neighborCoC[1] =  Texture1.Sample(Sampler, streams.TexCoord + Texture0TexelSize * float2(0, 1)).x;
            neighborCoC[2] =  Texture1.Sample(Sampler, streams.TexCoord + Texture0TexelSize * float2(0, -1)).x;
            neighborCoC[3] =  Texture1.Sample(Sampler, streams.TexCoord + Texture0TexelSize * float2(1,0)).x;
            neighborCoC[4] =  Texture1.Sample(Sampler, streams.TexCoord + Texture0TexelSize * float2(-1, 0)).x;

            float minCoC = 1;
            [unroll]
            for (int i = 0; i < 5; i++)
            {
                minCoC = min(minCoC, neighborCoC[i]);
            }
            */

            // Front-objects are made transparent. & use an epsilon to give slack to the compare operator
            if (minCoC < CoCReference + CoCCompareEpsilon)
            {

                if (CoCReference > 0)
                {
                    // Keep a "ghost" of the bleeding front object.
                    // The closest to our level, the more visible.
                    result.a = saturate ( lerp(0, 1, minCoC / CoCReference) );
                }
                else
                {
                    result.a = 0.0;
                }
            }

            return result;
        }
    };
}
