#ifndef isReflectPass
    flat in vec3 colAtmosSunlight;
    flat in vec3 atmosSun;
    flat in vec3 colMoonlight;
    flat in vec3 colSkylight;
    flat in vec3 colSky;
    flat in vec3 colHorizon;
    flat in vec3 colSunglow;
    flat in vec3 colMoonglow;
#endif

float getHorizonFade(in float GRAD, const float low, const float high) {
    float horizonFade = linStep(GRAD, low, high+0.05);
    return pow8(horizonFade*0.89);
}
float getLowDome(in float GRAD, const float height) {
    float lowDome   = linStep(GRAD, height-0.02, height+0.02);
    return pow4(lowDome);
}
float getSunGlow(in float GRAD, const float low, const float high) {
    float sunGlow   = linStep(GRAD, low, high);
        sunGlow     = pow5(sunGlow*0.9);
        sunGlow    *= 0.8-timeNoon*0.5;
        sunGlow    *= (1.0-rainStrength*0.95);
    return sunGlow;
}
float getHorizonGlow(in float hGRAD, in float sGRAD, const float low, const float high) {
    float horizonGlow = saturateF(mix(pow3(sGRAD), pow2(sGRAD*1.1), timeNoon));
        horizonGlow = (linStep(hGRAD, low-horizonGlow*low, high-horizonGlow*0.05))*horizonGlow;
        horizonGlow = pow3(horizonGlow*1.2);
        horizonGlow = saturateF(horizonGlow*0.75);
        horizonGlow *= (1.0-rainStrength*0.85);
    return horizonGlow;
}
float getZenithDarken(in float GRAD, const float low, const float high) {
    float zenithFade = linStep(GRAD, low, high);
        zenithFade  = pow3(zenithFade*0.83)*1.5+1.0;
    return zenithFade;
}
vec3 getSunDisk(in float sunGrad, in float hBottom, in vec3 sunDiscCol) {
    float sunDisc   = linStep(sunGrad, 1.0-(setSunDiscRadius*0.02+0.001), 1.0-(setSunDiscRadius*0.02));
        sunDisc     = pow2(sunDisc);

    float sunLimb   = linStep(hBottom, 0.58, 0.70);
        sunLimb     = pow2(sunLimb);

    float sunLimb2   = 1.0-linStep(hBottom, 0.66, 0.71);
        sunLimb2     = pow2(sunLimb2);

    vec3 sunDiscColMod = mix(vec3(1.0), vec3(1.0, 0.0, 0.0), sunLimb)*sunLimb2;

    return sunDisc*sunDiscCol*sunDiscColMod*20.0*(1.0-rainStrength);
}

