// 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 ComputeColorSoftLight : ComputeColor
{
    compose ComputeColor color1;
    compose ComputeColor color2;

    override float4 Compute()
    {
        float4 backColor = color1.Compute();
        float4 frontColor = color2.Compute();

        // From http://msdn.microsoft.com/en-us/library/windows/desktop/hh706313(v=vs.85).aspx
        //
        //  b = background, f = foreground, c = color, a = alpha, r = result color obtained with the specific blend formula
        //
        //  SoftLight:
        //      if fc < 0.5         : r = bc(1 + (1 - bc)(2fc - 1))
        //      else if bc < 9/64   : r = bc(bc(9 - 18fc) + 5.76fc - 1.88)
        //      else                : r = bc + (sqrt(bc) - bc)(2fc - 1)
        //
        //      color = (fa * ba) * r + (fa * (1-ba)) * fc + ((1-fa) * ba) * bc
        //      alpha = fa * (1-ba) + ba

        float3 r1 = backColor.rgb * (1.0f + (1.0f - backColor.rgb) * (2.0f * backColor.rgb -1.0f));
        float3 r2 = backColor.rgb * (backColor.rgb * (9.0f - 18.0f * frontColor.rgb) + 5.76f *frontColor.rgb -1.88f);
        float3 r3 = backColor.rgb + (sqrt(backColor.rgb) - backColor.rgb) * (2.0f * frontColor.rgb - 1.0f);

        float interColor = lerp( r1,
                                 lerp(r2,
                                      r3,
                                     step(9.0f / 64.0f, backColor.rgb)),
                                 step(0.5f, frontColor.rgb));

        return BlendUtils.BasicBlend(backColor, frontColor, interColor);
    }
};
