#version 430

in vec2 uv;

layout(location = 0) out vec4 frag;

vec2 rotateXY(vec2 p, float a) {
  vec2 r = p;
  r.x = cos(a)*p.x - sin(a)*p.y;
  r.y = sin(a)*p.x + cos(a)*p.y;
  return r;
}

uniform float g_time;
uniform float windowWidth = 1280.0;
uniform float windowHeight = 720.0;

float zn = 0.0;
float zf = 1.0;
uniform mat4 projectionMatrix;
uniform mat4 projectionInvMatrix;
uniform mat4 viewInvMatrix;
vec4 CalcEyeFromWindow(in vec3 windowSpace) {
    vec3 ndcPos;
    vec4 viewport = vec4(0.0, 0.0, windowWidth, windowHeight);
    ndcPos.xy = ((2.0 * windowSpace.xy) - (2.0 * viewport.xy)) / (viewport.zw) - 1;
    ndcPos.z = (2.0 * windowSpace.z - zn - zf) / (zf - zn);
    vec4 clipPos;
    clipPos.w = projectionMatrix[3][2]/(ndcPos.z-(projectionMatrix[2][2]/projectionMatrix[2][3]));
    clipPos.xyz = ndcPos * clipPos.w;
    return projectionInvMatrix * clipPos;
}


layout(binding=0) uniform sampler2D tex;
layout(binding=1) uniform sampler2D texDepth;

uniform float wipeWidth = 1.0;
uniform vec4 wipeExp = vec4(1.0, 1.0, 1.0, 1.0);
uniform float wipeZero = 0.0;
uniform float wipeOrig = 1.0;
uniform float wipeBright = 1.0;

uniform float wipePosX = 1.0;
uniform float wipePosY = 1.0;
uniform float wipePosZ = 1.0;

uniform float wipeRepeX = 1000.0;
uniform float wipeRepeY = 1000.0;
uniform float wipeRepeZ = 1000.0;

uniform float rotX = 0.0;
uniform float rotY = 0.0;
uniform float rotZ = 0.0;

void main() {

    vec2 uvS = uv;
    uvS.y = 1.0-uvS.y;

    vec2 tc = gl_FragCoord.xy;

    vec4 screen = texelFetch(tex, ivec2(tc), 0);
    vec4 d = texelFetch(texDepth, ivec2(tc), 0);


    vec4 eye = CalcEyeFromWindow(vec3(tc, d.r));

    vec4 wp = viewInvMatrix*eye;
    vec4 camPos = vec4(viewInvMatrix[3][0], viewInvMatrix[3][1], viewInvMatrix[3][2], viewInvMatrix[3][3]);
  //  wp.xyz -= camPos.xyz;

//    1.0 .. 0.0 .. 1.0 .. 2.0
//    =>
//    wipeWidth = 2.0
//    =>
//    0.5 .. 0.0 .. 0.5 .. 1.0
//    => (1/x)
//    2.0 .. inf .. 2.0 .. 1.0

    vec3 wipePos = vec3(wipePosX, wipePosY, wipePosZ);
    vec3 wipeRepe = vec3(wipeRepeX, wipeRepeY, wipeRepeZ);

    vec3 wpk = (wp.xyz-wipePos);

    wpk.xy = rotateXY(wpk.xy, rotZ);
    wpk.xz = rotateXY(wpk.xz, rotY);
    wpk.yz = rotateXY(wpk.yz, rotX);

    vec3 wpRep = wpk.xyz-vec3(0.5);

    vec3 repes = fract(abs(wpk)/wipeRepe+vec3(0.5))-vec3(0.5);
    vec3 repesSmoothe = vec3(1.0); //vec3(clamp((repes)*2048.0, 0.0, 1.0));
    wp.xyz = sign(wpk)*repes*wipeRepe;
//    wp.xyz = repes*wipeRepe;
    //wp.x = wp.x-wipePosX;
    vec3 br = vec3(1.0)/(abs(wp.xyz)/vec3(wipeWidth)+vec3(wipeZero));


    if (wpRep.x < 0.0) {
        br.x = pow(br.x, wipeExp.x*wipeExp.y);
    } else {
        br.x = pow(br.x, wipeExp.x*wipeExp.z);
    }
    if (wpRep.y < 0.0) {
        br.y = pow(br.y, wipeExp.x*wipeExp.y);
    } else {
        br.y = pow(br.y, wipeExp.x*wipeExp.z);
    }
    if (wpRep.z < 0.0) {
        br.z = pow(br.z, wipeExp.x*wipeExp.y);
    } else {
        br.z = pow(br.z, wipeExp.x*wipeExp.z);
    }
    br *= wipeBright;
    br *= repesSmoothe;

    screen.rgb *= (wipeOrig+br.x+br.y+br.z);

    screen.a = 1.0;

    frag = screen;
}