void skyGradient() {
    const float horizonLevel = 0.69;

    #ifndef isReflectPass
        vec3 nFrag      = -vec.view;
    #else
        vec3 nFrag      = -rvec.view;
    #endif

    vec3 hVec       = normalize(-vec.up+nFrag);
    vec3 hVec2      = normalize(vec.up+nFrag);
    vec3 sgVec      = normalize(vec.sun+nFrag);
    vec3 mgVec      = normalize(vec.moon+nFrag);

    float hTop      = dot(hVec, nFrag);
    float hBottom   = dot(hVec2, nFrag);

    float zenith    = dot(hVec2, nFrag);
    float sun       = 1.0-dot(sgVec, nFrag);
    float moon      = 1.0-dot(mgVec, nFrag);
    float horizon   = 1.0-max(hBottom, hTop);

    float sunHorizon  = getHorizonGlow(horizon, sun, 0.0, 0.32);

    float horizonFade   = getHorizonFade(hBottom, 0.1, horizonLevel-0.02);    //gradient for brighter sky towards horizon
    float lowDome       = getLowDome(hBottom, horizonLevel);
    float zenithFade    = getZenithDarken(zenith, 0.0, horizonLevel+0.02);

    float horizonLight  = linStep(horizon, 0.24, 0.296);                    //gradient for horizon sunlight scatter
        horizonLight    = pow4(horizonLight);

    float horizonGlow   = linStep(horizon, 0.16, 0.31);                    //gradient for additional horizon "glow"
        horizonGlow     = pow5(horizonGlow);

    float sunGlow       = getSunGlow(sun, 0.6, 0.98);

    float sunHorizonGlow  = pow2(sunHorizon);

    float moonGlow      = pow(moon*0.85, 15.0);
        moonGlow        = saturate(moonGlow*1.05)*0.8;

    float sunAlbedo     = smoothstep(sun, 0.85, 0.95)*(1.0-timeMoon);
    float moonAlbedo    = smoothstep(moon, 0.85, 0.95)*timeNight;

    vec3 sunColor       = atmosSun;
    vec3 moonColor      = vec3(0.5, 0.78, 1.0)*0.15;

    vec3 sunDiscCol     = sunAlbedo*(sunColor/2.2)*60.0*(1.0-timeMoon);
    vec3 albedoCol      = sunDiscCol*5.0 + moonAlbedo*normalize(moonColor)*5.0;

    #ifdef setSunDisc
        albedoCol      *= 1.0-linStep(sun, 0.78, 0.86);
    #endif

    float nightFix = (1.0-timeNight*0.9-timeMoon*0.1);

    vec3 sunScatterCol  = mix(colAtmosSunlight, colAtmosSunlight*colAtmosSunlight, 0.5)*2.0;
        sunScatterCol   = colorSat(sunScatterCol, 1.1);

    vec3 lowDomeColor   = colSky*0.7+(sunScatterCol*(0.07+horizonGlow*0.19)+colHorizon*0.12)*pow3(linStep(hTop, 0.0, 0.7))*nightFix*(1.0+timeNoon*0.8);
        lowDomeColor    += sunScatterCol*pow4(linStep(sun, 0.1, 1.0))*nightFix*timeSunHidden;
        lowDomeColor    += sunScatterCol*12.0*sunHorizon*nightFix*(1.0+timeNoon*0.6)*timeSunHidden;

    vec3 horizonColor   = normalize(sunColor)*vec3avg(colHorizon)*2.2*(normalize(colHorizon)*0.8+0.2);

    vec3 sky        = colSky*(1.0-timeNight*0.4-timeMoon*0.49)*zenithFade;
        sky         = mix(sky, colHorizon, horizonFade);
        sky         = mix(sky, (colHorizon/(colSky*0.5+0.5))*0.3, horizonGlow*(1.0-timeMoon));
        sky         = mix(sky, horizonColor, horizonLight*nightFix);
        sky         = mix(sky, sunScatterCol*10.0, saturate(sunGlow*0.16+sunHorizonGlow*0.2)*(1.0-timeNight));
        sky         = mix(sky, lowDomeColor, lowDome);

        sky   *= 6.6;

    #ifndef isReflectPass
        sky   += scene.albedo*albedoCol*2.0;
    #endif

    #ifdef setSunDisc
        sky   += getSunDisk(sun, hBottom, sunDiscCol);
    #endif


    #ifndef isReflectPass
        returnCol       = sky;
    #else
        ref.sky         = sky;
    #endif
    
    //returnCol       = vec3(horizon*30.0);

    horizonG         = saturate((horizonFade+horizonGlow));
}

float noise2Dstar(in vec2 coord) {
    coord /= 1024;
    return texture(noisetex, coord).x;
}
void skyStars() {
    #ifndef isReflectPass
        vec3 fragPos     = pos.screen;
        vec3 normFragpos = vec.view;
    #else
        vec3 fragPos     = rvec.view*1024;
        vec3 normFragpos = rvec.view;
    #endif

    vec3 wPos = vec3(gbufferModelViewInverse * vec4(fragPos,1.0));

    vec3 planeIntersect = wPos/(wPos.y+length(wPos.xz));
    float rotationValue = worldTime;
        rotationValue /= 24;
    vec2 rotate = vec2(rotationValue, -(pi/22)*rotationValue)*0.0018;
    vec2 coord = floor((planeIntersect.xz*0.4+pos.camera.xz*0.0001+rotate)*2048)/2048;
    vec2 coord2 = (planeIntersect.xz)*32+rotate*112;
        coord *= 1024.0;

	float NdotU = sqrt(sqrt(max(dot(normFragpos,normalize(vec.up)),0.0)));
	
    vec3 colorStar = vec3(0.5, 0.8, 1.0);
    vec3 colorStar2 = vec3(1.0, 0.4, 0.1);

	float star = 1.0;
		star *= noise2Dstar(coord.xy);
		//star *= noise2Dstar(coord.xy+0.1);
        //star *= noise2Dstar(coord.xy+0.23);

    float starVariation;
        starVariation = noise2Dstar(coord2.xy)-0.5;
        starVariation *= noise2Dstar(coord2.xy*0.77)*0.5+0.5;
        starVariation = clamp(starVariation, 0.0, 1.0);

	star = max(star-0.825,0.0)*5.0;
    star = clamp(star, 0.0, 1.0);

    colorStar = mix(colorStar, colorStar2, starVariation*2);
    colorStar = clamp(colorStar, 0.0, 1.0);

    #ifndef isReflectPass
        returnCol += colorStar*2.0*star*(timeNight*0.3+timeMoon*0.7);
    #else
        ref.sky   += colorStar*2.0*star*(timeNight*0.3+timeMoon*0.7);
    #endif
}