

vec3 blendTranslucencies(vec3 sceneColor, vec4 translucents)
{
    return (translucents.rgb * translucents.a) + (sceneColor.rgb * (1.0 - translucents.a));
}

float getFogDensity()
{
    // Convert ticks → hours (midnight = 0 h)
    float tod = mod((worldTime + 6000.0) / 1000.0, 24.0);

    // Envelope curves
    float dawn = mix(DAWN_DENSITY, DAY_DENSITY, smoothstep(DAWN_START, DAWN_END, tod));
    float dusk = mix(DAY_DENSITY, DUSK_DENSITY, smoothstep(DUSK_START, DUSK_END, tod));
    float nightA = mix(dusk, NIGHT_DENSITY, smoothstep(DUSK_END, NIGHT_START, tod));
    float nightB = mix(NIGHT_DENSITY, dawn, smoothstep(NIGHT_PEAK, NIGHT_END, tod));

    // Optional cosine bump
    float nTime = tod < 12.0 ? tod : tod - 24.0; // −12 h … +12 h
    float nightCos = NIGHT_DENSITY * cos(abs(nTime) * 3.14159265 / 6.0) * step(abs(nTime), 6.0);

    // Combine
    float fog = max(max(max(max(dawn, dusk), nightA), nightB), nightCos);
    fog = clamp(fog, 0.0, 1.0);

    // Weather
    return max(fog, mix(fog, 0.75, rainStrength));
}

float phaseg(float x, float g)
{
    float gg = g * g;
    return (gg * -0.25 + 0.25) * pow(-2.0 * (g * x) + (gg + 1.0), -1.5) / PI;
}

#include "/lib/sky_function.glsl"

float gbf(in vec3 eyePlayerPos, in float far, in float z0)
{

    float eyeDist = max(length(eyePlayerPos.xz), abs(eyePlayerPos.y));

#ifdef DISTANT_HORIZONS
    float borderFogFactor = smoothstep(dhRenderDistance * 0.75, dhRenderDistance - 8.0, eyeDist);
    return clamp(borderFogFactor, 0.0, 1.0);
#else
    float borderFogFactor = smoothstep(far * 0.6, far, eyeDist);
    return borderFogFactor * borderFogFactor;
#endif
}

float remap(const float originalValue, const float originalMin, const float originalMax, const float newMin, const float newMax)
{
    return newMin + (((originalValue - originalMin) / (originalMax - originalMin)) * (newMax - newMin));
}

#include "/lib/fog/fognoloop.glsl"

// Function to apply sky blending
void applySkyBlend(inout vec3 solid, inout vec4 translucent, vec3 sky, vec3 vL_w, vec3 p3, vec3 p30, float far, bool iswater)
{
#ifdef SKYBLEND
    if (isEyeInWater == 0)
    {
        float blend_factor1 = gbf(p3, far, 0.0);
        float blend_factor2 = gbf(p30, far, 0.0);
        if (iswater)
        {
            solid = mix(solid, sky, blend_factor1);
        }
        else
        {
            solid = mix(solid, sky, blend_factor2);
        }
        translucent.rgb = mix(translucent.rgb, sky, blend_factor1) * float(translucent.a > 0);
    }
    else
    {
        float blend_factor = gbf(p30, far, 0.0);
        if (!iswater)
        {

            //      sky = vL_w;
        }
        solid = mix(solid, sky, blend_factor);
    }

#endif
}
void applySkyBlend2(inout vec3 solid, vec3 sky, vec3 p3, float far)
{
#ifdef SKYBLEND

    float blend_factor = gbf(p3, far, 0.0);

    solid = mix(solid, sky, blend_factor);

#endif
}

void applyWaterEffects(
    inout vec3 solid,
    inout vec4 translucent,
    inout vec3 sky,
    vec3 vL_w,
    vec3 vL_a,
    vec3 absorbance_w,
    vec3 transmittance,
    vec3 fogColor,
    vec3 fragpos,
    vec3 p30,
    int isEyeInWater,
    bool iswater)
{
    if (isEyeInWater == 0)
    {
        if (iswater)
        {
            float blend_factor2 = gbf(p30, far, 0.0);
            solid = mix(solid * absorbance_w + vL_w, vL_w, blend_factor2);
        }
        translucent.rgb = translucent.rgb * transmittance + vL_a;
        solid = solid * transmittance + vL_a;
    }
    else if (isEyeInWater == 1)
    {
        solid = solid * absorbance_w + vL_w;
        sky = sky * absorbance_w + vL_w;
        translucent.rgb = translucent.rgb * absorbance_w + vL_w;
    }
    else if (isEyeInWater >= 2)
    {
        float fogFactor = exp(-length(fragpos));
        solid = solid * fogFactor + fogColor;
    }
}
