// 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.
/// <summary>
/// Various helper functions to perform blending.
/// </summary>
shader BlendUtils
{
    // Performs an overlay operation between the two colors.
    float4 Overlay(float4 col1, float4 col2)
    {
        // http://en.wikipedia.org/wiki/Blend_modes#Overlay
        // if a < 0.5f: 2ab
        // if a >= 0.5f: 1 - 2(1 - a)(1 - b)
        return lerp(2.0f * col1 * col2,
                    1.0f - 2.0f * (1.0f - col1) * (1.0f - col2),
                    step(col2, 0.5));
    }
    
    // Performs a blend operation between the three colors (RGB only).
    float3 BasicColorBlend(float4 backColor, float4 frontColor, float3 interColor)
    {
        return frontColor.a * backColor.a * interColor + frontColor.a*(1.0f-backColor.a) * frontColor.rgb + (1.0f-frontColor.a)*backColor.a * backColor.rgb;
    }

    // Performs a blend operation between the two alpha values.
    float BasicAlphaBlend(float ba, float fa)
    {
        return lerp(fa, 1.0f, ba);
    }

    // Performs a blend operation between the three colors.
    float4 BasicBlend(float4 backColor, float4 frontColor, float3 interColor)
    {
        return float4(frontColor.a * backColor.a * interColor + frontColor.a*(1.0f-backColor.a) * frontColor.rgb + (1.0f-frontColor.a)*backColor.a * backColor.rgb,
                      lerp(frontColor.a, 1.0f, backColor.a));
    }

    // Performs a divide operation between the three colors (RGB only).
    float3 ColorDivide(float3 t1, float3 t2)
    {
        // http://msdn.microsoft.com/en-us/library/windows/desktop/hh706313(v=vs.85).aspx
        // Division
        //    "0/0"    : 0
        //    "t1/0"    : 1
        //    "t1/t2"    : t1/t2

        /*return lerp(t1 / t2,
                    1.0 - Equals(t1, 0.0f),
                    Equals(t2, 0.0f));*/
        return lerp(t1 / t2,
                    1.0 - step(t1, 0.0f),
                    step(t2, 0.0f));
        /*return lerp(t1 / t2,
                    1.0 - step(abs(t1), 0.0f),
                    step(abs(t2), 0.0f));*/
    }

    // Compare each channel of the colors.
    float3 Equals(float3 t1, float3 t2)
    {
        return step(abs(t1 - t2), 0);
    }
};
