// This shader gets run last for eveything we've rendered so far.
// It currently features bloom, tone mapping, chromatic aberration and noise.

precision highp float;

out vec4 FragColor;

in vec2 FragCoord;

uniform sampler2D u_InputSampler;
uniform sampler2D u_NoiseSampler;
uniform sampler2D u_BloomSampler;
uniform int u_NoiseSize;
uniform float u_RocketRow;
uniform vec2 u_Resolution;

uniform r_Post {
    float aberration;
} post;

// https://64.github.io/tonemapping/
vec3 acesApprox(vec3 v) {
    v *= 0.6;
    float a = 2.51;
    float b = 0.03;
    float c = 2.43;
    float d = 0.59;
    float e = 0.14;
    return clamp((v * (a * v + b)) / (v * (c * v + d) + e), 0., 1.);
}

void main() {
    // Input color with RGB aberration
    vec2 uv = FragCoord * 0.5 + 0.5;
    vec3 color = vec3(
            texture2D(u_InputSampler, uv + post.aberration).r,
            texture2D(u_InputSampler, uv).g,
            texture2D(u_InputSampler, uv - post.aberration).b
        );

    // Add bloom
    for (int i = 0; i < BLOOM_LEVELS; i++) {
        color += textureLod(u_BloomSampler, FragCoord * 0.5 + 0.5, float(i)).rgb / float(BLOOM_LEVELS);
    }

    // Tone mapping
    color = acesApprox(color);

    // Add noise
    color += texelFetch(u_NoiseSampler, ivec2(gl_FragCoord.xy) % u_NoiseSize, 0).rgb * 0.08 - 0.04;

    // Vignette
    color -= length(FragCoord) * 0.1;

    // Gamma correct on GL ES, sRGB framebuffer doesn't seem to work on ES
    #ifdef GL_ES
    color = pow(color, vec3(2.2));
    #endif

    FragColor = vec4(clamp(color, 0., 1.), 1.);
}
