#define s_fogMieD 1.0 //[0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0 1.1 1.2 1.3 1.4 1.5 1.6 1.7 1.8 1.9 2.0 2.2 2.4 2.6 2.8 3.0 3.2 3.4 3.6 3.8 4.0 4.5 5.0 5.5 6.0 7.0 8.0]
#define s_fogRaylD 1.0 //[0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0 1.1 1.2 1.3 1.4 1.5 1.6 1.7 1.8 1.9 2.0 2.2 2.4 2.6 2.8 3.0 3.2 3.4 3.6 3.8 4.0]

#define setBiomeEffects

#define s_skyLuma 1.0          //[0.25 0.5 0.75 1.0 1.25 1.5 1.75 2.0 2.2 2.4 2.6 2.8 3.0 3.2 3.4 3.6 3.8 4.0]
#define s_skyR 1.0         //[0.25 0.5 0.75 1.0 1.25 1.5 1.75 2.0]
#define s_skyG 1.0         //[0.25 0.5 0.75 1.0 1.25 1.5 1.75 2.0]
#define s_skyB 1.0        //[0.25 0.5 0.75 1.0 1.25 1.5 1.75 2.0]

#define s_torchlightTemp 2200.0 //[1200.0 1400.0 1600.0 1800.0 2000.0 2200.0 2400.0 2600.0 2800.0 3000.0 3400.0 3600.0 4000.0 4400.0 4800.0 5200.0 5600.0 6000.0 6400.0]
#define s_torchlightLuma 1.0    //[0.25 0.5 0.75 1.0 1.25 1.5 1.75 2.0 2.2 2.4 2.6 2.8 3.0 3.2 3.4 3.6 3.8 4.0]
#define s_sunlightTempMult 1.0  //[0.5 0.6 0.7 0.8 0.9 1.0 1.1 1.2 1.3 1.4 1.5]

uniform float biomeCold;
uniform float biomeHot;
uniform float biomeTropic;
uniform float biomeSnow;
uniform float biomeDesert;

#ifdef overcastOverride
    float wetness = manualOvercast;
    float rainStrength = manualOvercast;
#else
    uniform float wetness;
    uniform float rainStrength;
#endif

flat out float tempSunlight;

flat out vec3 colMoonlight;
flat out vec3 colSkylight;
flat out vec3 colSky;
flat out vec3 colHorizon;
flat out vec3 colSunglow;
flat out vec3 colMoonglow;

flat out vec3 colTorchlight;

flat out vec2 fogDensity;
flat out float fogHeight;

flat out float cloudCoverage;

struct colHorizionBiome {
    vec3 cold;
    vec3 hot;
    vec3 tropic;
    vec3 snow;
    vec3 desert;
} bcHor;

struct colSkyBiome {
    vec3 cold;
    vec3 hot;
    vec3 tropic;
    vec3 snow;
    vec3 desert;
} bcSky;

struct fogDensityBiome {
    float cold;
    float hot;
    float tropic;
    float snow;
    float desert;
} fogD;

struct fogHeightBiome {
    float cold;
    float hot;
    float tropic;
    float snow;
    float desert;
} fogH;

void nColor() {
    tempSunlight    = 2573.0*timeSunrise + 6022.0*timeNoon + 2324.0*timeSunset + 2005.0*timeNight;
    tempSunlight *= s_sunlightTempMult;

    vec3 skylightSunrise;
    skylightSunrise.r    = 0.62;
    skylightSunrise.g    = 0.68;
    skylightSunrise.b    = 1.00;
    skylightSunrise     *= 0.29;

    vec3 skylightNoon;
    skylightNoon.r       = 0.56;
    skylightNoon.g       = 0.85;
    skylightNoon.b       = 1.00;
    skylightNoon        *= 1.00;

    vec3 skylightSunset;
    skylightSunset.r     = 0.74;
    skylightSunset.g     = 0.71;
    skylightSunset.b     = 1.00;
    skylightSunset      *= 0.18;

    vec3 skylightNight;
    skylightNight.r      = 0.6;
    skylightNight.g      = 0.72;
    skylightNight.b      = 1.00;
    skylightNight       *= 0.026;

    vec3 skylightMoon;
    skylightMoon.r      = 0.08;
    skylightMoon.g      = 0.81;
    skylightMoon.b      = 1.00;
    skylightMoon       *= 0.008;

    colSkylight          = skylightSunrise*timeSunrise + skylightNoon*timeNoon + skylightSunset*timeSunset + skylightNight*timeNight;
    colSkylight          = mix(colSkylight, skylightMoon, timeMoon);

    vec3 skySunrise;
    skySunrise.r    = 0.54;
    skySunrise.g    = 0.76;
    skySunrise.b    = 1.0;
    skySunrise     *= 0.32;

    vec3 skyNoon;
    skyNoon.r       = 0.15;
    skyNoon.g       = 0.43;
    skyNoon.b       = 1.00;
    skyNoon        *= 0.82;

    vec3 skySunset;
    skySunset.r     = 0.48;
    skySunset.g     = 0.74;
    skySunset.b     = 1.00;
    skySunset      *= 0.38;

    vec3 skyNight;
    skyNight.r      = 0.14;
    skyNight.g      = 0.58;
    skyNight.b      = 1.00;
    skyNight       *= 0.008;

    colSky          = skySunrise*timeSunrise + skyNoon*timeNoon + skySunset*timeSunset + skyNight*timeNight;
    colSky         *= s_skyLuma*vec3(s_skyR, s_skyG, s_skyB);
    colSky          = mix(colSky, vec3(getLuma(colSky)), rainStrength*0.95);

    vec3 horSunrise;
    horSunrise.r    = 0.6;
    horSunrise.g    = 1.0;
    horSunrise.b    = 1.00;
    horSunrise     *= 2.70;

    vec3 horNoon;
    horNoon.r       = 0.29;
    horNoon.g       = 0.62;
    horNoon.b       = 1.00;
    horNoon        *= 8.00;

    vec3 horSunset;
    horSunset.r     = 0.54;
    horSunset.g     = 1.0;
    horSunset.b     = 1.00;
    horSunset      *= 2.90;

    vec3 horNight;
    horNight.r      = 0.10;
    horNight.g      = 0.68;
    horNight.b      = 1.00;
    horNight       *= 0.01;

    colHorizon      = horSunrise*timeSunrise + horNoon*timeNoon + horSunset*timeSunset + horNight*timeNight;

    #ifndef setBiomeEffects
        colHorizon      = mix(colHorizon, vec3(getLuma(colHorizon))*0.6, rainStrength*0.99);
    #endif

    #ifdef isLightingPass
        colTorchlight   = blackbody(s_torchlightTemp)*s_torchlightLuma;
    #endif

}

