#version 330 core

in vec2 texCoord;
in vec4 vertexFragColor;
out vec4 fragColor;
uniform sampler2D texture0;
uniform sampler2D texture1;
uniform float time = 1.0;
uniform vec4 color = vec4(1,1,1,1);

uniform float distortionResolutionX = 1920.0;
uniform float distortionResolutionY = 1080.0;
uniform float distortionX = 0.01;
uniform float distortionY = 0.01;
uniform float noiseAlpha = 0.1;
uniform float shakeSizeY = 0.005;
uniform float glitchSize = 0.001;

uniform float farThresHold = 0.2;
uniform float maxBias = 3.0;

float calculateDepth()
{
    float z = texture(texture1, texCoord).r;
    float near = 1.0;
    float far = 10.0;
    float clipNormZ = (2.0 * near) / (far + near - z * (far - near));
    return clipNormZ;
}

float calculateDofLodBias()
{
    float bias = 0.0;
    float normDepthZ = calculateDepth();
    if (normDepthZ > farThresHold) {
        bias = maxBias*smoothstep(0.0,1.0,((normDepthZ-farThresHold)/(1.0-farThresHold)));
    }

    return bias;
}

float rand(vec2 coord)
{
    return fract(sin(dot(coord.st,vec2(12.9898,78.233)+time)) * 43758.5453);
}

float getDistortionFactor(vec2 coord)
{
    //pixelize distortion
    vec2 d = vec2(1.0,1.0)/vec2(distortionResolutionX, distortionResolutionY);
    coord.s = floor(coord.s/d.s)*d.s+time;
    coord.t = floor(coord.t/d.t)*d.t+time;
    
    return rand(coord);
}

float getRandomNoise(vec2 coord)
{
    return rand(coord);
}

vec4 distortion()
{
    float bias = calculateDofLodBias();

    vec2 coord = texCoord;

    vec2 pseudoRandomCoord = coord + vec2(1.,2.*tan(time*10))*time;
    float distortion = getDistortionFactor(pseudoRandomCoord);
    float random = getRandomNoise(pseudoRandomCoord);
    
    float noiseDistortionX = texture(texture0,vec2(coord.t+time,0),bias).x*distortion*distortionX;

    coord.x = fract(coord.x + noiseDistortionX + tan(coord.y + time)*glitchSize*sin(time + 4*sin(time*4))*(1.0 + cos(time*80.)));
    
    float shakeY = shakeSizeY*sin(time*0.1*cos(time*2))*(sin(time)*sin(time*20) + (1.0 + sin(time*20)*cos(time)));
    
    float noiseDistortionY = texture(texture0,vec2(0,coord.s+time),bias).x * distortion * distortionY;
    
    coord.y = fract(coord.y + shakeY + noiseDistortionY);
    
    vec4 result = texture(texture0,coord,bias)*(1.0 - noiseAlpha) + random*noiseAlpha;
    
    return result * color;
}

void main()
{
    vec4 c = distortion();
    vec4 grayColor = vec4(vec3((c.r+c.g+c.b)/3.0)*0.7, c.a);

    fragColor = vec4(grayColor.rgb+(c.rgb*0.3), 1.0);
}
