#version 100
// referenced from https://www.shadertoy.com/view/tlVXD3
precision highp float;

varying vec2 uv;
uniform sampler2D screenTexture;
uniform vec2 screenSize;
uniform float time;

uniform float exposure; // %1% 0.1..6.1
uniform float factor; // %1% 0..1

// linear to sRGB
float toneMap(float c)
{
    return c / (c + .1667);
}

// sRGB to linear
float unToneMap(float c)
{
    return c/(6.-6.*c);
}

// combined exposure, tone map, gamma correction
vec3 toneMap(vec3 crgb, float exposure) // exposure = white point
{
    vec4 c = vec4(crgb, exposure);
    c = vec4(toneMap(c.r), toneMap(c.g), toneMap(c.b), toneMap(c.a));
    return c.rgb / c.a;
}

vec3 dither(vec3 c, vec2 p)
{
    float x; // noise
    x = fract(time*0. + 23456.7*sin(dot(p, vec2(12.93,8.57)))); // from ALU hash
    x = 2. * x - 1.; // signed
    c += .75 * exp2(-8.) * x; // tuned for 8 bits per channel
    return c;
}

void main()
{
    vec4 t = texture2D(screenTexture, uv);
    t.rgb = pow(t.rgb, vec3(2.2)); //t.rgb*t.rgb; // from sRGB
    vec3 c = t.rgb;
    c *= exposure;
    c = toneMap(c, exposure);
    c = dither(c, uv * screenSize);
    gl_FragColor=mix(texture2D(screenTexture,uv),vec4(c, t.a),factor);
}