#ifndef OVERWORLD

vec3 calcAmbientLight(vec3 wNormal, vec2 lightmap, vec3 ambientUp, vec3 ambientDown, vec3 ambientRight,
                      vec3 ambientLeft, vec3 ambientB, vec3 ambientF, vec3 RSML, float diffuseSun, vec3 torch)
{
    vec3 ambientCoefs = wNormal / dot(abs(wNormal), vec3(1.0));
    vec3 clampedCoefs = clamp(ambientCoefs, 0.0, 1.0);
    vec3 clampedCoefsNeg = clamp(-ambientCoefs, 0.0, 1.0);
    float mixstrength = clamp(pow(shadowblend, 0.3), 0, 1);
    float skymap = 1.0;
    vec3 sunLight = ambientUp;
    vec3 bounce = (sunLight * 0.25);

    bounce += mix(sunLight * 0.15 * clamp(diffuseSun, 0.5, 1), vec3(0.0), clamp(mixstrength * 1.0, 0, 1));
    bounce *= pow(skymap, 4.0);
    ambientRight = mix(ambientDown, ambientRight, mixstrength);
    ambientLeft = mix(ambientDown, ambientLeft, mixstrength);

    vec3 ambientCombined =
        (ambientUp * clampedCoefs.y + ambientDown * clampedCoefsNeg.y + ambientRight * clampedCoefs.x +
         ambientLeft * clampedCoefsNeg.x + ambientB * clampedCoefs.z + ambientF * clampedCoefsNeg.z) *
            pow(skymap, 2.0) +
        RSML;

    ambientCombined = mix(ambientCombined, bounce, 0.1);

    vec3 diffuseLight = diffuseSun * sunLight + ambientCombined;

    float darknessFactor = darknessLightFactor * darknessLightFactor * darknessLightFactor;

    diffuseLight *= (1.0 - 6.0 * darknessFactor);

    vec3 light = max(diffuseLight + torch * hdrMulttorch + (vec3(0.002, 0.005, 0.006) * (1.0 + screenBrightness * MIN_LIGHT_BOOST)), 0.001);

    light *= 1.0 - darknessLightFactor;

    return vec3(light);
}
#else
vec3 calcAmbientLight(vec3 wNormal, vec2 lightmap, vec3 ambientUp, vec3 ambientDown, vec3 ambientRight,
                      vec3 ambientLeft, vec3 ambientB, vec3 ambientF, vec3 RSML, float diffuseSun, vec3 torch)
{
    // Precompute sums and inverses to reduce divisions
    float sumAbsWNormal = abs(wNormal.x) + abs(wNormal.y) + abs(wNormal.z);
    float invSumAbsWNormal = 1.0 / sumAbsWNormal;
    vec3 ambientCoefs = wNormal * invSumAbsWNormal;

    // Compute clamped coefficients
    vec3 clampedCoefs = max(ambientCoefs, 0.0);
    vec3 clampedCoefsNeg = max(-ambientCoefs, 0.0);

    float mixstrength = clamp(pow(shadowblend, 0.3), 0.0, 1.0);

    // Extract skymap value and precompute powers
    float skymap = lightmap.y;
    float skymap2 = skymap * skymap;
    float skymap4 = skymap2 * skymap2;

    // Precompute factors to minimize operations
    float oneMinusMixStrength = 1.0 - mixstrength;
    float diffuseSunClamped = clamp(diffuseSun, 0.5, 1.0);

    // Compute bounce lighting
    float bounceFactor = 0.25 + 0.15 * diffuseSunClamped * oneMinusMixStrength;
    vec3 bounce = sunLight * bounceFactor * skymap4;

    // Adjust ambient sides based on mixstrength
    ambientRight = ambientDown * oneMinusMixStrength + ambientRight * mixstrength;
    ambientLeft = ambientDown * oneMinusMixStrength + ambientLeft * mixstrength;

    // Combine ambient light components
    vec3 ambientCombined = (
        ambientUp * clampedCoefs.y +
        ambientDown * clampedCoefsNeg.y +
        ambientRight * clampedCoefs.x +
        ambientLeft * clampedCoefsNeg.x +
        ambientB * clampedCoefs.z +
        ambientF * clampedCoefsNeg.z
    ) * skymap2 + RSML;

    // Mix ambientCombined with bounce lighting
    ambientCombined = ambientCombined * 0.9 + bounce * 0.1;

    // Calculate diffuse lighting
    vec3 diffuseLight = diffuseSun * sunLight + ambientCombined;

    // Compute darkness factors
    float darknessFactor = darknessLightFactor * darknessLightFactor * darknessLightFactor;
    float oneMinus6DarknessFactor = 1.0 - 6.0 * darknessFactor;
    diffuseLight *= oneMinus6DarknessFactor;

    // Prepare torch and small light contributions
    vec3 torchContribution = torch * hdrMulttorch;
    float screenBrightnessTerm = 1.0 + screenBrightness * MIN_LIGHT_BOOST;
    vec3 smallLightContribution = vec3(0.002, 0.005, 0.006) * screenBrightnessTerm;

    // Sum up the light components and apply final adjustments
    vec3 light = max(diffuseLight + torchContribution + smallLightContribution, 0.001);
    light *= 1.0 - darknessLightFactor;

    return light;
}

#endif

vec3 calcAmbientLight(vec3 Normal, vec2 lightmap, vec3 ambientUp, float diffuseSun, vec3 torch)
{

    vec3 ambient = calcAmbientLight(Normal, lightmap.xy, ambientUp, ambientUp, ambientUp, ambientUp, ambientUp,
                                    ambientUp, vec3(0.6 * ambientUp.b * lightmap.y), diffuseSun, torch);

    return ambient;
}