#version 430 core

uniform float fGlobalTime; // in seconds
uniform vec2 v2Resolution; // viewport resolution (in pixels)

uniform sampler1D texFFT; // towards 0.0 is bass / lower freq, towards 1.0 is higher / treble freq
uniform sampler1D texFFTSmoothed; // this one has longer falloff and less harsh transients
uniform sampler2D texBricks;
uniform sampler2D texGrunge;
uniform sampler2D texHello;
uniform sampler2D texMono;
uniform sampler2D texNoise;
uniform sampler2D texNormal;
uniform sampler2D texPaper;

float time;

layout(location = 0) out vec4 out_color; // out_color must be written in order to see anything

vec4 plas( vec2 v, float time )
{
  float phi = atan(v.x,v.y);
  float c = 0.5 + sin( v.x * 10.0 ) + cos( sin( time + v.y ) * 20.0 );
  float a = mod(phi+time,2);
  vec4 b = texture(texHello,v);
  return b+5*a*vec4( sin(c * 0.2 + cos(time)), c * 0.15, cos( c * 0.1 + time / .4 ) * .25, 1.0 );
}

float max3(vec3 d) {
 return max(d.x, min(d.y,d.z));
}

float cube(vec3 p, vec3 d) {
  vec3 x = abs(p) - d;
  return length(max(x,0)) + max3(min(x,0));
}

vec3 modrepeat(vec3 p, vec3 r) {
  return mod(p -.5*r, r) + .5*r;
}

#define R(v,a) (v.xy*cos(a) + v.yx * vec2(-sin(a),sin(a)))

float f(vec3 p) {
  vec3 q = p;
  q.xz = R(q.xz,time);  
  float c = cube(q-vec3(0,0,10), vec3(3));
  c = min(c, cube(q-vec3(5,3,13), vec3(2,7,3)));
c = min(c, cube(q-vec3(-5,-3,13), vec3(2,7,3)));
   return min(p.y + 3, c);
}

void main(void)
{
  vec2 uv = vec2(gl_FragCoord.x / v2Resolution.x, gl_FragCoord.y / v2Resolution.y);
  uv -= 0.5;
  uv /= vec2(v2Resolution.y / v2Resolution.x, 1);


  time = fGlobalTime;
  
    uv.x += .3*sin(time);
    uv.y += .3*cos(time)+.3;
 if(mod(time, 7.5) < 2.5) {
  time += length(uv) - mod(length(uv),.2);
 } else if(mod(time, 7.5) < 5) {
  time += uv.x + uv.y - mod(uv.x,.2) - mod(uv.y,.2);
  }



  float t=0;
  float tmax=100;
  float epsilon = 0.0001;
  float r;
  vec3 p=vec3(0);
  vec3 d=vec3(uv.xy,1);
  for(int i=0; i<128 && t<tmax; i++) {
    r = f(p+d*t);
    if(r < epsilon*.1) {
       break;
    }   
    t+=r;
  }

  if(t < tmax) {
    uv.y = p.y-uv.y;
  }

  {
  vec2 m;
  m.x = atan(uv.x / uv.y) / 3.14;
  m.y = 1 / length(uv) * .2;
  float d = m.y;

  float f = texture( texFFT, d ).r * 100;
  m.x += sin( time ) * 0.1;
  m.y += time * 0.25;

  vec4 t = plas( m * 3.14, time ) / d;
  t = clamp( t, 0.0, 1.0 );
  out_color = t;
  }

  if(t < tmax) {
    out_color *= .1*t/tmax;
    float b=(1-t/tmax);
    out_color += vec4(b,b*b,sin(b)*b,1);
  }
  
 float fa = texture(texFFTSmoothed,0.01).x;
 out_color = mix(out_color, vec4(1)-out_color, .3*(texture(texFFT,0.01).x-fa)/fa);
 out_color = pow(out_color, vec4(1.3-.7*mod(time,2.5)));
 float val = length(out_color);
 out_color = mix(out_color, vec4(val), texture(texPaper,uv)*(1.2-vec4(sqrt(val))));

}