/*
 * Independent Overworld lighting controls.
 *
 * EXPOSURE_MULTIPLIER has been intentionally removed. Scene exposure is now
 * fixed in final.fsh, while day/twilight/night/cave/block lighting are
 * controlled at the light contribution level.
 */
#ifndef INDEPENDENT_LIGHTING_GLSL
#define INDEPENDENT_LIGHTING_GLSL

#define DAYLIGHT_MULTIPLIER 0.20 //[0.20 0.25 0.30 0.35 0.40 0.50 0.60 0.70 0.80 0.90 1.00 1.10 1.20 1.30]
#define TWILIGHT_MULTIPLIER 0.85 //[0.65 0.70 0.75 0.80 0.85 0.90 0.95 1.00 1.10 1.20]
#define NIGHT_LIGHT_MULTIPLIER 1.55 //[0.80 1.00 1.15 1.30 1.45 1.55 1.70 1.85 2.00]
// Direct/shadow-casting moonlight strength. Previously the night phase had no
// direct-light term at all, so terrain, entities, water, etc. never showed a
// moon-cast shadow at night, only flat ambient sky light.
#define NIGHT_DIRECT_MULTIPLIER 0.55 //[0.00 0.15 0.25 0.35 0.45 0.55 0.65 0.80 1.00 1.20]
#define CAVE_LIGHT_MULTIPLIER 1.65 //[0.80 1.00 1.15 1.30 1.45 1.65 1.85 2.10 2.40 2.80]
#define CAVE_AMBIENT_FLOOR 0.85 //[0.00 0.20 0.40 0.60 0.75 0.85 1.00 1.25 1.50 2.00]
#define BLOCK_LIGHT_MULTIPLIER 1.35 //[0.75 0.90 1.00 1.10 1.20 1.35 1.50 1.70 2.00]
#define LIGHTMAP_FLOOR 0.0175

float getDayWeight(float sunElevationValue) {
    return smoothstep(0.22, 0.62, sunElevationValue);
}

float getNightWeight(float sunElevationValue) {
    return 1.0 - smoothstep(-0.12, 0.10, sunElevationValue);
}

float getTwilightWeight(float sunElevationValue) {
    float dayWeight = getDayWeight(sunElevationValue);
    float nightWeight = getNightWeight(sunElevationValue);
    return clamp(1.0 - dayWeight - nightWeight, 0.0, 1.0);
}

float getSkyLightPhaseMultiplier(float sunElevationValue) {
    float dayWeight = getDayWeight(sunElevationValue);
    float twilightWeight = getTwilightWeight(sunElevationValue);
    float nightWeight = getNightWeight(sunElevationValue);

    return dayWeight * DAYLIGHT_MULTIPLIER
         + twilightWeight * TWILIGHT_MULTIPLIER
         + nightWeight * NIGHT_LIGHT_MULTIPLIER;
}

float getSunDirectMultiplier(float sunElevationValue) {
    float dayWeight = getDayWeight(sunElevationValue);
    float twilightWeight = getTwilightWeight(sunElevationValue);
    float nightWeight = getNightWeight(sunElevationValue);
    return dayWeight * DAYLIGHT_MULTIPLIER
         + twilightWeight * TWILIGHT_MULTIPLIER
         + nightWeight * NIGHT_DIRECT_MULTIPLIER;
}

vec3 getIndependentLightmap(
    sampler2D lightmapTex,
    vec2 lightmapUV,
    vec2 screenTexelSize,
    float skyLevel,
    float sunElevationValue,
    float caveMask
) {
    // Read the lightmap axes independently. The previous implementation
    // recovered these values into colortex2 and multiplied the final image by
    // a mask. That made bright pixels turn white and made edges shimmer.
    // Here the sky and block components are added separately instead.
    vec3 floorLight = vec3(LIGHTMAP_FLOOR);

    vec2 skyOnlyUV = vec2(0.5 * screenTexelSize.x, lightmapUV.y);
    vec2 blockOnlyUV = vec2(lightmapUV.x, 0.5 * screenTexelSize.y);

    vec3 skyOnly = max(texture2D(lightmapTex, skyOnlyUV).rgb - floorLight, vec3(0.0));
    vec3 blockOnly = max(texture2D(lightmapTex, blockOnlyUV).rgb - floorLight, vec3(0.0));

    float skyMultiplier = getSkyLightPhaseMultiplier(sunElevationValue);
    float caveMultiplier = mix(1.0, CAVE_LIGHT_MULTIPLIER, caveMask);

    // A small independent ambient floor keeps caves from collapsing to pure
    // black without raising outdoor daytime exposure.
    vec3 caveAmbient = vec3(0.12, 0.15, 0.20) * CAVE_AMBIENT_FLOOR * caveMask;

    return skyOnly * skyMultiplier * caveMultiplier
         + blockOnly * BLOCK_LIGHT_MULTIPLIER
         + floorLight
         + caveAmbient;
}

#endif
