#version 420 core
uniform float fGlobalTime;
uniform vec2 v2Resolution;
uniform float fFrameTime;
uniform sampler2D uSceneTex;
uniform float uPostExposure;
uniform float uPostGamma;
uniform float uChromaAmount;
uniform float uChromaRadius;
uniform float uChromaCenterX;
uniform float uChromaCenterY;
uniform float uFadeBlack;
uniform float uFadeWhite;
uniform float uGlitchAmount;
uniform float uGlitchMode;
uniform float uGlitchBlockSize;
uniform float uGlitchDisplace;
uniform float uGlitchRGB;
uniform float uGlitchScan;
uniform float uGlitchRate;
uniform float uGlitchSeed;
layout(location = 0) out vec4 out_color;

                      const int m=16;float u(vec2 p){vec3 P=fract(
                vec3(p.xyx)*.1031);P+=dot(P,P.yzx+33.33);return fract((P.
            x+P.y)*P.z);}float U(float p){return fract(sin(p*127.1)*
         43758.5453123);}vec3 L(vec3 x){const float a=2.51;const float b=.03;
       const float c=2.43;const float d=.59;const float e=.14;return clamp((x*(a*x+
     b))/(x*(c*x+d)+e),0.,1.);}vec2 I(vec2 J,out float G,out float j,out int n){
    float B=clamp(uGlitchAmount,0.,1.);float v=max(uGlitchBlockSize,8.);vec2 H=J*
  v2Resolution;vec2 K=floor(H/v);vec2 C=fract(H/v);float D=floor(fGlobalTime*max(
 uGlitchRate,0.)+uGlitchSeed*19.);j=u(K+vec2(D*.73,D*1.91)+uGlitchSeed);G=step(1.-B,j);
 int E=int(floor(uGlitchMode+.5));if(E<=0){n=1+int(floor(u(K+vec2(31.7,9.2)+D)*4.));}else
{n=clamp(E,1,4);}if(G<.5)return J;float V=u(K+vec2(17.,43.)+D);float X=u(K+vec2(71.,11.)-
D);if(n==1){J.x+=(V*2.-1.)*uGlitchDisplace;}else if(n==2){if(V>.5)C.x=1.-C.x;if(X>.65)C.y=
1.-C.y;J=(K*v+C*v)/v2Resolution;}else if(n==4){vec2 S=vec2(V-.5,X-.5);J+=S*uGlitchDisplace
*vec2(1.,.45);}return J;}vec3 o(vec2 J){float B=abs(uChromaAmount);if(B<1e-7)return
texture(uSceneTex,clamp(J,0.,1.)).rgb;vec2 M=vec2(uChromaCenterX,uChromaCenterY);vec2 N=J
 -M;vec3 Q=vec3(0.);vec3 F=vec3(0.);for(int i=0;i<m;++i){float t=(float(i)+.5)/float(m);t
  =t*2.-1.;vec2 W=J+N*(t*B*uChromaRadius);vec3 s=texture(uSceneTex,clamp(W,0.,1.)).rgb;
   float Y=exp2(-13.*(t-.36)*(t-.36))+.035;float Z=exp2(-18.*t*t)+.035;float wb=exp2(-
    13.*(t+.36)*(t+.36))+.035;vec3 w=vec3(Y,Z,wb);Q+=s*w;F+=w;}return Q/max(F,vec3(
     1e-5));}void main(void){vec2 J=gl_FragCoord.xy/v2Resolution;float l;float j;int
       k;vec2 A=I(J,l,j,k);vec3 f=o(A);if(l>.5){float h=u(floor(gl_FragCoord.xy/
          max(uGlitchBlockSize,8.))+uGlitchSeed);if(k==3){vec2 R=vec2((h*2.-1.)*
             uGlitchRGB,0.);vec3 cr=texture(uSceneTex,clamp(A+R,0.,1.)).rgb;
                 vec3 cb=texture(uSceneTex,clamp(A-R,0.,1.)).rgb;f.r=cr.
                     r;f.b=cb.b;}else if(k==4){float q=max(2.,floor(
                         3.+9.*h));f=floor(f*q+.5)/q;if(j>.96)f=
                              vec3(1.)-f;}float T=sin(
                              gl_FragCoord.y*.34+fGlobalTime
                              *47.+j*31.);f*=1.+uGlitchScan
                                *T*l;}f*=max(
                              uPostExposure,0.);f=L(max(f,
                              vec3(0.)));f=mix(f,vec3(0.),
                                clamp(uFadeBlack,0.,1.));
                              f=mix(f,vec3(1.),clamp(
                               uFadeWhite,0.,1.));float O=
                                max(uPostGamma,.1);f=pow(
                                 max(f,vec3(0.)),vec3(1.
                                   /O));out_color=vec4(
                                     clamp(f,0.,1.),
                                        1.);}
