in vec2 uv;
in vec2 uvn;

out vec4 C;

uniform int accum_tex;

#define AGX_LOOK 0

// AgX
// ->

// Mean error^2: 3.6705141e-06
//vec3 agxDefaultContrastApprox(vec3 x) {
//}

vec3 agx(vec3 val) {
    const mat3 agx_mat = mat3(
    0.842479062253094, 0.0423282422610123, 0.0423756549057051,
    0.0784335999999992,  0.878468636469772,  0.0784336,
    0.0792237451477643, 0.0791661274605434, 0.879142973793104);

    const float min_ev = -12.47393f;
    const float max_ev = 4.026069f;

    // Input transform
    val = agx_mat * val;

    // Log2 space encoding
    val = clamp(log2(val), min_ev, max_ev);
    val = (val - min_ev) / (max_ev - min_ev);


    vec3 x = val;
    vec3 x2 = x * x;
    vec3 x4 = x2 * x2;

    val = + 15.5 * x4 * x2
    - 40.14 * x4 * x
    + 31.96 * x4
    - 6.868 * x2 * x
    + 0.4298 * x2
    + 0.1191 * x
    - 0.00232;


    const vec3 lw = vec3(0.2126, 0.7152, 0.0722);
    float luma = dot(val, lw);

    // Default
    vec3 offset = vec3(0.0);

    vec3 slope = vec3(1.0);
    vec3 power = vec3(1., 1., 1.)*1.4;
    float sat = 1.5;

    val = pow(val * slope + offset, power);
    return luma + sat * (val - luma);

    return val;
}

vec3 agxEotf(vec3 val) {
    const mat3 agx_mat_inv = mat3(
    1.19687900512017, -0.0528968517574562, -0.0529716355144438,
    -0.0980208811401368, 1.15190312990417, -0.0980434501171241,
    -0.0990297440797205, -0.0989611768448433, 1.15107367264116);

    // Undo input transform
    val = agx_mat_inv * val;

    // sRGB IEC 61966-2-1 2.2 Exponent Reference EOTF Display
//    val = pow(val, vec3(2.2));

    return val;
}


//vec3 agxLook(vec3 val) {
//}
struct Buff {
    float[100] stuff;
// etc.
};
layout(location=5) uniform Buff *buff;
//layout(location=5) uniform uint64_t buff;

vec3 XYZtosRGB( vec3 XYZ ) { mat3 m = mat3 ( 3.2404542, -1.5371385, -0.4985314, -0.9692660,  1.8760108,  0.0415560, 0.0556434, -0.2040259,  1.0572252 ); return XYZ * m; }

void main(){
//    C = tex(accum_tex, uvn);
//    imageStore(
//        f_images[prev_gi_tex],
//        ivec2(gl_FragCoord),
////        imageLoad(f_images[gi_tex], ivec2(gl_FragCoord))
//        texelFetch(textures[gi_tex], ivec2(gl_FragCoord),0)
//    );
//    C = tex(taa_tex, uvn);



    C = tex(accum_tex, uvn);
//    C = max(C,0);

    C.rgb = XYZtosRGB(C.rgb);
    C.rgb = agx(C.rgb);
    C.rgb = agxEotf(C.rgb);
    C = max(C,0.);


    C = max(C,0.0);
    C.rgb += h33(vec3(uv*100,fract(T)))*0.01;

    C *= 1.-dot(uv,uv)*0.34;

    C = pow(max(C,0.),vec4(0.45454545));
    C.a = 1.0;

//    float* buff_pt = (float*)buff;
//    C.x += buff_pt[2]*0.2;
    C.x += buff->stuff[0];
//    float g = buff->stuff[0];
//    C.x += g;


    // ------- storage

//    uint dbg = imageLoad(u32_images[dbg_tex], ivec2(gl_FragCoord)).x;
//    C += float(dbg);
//    imageStore(u32_images[dbg_tex], ivec2(gl_FragCoord), uvec4(0u));
}
