#ifndef VOXY_TERRAIN
flat out vec3 SUN_DIRECT;
flat out vec3 SUN_AMBIENT;
flat out vec3 SKY_TOP;
flat out vec3 SKY_GROUND;
#else
vec3 SUN_DIRECT;
vec3 SUN_AMBIENT;
vec3 SKY_TOP;
vec3 SKY_GROUND;
#endif


void get_sky_color() {

    // Precomputed sky colors
    const vec3 SKY_TOP_NOON = to_linear(vec3(f_NOON_SKY_T_R, f_NOON_SKY_T_G, f_NOON_SKY_T_B));
    const vec3 SKY_TOP_SUNRISE = to_linear(vec3(f_SUNRISE_SKY_T_R, f_SUNRISE_SKY_T_G, f_SUNRISE_SKY_T_B));
    const vec3 SKY_TOP_SUNSET = to_linear(vec3(f_SUNSET_SKY_T_R, f_SUNSET_SKY_T_G, f_SUNSET_SKY_T_B));
    const vec3 SKY_TOP_NIGHT = to_linear(vec3(f_NIGHT_SKY_T_R, f_NIGHT_SKY_T_G, f_NIGHT_SKY_T_B));

    const vec3 SKY_GROUND_NOON = to_linear(vec3(f_NOON_SKY_G_R, f_NOON_SKY_G_G, f_NOON_SKY_G_B));
    const vec3 SKY_GROUND_SUNRISE = to_linear(vec3(f_SUNRISE_SKY_G_R, f_SUNRISE_SKY_G_G, f_SUNRISE_SKY_G_B));
    const vec3 SKY_GROUND_SUNSET = to_linear(vec3(f_SUNSET_SKY_G_R, f_SUNSET_SKY_G_G, f_SUNSET_SKY_G_B));
    const vec3 SKY_GROUND_NIGHT = to_linear(vec3(f_NIGHT_SKY_G_R, f_NIGHT_SKY_G_G, f_NIGHT_SKY_G_B));

    SKY_TOP =
        SKY_TOP_SUNRISE * sunriseStrength +
        SKY_TOP_NOON * dayStrength +
        SKY_TOP_SUNSET * sunsetStrength +
        SKY_TOP_NIGHT * nightStrength;

    SKY_GROUND =
        SKY_GROUND_SUNRISE * sunriseStrength +
        SKY_GROUND_NOON * dayStrength +
        SKY_GROUND_SUNSET * sunsetStrength +
        SKY_GROUND_NIGHT * nightStrength;

    float DesatFactor = 1.0 - rainStrength * RAIN_SKY_DESATURATION;
    float DarkenFactor = 1.0 - rainStrength * RAIN_SKY_DARKENING;

#ifdef IS_IRIS
    float thunder = 1.0 - thunderStrength * 0.33;
    DesatFactor *= thunder;
    DarkenFactor *= thunder;
#endif

    SKY_TOP = mix_preserve_c1lum(SKY_TOP, to_linear(skyColor.rgb), f_BIOME_SKY_CONTRIBUTION);

    SKY_TOP = apply_saturation(SKY_TOP, DesatFactor) * DarkenFactor;
    SKY_GROUND *= DarkenFactor;
}



void get_sun_color() {

#ifdef DIMENSION_NETHER
    SUN_AMBIENT = to_linear(vec3(f_NETHER_AMBIENT_R, f_NETHER_AMBIENT_G, f_NETHER_AMBIENT_B));
    SUN_DIRECT = vec3(0.0);
    return;

#elif defined DIMENSION_END
    SUN_AMBIENT = to_linear(vec3(f_END_AMBIENT_R, f_END_AMBIENT_G, f_END_AMBIENT_B));
    SUN_DIRECT = to_linear(vec3(f_END_DIRECT_R, f_END_DIRECT_G, f_END_DIRECT_B));
    return;
#endif


    SUN_AMBIENT = vec3(
        f_SUNRISE_AMBIENT * sunriseStrength +
        f_NOON_AMBIENT * dayStrength +
        f_SUNSET_AMBIENT * sunsetStrength +
        f_NIGHT_AMBIENT * nightStrength
    );

    SUN_AMBIENT = to_linear(SUN_AMBIENT);


    float LHeight = sin(sunAngleAtHome * TAU);


    if (LHeight > 0.0) {

        const vec3 SUNRISE_SUN = to_linear(vec3(f_SUNRISE_RED, f_SUNRISE_GREEN, f_SUNRISE_BLUE));
        const vec3 NOON_SUN = to_linear(vec3(f_NOON_RED, f_NOON_GREEN, f_NOON_BLUE));
        const vec3 SUNSET_SUN = to_linear(vec3(f_SUNSET_RED, f_SUNSET_GREEN, f_SUNSET_BLUE));

        SUN_DIRECT =
            SUNRISE_SUN * sunriseStrength +
            NOON_SUN * dayStrength +
            SUNSET_SUN * sunsetStrength;

    } else {

        SUN_DIRECT = to_linear(vec3(f_MOON_RED, f_MOON_GREEN, f_MOON_BLUE));

        float MoonPhaseFactor =
            cos(float(worldDay % 8) * 0.785398) * (MOON_PHASE_INFLUENCE * 0.5)
            + (1.0 - MOON_PHASE_INFLUENCE * 0.5);

        SUN_DIRECT *= MoonPhaseFactor;
    }


    SUN_DIRECT *= smoothstep(0.0, 0.2, abs(LHeight));


    float DesatFactor = 1.0 - rainStrength * 0.5;
    float DarkenFactor = 1.0 - rainStrength * 0.5;

#ifdef IS_IRIS
    DesatFactor *= 1.0 - thunderStrength * 0.33;
    DarkenFactor *= 1.0 - thunderStrength * 0.5;
#endif

    SUN_DIRECT = apply_saturation(SUN_DIRECT, DesatFactor) * DarkenFactor;

#if defined(DYNAMIC_SHADOWS) && defined(DIMENSION_OVERWORLD)
    SUN_DIRECT *= 1.33;
#endif
}


void init_colors() {
    get_sky_color();
    get_sun_color();
}