void nFog() {
    float noonMie           = 0.3;

#ifdef setBiomeEffects
    fogD.cold       = 0.55;
    fogD.hot        = 0.72;
    fogD.tropic     = 0.75;
    fogD.snow       = 0.6;
    fogD.desert     = 0.5;
        noonMie     = mix(noonMie, fogD.cold, biomeCold);
        noonMie     = mix(noonMie, fogD.hot, biomeHot);
        noonMie     = mix(noonMie, fogD.tropic, biomeTropic);
        noonMie     = mix(noonMie, fogD.snow, biomeSnow);
        noonMie     = mix(noonMie, fogD.desert, biomeDesert);
#endif

    const float mieBaseDensity = 1.0*s_fogMieD;

    float mieDensity        = timeSunrise*2.0+noonMie*timeNoon+timeSunset*0.6+timeNight*1.4;
        mieDensity          = mix(mieDensity, 4.0, wetness);

    fogDensity.x            = mieBaseDensity*mieDensity;

    float rayleighBaseDensity = (17.0+biomeCold*2.0)*s_fogRaylD;
    float rayleighDensity   = timeSunrise*0.6+1.0*timeNoon+timeSunset*0.6+timeNight*0.5;

    fogDensity.y            = rayleighBaseDensity*rayleighDensity+wetness*0.5;
}

void nBiomes() {
#ifdef setBiomeEffects
    bcHor.cold      = vec3(0.38, 0.71, 1.00)*7.30;
    bcHor.hot       = vec3(0.68, 0.98, 1.00)*7.95;
    bcHor.tropic    = vec3(0.36, 0.86, 1.00)*7.80;
    bcHor.snow      = vec3(0.42, 0.74, 1.00)*7.60;
    bcHor.desert    = vec3(0.68, 1.00, 1.00)*8.10;
    vec3 colHorizonMod = colHorizon;
        colHorizonMod   = mix(colHorizonMod, bcHor.cold, biomeCold);
        colHorizonMod   = mix(colHorizonMod, bcHor.hot, biomeHot);
        colHorizonMod   = mix(colHorizonMod, bcHor.tropic, biomeTropic);
        colHorizonMod   = mix(colHorizonMod, bcHor.snow, biomeSnow);
        colHorizonMod   = mix(colHorizonMod, bcHor.desert, biomeDesert);
    colHorizon  = mix(colHorizon, colHorizonMod, timeNoon);
    colHorizon  = mix(colHorizon, vec3(getLuma(colHorizon))*0.6, rainStrength*0.99);

    bcSky.cold      = vec3(1.1, 1.06, 1.00)*0.5;
    bcSky.hot       = vec3(1.20, 1.12, 1.00)*1.20;
    bcSky.tropic    = vec3(0.75, 1.10, 0.95)*1.40;
    bcSky.snow      = vec3(1.20, 1.00, 0.90)*0.7;
    bcSky.desert    = vec3(1.20, 1.14, 1.00)*1.30;
    vec3 colSkyMod  = vec3(1.00);
        colSkyMod   = mix(colSkyMod, bcSky.cold, biomeCold);
        colSkyMod   = mix(colSkyMod, bcSky.hot, biomeHot);
        colSkyMod   = mix(colSkyMod, bcSky.tropic, biomeTropic);
        colSkyMod   = mix(colSkyMod, bcSky.snow, biomeSnow);
        colSkyMod   = mix(colSkyMod, bcSky.desert, biomeDesert);
    colSky         *= colSkyMod;
#endif
}