#ifndef FLOOR_VISIBILITY_INCLUDED
#define FLOOR_VISIBILITY_INCLUDED

void FloorVisibility_float(
    float3 WorldPosition,
    float VisibilityOriginY,
    float UpperThreshold,
    float UpperMax,
    float LowerThreshold,
    float LowerMin,
    float3 LowerTintColor,
    out float AlphaMultiplier,
    out float3 TintMultiplier)
{
    float relativeY = WorldPosition.y - VisibilityOriginY;

    // ------------------------------------------------------------
    // Alpha superior
    // ------------------------------------------------------------
    // relativeY <= UpperThreshold => alpha 1
    // relativeY >= UpperMax       => alpha 0

    float upperRange = max(UpperMax - UpperThreshold, 0.0001);
    float upperT = saturate((relativeY - UpperThreshold) / upperRange);
    // Smoothstep manual.
    upperT = upperT * upperT * (3.0 - 2.0 * upperT);

    float alphaMultiplier = 1.0 - upperT;

    // ------------------------------------------------------------
    // Tint inferior
    // ------------------------------------------------------------
    // LowerThreshold e LowerMin devem ser negativos.
    //
    // relativeY >= LowerThreshold => sem tint
    // relativeY <= LowerMin       => tint máximo

    float lowerRange = max(LowerThreshold - LowerMin, 0.0001);
    float lowerT = saturate((LowerThreshold - relativeY) / lowerRange);

    // Smoothstep manual.
    lowerT = lowerT * lowerT * (3.0 - 2.0 * lowerT);

    float3 tintMultiplier = lerp(
        float3(1.0, 1.0, 1.0),
        LowerTintColor,
        lowerT
    );

    AlphaMultiplier = alphaMultiplier;
    TintMultiplier = tintMultiplier;
}

void FloorVisibility_half(
    half3 WorldPosition,
    half VisibilityOriginY,
    half UpperThreshold,
    half UpperMax,
    half LowerThreshold,
    half LowerMin,
    half3 LowerTintColor,
    out half AlphaMultiplier,
    out half3 TintMultiplier)
{
    half relativeY = WorldPosition.y - VisibilityOriginY;

    half upperRange = max(UpperMax - UpperThreshold, 0.0001h);
    half upperT = saturate((relativeY - UpperThreshold) / upperRange);
    upperT = upperT * upperT * (3.0h - 2.0h * upperT);

    half alphaMultiplier = 1.0h - upperT;

    half lowerRange = max(LowerThreshold - LowerMin, 0.0001h);
    half lowerT = saturate((LowerThreshold - relativeY) / lowerRange);
    lowerT = lowerT * lowerT * (3.0h - 2.0h * lowerT);

    half3 tintMultiplier = lerp(
        half3(1.0h, 1.0h, 1.0h),
        LowerTintColor,
        lowerT
    );

    AlphaMultiplier = alphaMultiplier;
    TintMultiplier = tintMultiplier;
}

#endif