#version 330 core

in vec2 TexCoords;
out vec4 FragColor;

uniform sampler2D screenTexture;
uniform sampler2D blurTexture;
uniform sampler2D luminanceTexture;
uniform float gamma;
uniform float exposure;

// http://filmicgames.com/archives/75
float A = 0.15;
float B = 0.50;
float C = 0.10;
float D = 0.20;
float E = 0.02;
float F = 0.30;
float W = 11.2;

vec3 uncharted2Tonemap(vec3 x)
{
    return ((x*(A*x+C*B)+D*E)/(x*(A*x+B)+D*F))-E/F;
}

vec3 mapUncharted(vec3 color)
{
    //float ExposureBias = 2.0f;
    float ExposureBias = exposure;
    vec3 curr = uncharted2Tonemap(ExposureBias * color);

    float brightness = dot(color, vec3(0.2126, 0.7152, 0.0722));
    vec3 whiteScale = 1.0f / uncharted2Tonemap(vec3(W, W, W));
    color = curr * whiteScale;
    
    //return pow(color, vec3(1 / 2.2));
    //return pow(color, vec3(1 / gamma));
    return color;
}

void main()
{
    vec3 avgColor = texture(luminanceTexture, TexCoords).rgb;
    float avgLuminance = dot(avgColor, vec3(0.2126, 0.7152, 0.0722));
    vec3 hdrColor = texture(screenTexture, TexCoords).rgb;
    vec3 bloomColor = texture(blurTexture, TexCoords).rgb;
    vec3 result = hdrColor + bloomColor;

    // Exposure adjustment
    //result *= exposure;
    result *= min((exposure / avgLuminance), 10);

    // Tone mapping
    //result = result / (vec3(1.0) + result); // Reinhard
    result = vec3(1.0) - exp(-result); // Exposure
    //result = mapUncharted(result);
    //fragColor = textureLod(myTexture, textureCoord, mipmapLevel);

    // Gamma correction
    result = pow(result, vec3(1.0 / gamma));
    
    FragColor = vec4(result, 1.0f);
    //FragColor = texture(screenTexture, TexCoords) + texture(blurTexture, TexCoords);
}
