#version 400 compatibility

/*
====================================================================================================

    Copyright (C) 2020 RRe36

    All Rights Reserved unless otherwise explicitly stated.


    By downloading this you have agreed to the license and terms of use.
    These can be found inside the included license-file
    or here: https://rre36.com/copyright-license

    Violating these terms may be penalized with actions according to the Digital Millennium
    Copyright Act (DMCA), the Information Society Directive and/or similar laws
    depending on your country.

====================================================================================================
*/


#include "/lib/head.glsl"

/*DRAWBUFFERS:0*/
layout(location = 0) out vec4 sceneColor;

#include "/lib/util/colorspace.glsl"

in vec2 coord;

#ifndef airTransmittanceHQ
flat in vec3 sunColor;
#endif

uniform sampler2D colortex0;
uniform sampler2D colortex5;

uniform sampler2D depthtex0;

uniform sampler2D noisetex;

uniform sampler2D shadowtex0;
uniform sampler2D shadowtex1;
uniform sampler2D shadowcolor0;
uniform sampler2D shadowcolor1;

uniform int frameCounter;
uniform int worldTime;

uniform float far, near;

uniform vec2 skyCaptureResolution;
uniform vec2 taaOffset;
uniform vec2 pixelSize, viewSize;

//uniform vec3 cameraPosition;
uniform vec3 upvec, upvecView;
uniform vec3 sunvec, sunvecView;
uniform vec3 moonvec, moonvecView;
//uniform vec3 lightvec, lightvecView;

uniform vec4 daytime;

uniform mat4 gbufferModelView, gbufferModelViewInverse;
uniform mat4 gbufferProjection, gbufferProjectionInverse;

/* ------ includes ------*/
#define FUTIL_LINDEPTH
#define FUTIL_ROT2
#include "/lib/fUtil.glsl"
#include "/lib/util/encoders.glsl"

#include "/lib/util/transforms.glsl"
#include "/lib/atmos/air/const.glsl"
#include "/lib/atmos/project.glsl"
#include "/lib/util/bicubic.glsl"

vec3 sunDisk(vec3 viewDir) {
    vec3 v      = -viewDir;
    vec3 sv     = normalize(sunvecView + v);
    float sun   = dot(sv, v);

    const float size = 0.0055;
    float maxsize = size + 0.0004;
        maxsize  += linStep(sunvec.y, -0.04, 0.04)*0.004;

    float s   = 1.0-linStep(sun, size, maxsize);
        //s    *= 1.0-sstep(sun, 0.004, 0.0059)*0.5;

    float limb = 1.0 - cube(linStep(sun, 0.0, maxsize))*0.8;
        s    *= limb;

    #ifdef airTransmittanceHQ
        return s * sunIllum * 5e3;
    #else
        return s * sunColor * 5e3;
    #endif
}

vec3 moonTexture(vec3 viewDir, vec3 color) {
    vec3 v      = -viewDir;
    vec3 sv     = normalize(moonvecView + v);
    float moon  = dot(sv, v);

    float s   = 1.0-linStep(moon, 0.03, 0.08);

    return color * s * moonIllum * 6.0;
}

#include "/lib/frag/noise.glsl"

vec3 skyStars(vec3 worldDir) {
    vec3 plane  = worldDir/(worldDir.y+length(worldDir.xz)*0.66);
    float rot   = worldTime*rcp(2400.0);
    plane.x    += rot*0.6;
    plane.yz    = rotatePos(plane.yz, (25.0/180.0)*pi);
    vec2 uv1    = floor((plane.xz)*768)/768;
    vec2 uv2    = (plane.xz)*0.04;

    vec3 starcol = vec3(0.3, 0.78, 1.0);
        starcol  = mix(starcol, vec3(1.0, 0.7, 0.6), noise2D(uv2).x);
        starcol  = normalize(starcol)*(noise2D(uv2*1.5).x+1.0);

    float star  = 1.0;
        star   *= noise2D(uv1).x;
        star   *= noise2D(uv1+0.1).x;
        star   *= noise2D(uv1+0.26).x;

    star        = max(star-0.25, 0.0);
    star        = saturate(star*4.0);

    return star*starcol*0.25*sqrt(daytime.w);
}

void main() {
    sceneColor      = texture(colortex0, coord);
    sceneColor.rgb  = linearToAP1Albedo(sceneColor.rgb);

    float sceneDepth = texture(depthtex0, coord).x;

    if (!landMask(sceneDepth)) {
        vec3 viewPos    = screenToViewSpace(vec3(coord, sceneDepth));
        vec3 viewDir    = normalize(viewPos);
        vec3 scenePos   = viewToSceneSpace(viewPos);
        vec3 sceneDir   = normalize(scenePos);

        vec3 sunMoon    = sunDisk(viewDir) + moonTexture(viewDir, sceneColor.rgb) + skyStars(sceneDir);

        sceneColor.rgb  = textureBicubic(colortex5, projectSky(sceneDir)).rgb;

        #ifdef airTransmittanceHQ
            vec3 transmittance = textureBicubic(colortex5, projectSky(sceneDir) + vec2(0.0, exp2(-SKY_RENDER_LOD) + pixelSize.y)).rgb;
        #else
            float transmittance = cube(linStep(sceneDir.y, -0.02, 0.02));
        #endif

        #if (defined cloudVolumeEnabled || defined cloudCirrusEnabled)
            const float clod = sqrt(CLOUD_RENDER_LOD);
            vec2 cloudCoord = (coord)*rcp(clod)+vec2(1.0-rcp(clod), 0.0);

            vec4 clouds     = textureBicubic(colortex5, cloudCoord);

            sceneColor.rgb  = sceneColor.rgb * clouds.a + clouds.rgb;

            sceneColor.rgb += sunMoon * transmittance * mix(1.0, clouds.a, cubeSmooth(saturate((sceneDir.y - 0.05) * 14.0)));
        #else
            sceneColor.rgb += sunMoon * transmittance;
        #endif
        //sceneColor.rgb = vec3(cubeSmooth(saturate((sceneDir.y - 0.05) * 10.0))) * 2;
    }

    sceneColor      = clamp16F(sceneColor);
}