/////////////////////////////////////
// Complementary Shaders by EminGT //
/////////////////////////////////////

//Common//
#include "/lib/common.glsl"

//////////Fragment Shader//////////Fragment Shader//////////Fragment Shader//////////
#ifdef FRAGMENT_SHADER

flat in vec3 upVec, sunVec;

flat in vec4 glColor;

#ifdef OVERWORLD
    flat in float vanillaStars;
#endif

//Pipeline Constants//

//Common Variables//
float SdotU = dot(sunVec, upVec);
float sunFactor = SdotU < 0.0 ? clamp(SdotU + 0.375, 0.0, 0.75) / 0.75 : clamp(SdotU + 0.03125, 0.0, 0.0625) / 0.0625;
float sunVisibility = clamp(SdotU + 0.0625, 0.0, 0.125) / 0.125;
float sunVisibility2 = sunVisibility * sunVisibility;
float shadowTimeVar1 = abs(sunVisibility - 0.5) * 2.0;
float shadowTimeVar2 = shadowTimeVar1 * shadowTimeVar1;
float shadowTime = shadowTimeVar2 * shadowTimeVar2;

//Common Functions//

//Includes//
#include "/lib/util/dither.glsl"

#ifdef OVERWORLD
    #include "/lib/atmospherics/sky.glsl"
    #include "/lib/atmospherics/stars.glsl"
#endif

#ifdef CAVE_FOG
    #include "/lib/atmospherics/fog/caveFactor.glsl"
#endif

#ifdef ATM_COLOR_MULTS
    #include "/lib/colors/colorMultipliers.glsl"
#endif
#ifdef MOON_PHASE_INF_ATMOSPHERE
    #include "/lib/colors/moonPhaseInfluence.glsl"
#endif

#ifdef COLOR_CODED_PROGRAMS
    #include "/lib/misc/colorCodedPrograms.glsl"
#endif

#if SUN_MOON_STYLE >= 2
    #include "/lib/util/spaceConversion.glsl"
#endif

//Program//
void main() {
    vec4 color = vec4(glColor.rgb, 1.0);

    #ifdef OVERWORLD
    if (vanillaStars < 0.5) {
        vec4 screenPos = vec4(gl_FragCoord.xy / vec2(viewWidth, viewHeight), gl_FragCoord.z, 1.0);
        vec4 viewPos = gbufferProjectionInverse * (screenPos * 2.0 - 1.0);
        viewPos /= viewPos.w;
        vec3 nViewPos = normalize(viewPos.xyz);

        vec3 earthVec = vec3(0.5, 0.5, 0.5);

        float VdotU = dot(nViewPos, upVec);
        float VdotS = dot(nViewPos, sunVec);
        float VdotE = dot(nViewPos, earthVec);
        float dither = Bayer8(gl_FragCoord.xy);

        color.rgb = GetSky(VdotU, VdotS, dither, true, false);

        #ifdef ATM_COLOR_MULTS
            color.rgb *= GetAtmColorMult();
        #endif
        #ifdef MOON_PHASE_INF_ATMOSPHERE
            color.rgb *= moonPhaseInfluence;
        #endif

        vec2 starCoord = GetStarCoord(viewPos.xyz, 0.5);
        color.rgb += GetStars(starCoord, VdotU, VdotS);

        #if SUN_MOON_STYLE >= 2
            float absVdotS = abs(VdotS);
            float absVdotE = abs(VdotE);
            #if SUN_MOON_STYLE == 2
                float sunSizeFactor1 = 0.9975;
                float sunSizeFactor2 = 400.0;
            #else
                float sunSizeFactor1 = 0.9983;
                float sunSizeFactor2 = 588.235;
            #endif
            if (absVdotS > sunSizeFactor1) {
                float sunMoonMixer = sqrt1(sunSizeFactor2 * (absVdotS - sunSizeFactor1));

                #ifdef SUN_MOON_DURING_RAIN
                    sunMoonMixer *= 1.0 - 0.4 * rainFactor2;
                #else
                    sunMoonMixer *= 1.0 - rainFactor2;
                #endif

                if (VdotS > 0.0) {
                    sunMoonMixer = pow2(sunMoonMixer) * GetHorizonFactor(SdotU);

                    #ifdef CAVE_FOG
                        sunMoonMixer *= 1.0 - 0.65 * GetCaveFactor();
                    #endif

                    // color= texture2D(colortex8, viewPos.xy/4.0);
                    // color= vec4(viewPos.xy, 0.0, 1.0f);
                    color.rgb = mix(color.rgb, vec3(0.8, 0.8, 0.8) * 5.0, sunMoonMixer);
                }
            }

        #endif
    } else discard;
    #endif

    color.rgb *= 1.0 - maxBlindnessDarkness;

    #ifdef COLOR_CODED_PROGRAMS
        ColorCodeProgram(color, -1);
    #endif

    /* DRAWBUFFERS:0 */
    gl_FragData[0] = color;
}

#endif

//////////Vertex Shader//////////Vertex Shader//////////Vertex Shader//////////
#ifdef VERTEX_SHADER

flat out vec3 upVec, sunVec;

flat out vec4 glColor;

#ifdef OVERWORLD
    flat out float vanillaStars;
#endif

//Attributes//

//Common Variables//

//Common Functions//

//Includes//

//Program//
void main() {
    gl_Position = ftransform();

    glColor = gl_Color;

    upVec = normalize(gbufferModelView[1].xyz);
    sunVec = GetSunVector();

    #ifdef OVERWORLD
        //Vanilla Star Dedection by Builderb0y
        vanillaStars = float(glColor.r == glColor.g && glColor.g == glColor.b && glColor.r > 0.0 && glColor.r < 0.51);
    #endif
}

#endif
