/***********************************************/
/*           Copyright (c) 2025 Belmu          */
/*             All Rights Reserved             */
/***********************************************/

/*
    [References]:
        Hellsten, J. (2007). Evaluation of tone mapping operators for use in real time environments. http://www.diva-portal.org/smash/get/diva2:24136/FULLTEXT01.pdf
        Lagarde, S. (2014). Moving Frostbite to Physically Based Rendering 3.0. https://seblagarde.files.wordpress.com/2015/07/course_notes_moving_frostbite_to_pbr_v32.pdf
        Guy, R., & Agopian, M. (2019). Physically Based Rendering in Filament. https://google.github.io/filament/Filament.md.html
*/

#if defined STAGE_VERTEX

    out vec2 textureCoords;

    void main() {
        textureCoords = gl_Vertex.xy;
        gl_Position   = vec4(gl_Vertex.xy * 2.0 - 1.0, 1.0, 1.0);
    }

#elif defined STAGE_FRAGMENT

    /* RENDERTARGETS: 0 */

    layout (location = 0) out vec3 color;

    in vec2 textureCoords;

    #include "/settings.glsl"
    #include "/include/uniforms.glsl"
    #include "/include/utility/math.glsl"
    #include "/include/utility/color.glsl"

    #if TONEMAP == 0
        #include "/include/camera/tonemap.glsl"
    #elif TONEMAP == ACES
        #include "/include/post/aces/lib/parameters.glsl"

        #include "/include/post/aces/lib/splines.glsl"
        #include "/include/post/aces/lib/transforms.glsl"

        #include "/include/post/aces/lmt.glsl"
        #include "/include/post/aces/rrt.glsl"
        #include "/include/post/aces/odt.glsl"
    #endif

    #include "/include/post/exposure.glsl"
    #include "/include/post/grading.glsl"
    
    void main() {
        vec4 tmp = texture(MAIN_BUFFER, textureCoords);
        color 	 = tmp.rgb;

        #if DEBUG_HISTOGRAM == 1 && EXPOSURE == 2
            if (all(lessThan(gl_FragCoord.xy, debugHistogramSize))) return;
        #endif

        float exposure = computeExposure(texelFetch(LUMINANCE_BUFFER, ivec2(0), 0).r);

        #if DEBUG_ALBEDO == 0 && DEBUG_NORMALS == 0 && DEBUG_HIT_POSITION == 0
        
            #if PURKINJE == 1
                if (hideGUI == 1)
                    scotopicVisionApproximation(color);
            #endif

            color *= exposure;

        #endif

        // Tonemapping & Color Grading

        #if TONEMAP == 0            // Camera Response
            cameraResponse(color);
        #elif TONEMAP == 1		   	// AgX
            agx(color);
            agxLook(color);
            agxEotf(color);
        #elif TONEMAP == ACES       // ACES
            compressionLMT(color);
            rrt(color);
            odt(color);
        #elif TONEMAP == 3          // Uchimura
            uchimura(color);
        #elif TONEMAP == 4         	// Lottes
            lottes(color);
        #elif TONEMAP == 5         	// Burgess
            burgess(color);
        #elif TONEMAP == 6         	// Reinhard-Jodie
            reinhardJodie(color);
        #elif TONEMAP == 7		   	// Uncharted 2
            uncharted2(color);
        #endif

        #if TONEMAP != ACES && TONEMAP != 1
            color = linearToSrgb(color);
        #endif

        whiteBalance(color);
        vibrance(color,   1.0 + VIBRANCE);
        saturation(color, 1.0 + SATURATION);
        contrast(color,   1.0 + CONTRAST);
        liftGammaGain(color, LIFT * 0.1, 1.0 + GAMMA, 1.0 + GAIN);

        color = saturate(color);

        vec4 raster = texture(RASTER_BUFFER, textureCoords);
             color  = mix(color, raster.rgb, raster.a);
    }
#endif
