varying vec4 texcoord;
varying vec2 sunhide;
flat varying vec3 flareColor;

uniform sampler2D colortex6;

uniform sampler2D colortex15;
uniform sampler2D colortex8;
uniform mat4 gbufferProjection;

uniform sampler2D depthtex1;
uniform float frameTimeCounter;
uniform mat4 gbufferModelViewInverse;
uniform mat4 gbufferProjectionInverse;
uniform float far;
uniform vec3 cameraPosition;

#include "/lib/taa/res_params.glsl"
#include "/lib/uniforms.glsl"
#include "/lib/sky_gradient.glsl"
float phaseg(float x, float g)
{
    float gg = g * g;
    return (gg * -0.25 + 0.25) * pow(-2.0 * (g * x) + (gg + 1.0), -1.5) / PI;
}

vec3 toLinear(vec3 sRGB)
{
    return sRGB * (sRGB * (sRGB * 0.305306011 + 0.682171111) + 0.012522878);
}

float NoisyStarField(in vec2 vSamplePos, float fThreshold)
{
    float StarVal =
        fract(dot(fract(vec3(vSamplePos.xyx) * 0.1031) +
                      dot(fract(vec3(vSamplePos.xyx) * 0.1031), fract(vec3(vSamplePos.xyx) * 0.1031).yzx + 19.19),
                  vec3(1.0)));

    StarVal = max(0.0, pow((abs(StarVal) - fThreshold) / (1.0 - fThreshold), 6.0));
    return clamp(StarVal, 0, 1);
}

float StableStarField(in vec2 vSamplePos, float fThreshold)
{
    float fractX = fract(vSamplePos.x);
    float fractY = fract(vSamplePos.y);
    vec2 floorSample = floor(vSamplePos);

    float v1 = NoisyStarField(floorSample, fThreshold);
    float v2 = NoisyStarField(floorSample + vec2(0.0, 1.0), fThreshold);
    float v3 = NoisyStarField(floorSample + vec2(1.0, 0.0), fThreshold);
    float v4 = NoisyStarField(floorSample + vec2(1.0, 1.0), fThreshold);

    float StarVal = mix(mix(v1, v2, fractY), mix(v3, v4, fractY), fractX);
    return StarVal;
}

float starsog(vec3 fragpos)
{
    float elevation = clamp(fragpos.y, 0, 1);
    vec2 uv = fragpos.xz / (1 + elevation);

    return (1 - nightblend5) * 4 * StableStarField(uv * 700, 0.999) * (0.3 - 0.3 * rainStrength);
}

float stars(vec3 fragpos)
{
    float elevation = clamp(fragpos.y, 0, 1);
    vec2 uv = fragpos.xz / (1 + elevation);

    return (1 - nightblend5) * 4 * StableStarField(uv * 700, 0.999) * (0.3 - 0.3 * rainStrength);
}

vec3 toScreenSpace(vec3 position)
{
    position = position * 2.0 - 1.0;
    position.xy = vec2(gbufferProjectionInverse[0].x, gbufferProjectionInverse[1].y) * position.xy +
                  gbufferProjectionInverse[3].xy;
    return vec3(position.xy, gbufferProjectionInverse[3].z) /
           (gbufferProjectionInverse[2].w * position.z + gbufferProjectionInverse[3].w);
}

#include "/lib/clouds_bloop.glsl"

// https://software.intel.com/en-us/node/503873
vec3 RGB_YCoCg(vec3 c)
{
    // Y = R/4 + G/2 + B/4
    // Co = R/2 - B/2
    // Cg = -R/4 + G/2 - B/4
    return vec3(c.x / 4.0 + c.y / 2.0 + c.z / 4.0, c.x / 2.0 - c.z / 2.0, -c.x / 4.0 + c.y / 2.0 - c.z / 4.0);
}

float luma(vec3 color)
{
    return dot(color, vec3(0.299, 0.587, 0.114));
}
vec3 Dither_Vlachos(vec3 rgba, float levels)
{
    // Vlachos 2016, "Advanced VR Rendering"
    vec3 noise = vec3(dot(vec2(171.0, 231.0), gl_FragCoord.xy));
    noise = fract(noise / vec3(103.0, 71.0, 97.0));
    noise = noise - 0.5;
    return vec3(rgba.rgb + (noise / (levels - 1.0)));
}
void main()
{
    /* DRAWBUFFERS:8 */
    vec3 np3 = vec3(vec2(gbufferProjectionInverse[0].x, gbufferProjectionInverse[1].y) * (texcoord.xy * 2.0 - 1.0) +
                        gbufferProjectionInverse[3].xy,
                    1.0);
    np3 = vec3(np3.xy, gbufferProjectionInverse[3].z) / (gbufferProjectionInverse[2].w + gbufferProjectionInverse[3].w);
    np3 = mat3(gbufferModelViewInverse) * np3;
    np3 = normalize(np3);

    //  vec3 color = skyFromTex2((np3), colortex6).rgb + noise_standard(gl_FragCoord.xy) / 1024;
#ifdef OVERWORLD
    vec3 color = texture(colortex8, texcoord.xy).rgb;
    vec4 cloud = vec4(0, 0, 0, 0);
    float alpha = texture(colortex8, texcoord.xy).a;
    if (np3.y > 0.0)
    {

        float noise = noise_standard(gl_FragCoord.xy);
        cloud = renderClouds(noise, np3, vec3(0));
    }

    if (alpha < 1)
    {
        vec3 altcol = skyFromTex2((np3), colortex6).rgb;

        color = mix(altcol, color, clamp(cloud.a, 0, 1));
    }
    color += cloud.rgb;
#else
#ifdef END
    vec3 altcol = skyFromTex2((np3), colortex6).rgb;

    vec3 color = altcol;
    vec4 cloud = vec4(0, 0, 0, 0);

    if (np3.y > 0.0)
    {
        float noise = noise_standard(gl_FragCoord.xy);
        cloud = renderClouds(noise, np3, vec3(0)) ;
    }

    color += cloud.r;
#else
    vec3 color = skyFromTex2((np3), colortex6).rgb;

#endif
#endif
    color.rgb = Dither_Vlachos(color, 1024);

    gl_FragData[0].rgb = vec3(color);
}
