#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 texMono;
uniform sampler2D texNoise;
uniform sampler2D texNormal;
uniform sampler2D texPaper;
uniform sampler2D texPooBrain;

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

vec4 plas( vec2 v, float time )
{
  float c = 0.5 + sin( v.x * 10.0 ) + cos( sin( time + v.y ) * 20.0 );
  return vec4( sin(c * 0.2 + cos(time)), c * 0.15, cos( c * 0.1 + time / .4 ) * .25, 1.0 );
}

float field(vec3 pos) {
  vec3 p = pos;

  float sc = vec3(1.3);

  p = fract(pos/sc)-.5;


  float b = fGlobalTime;
  p.xy *= mat2(cos(b),sin(b),-sin(b),cos(b));
  p.yz *= mat2(cos(b),sin(b),-sin(b),cos(b));
  p.zx *= mat2(cos(b),sin(b),-sin(b),cos(b));
  p = abs(p);
  

  float a = abs(length(pos.xy)-2.);
  p *= sc;
  p.x *= (1.-texture(texFFT,p.z*.001)*20.);
  p.y *= (1.-texture(texFFT,p.z*.001+.4)*10.);


  return min(a
  -texture(texNormal,vec2(atan(pos.x,pos.y),pos.z+texture(texFFT,p.z*.01))*.1).x*.5
  -texture(texNormal,vec2(atan(pos.x,pos.y),pos.z)*.03).x*.5+.28,
   max(max(p.x,p.y),p.z)-.1
   );
 

}

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);

  vec3 pos = vec3(0,0,fGlobalTime*3.);
  vec3 dir = normalize(vec3(uv,1));

  for (int i = 0; i < 40; i++) {
    float d = min(field(pos),2.);
    pos += d*dir;
  }

  float an = fGlobalTime*.3;

  dir.xy *= mat2(cos(an),sin(an),-sin(an),cos(an));
  
  vec2 pp = dir.xz/dir.y*.2;
  pp.y *= .1;

  vec4 pc = vec4(0);

  for (int i = 1; i < 10; i++) {
    vec2 coords = pp/i+vec2(0,fGlobalTime*.2*sign(pp.y));
   coords.y = floor(coords.y*30.)/30.;
    pc += (step(vec4(.4),texture(texPaper,coords))-.7)/sqrt(1.+pp.x*pp.x/1.); 
}
  pc *= .3;
  

  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( fGlobalTime ) * 0.1;
  m.y += fGlobalTime * 0.25;

  vec4 t = plas( m * 3.14, fGlobalTime ) / d;
  t = clamp( t, 0.0, 1.0 );
  float l1 = length(pos.xy);
  float l2 = l1;
  float l3 = 1.-min(2/l1,1.);
  vec4 result = (f + t)*.2 + (1.+vec4(cos(l2),cos(l2+.5),cos(l2-.5),0))*(1.-l3)+pc*l3;

  for (int i = 0; i < 10; i++) {
    float d = uv.x-(sin(uv.y*10.+i+fGlobalTime)*.1+i*.1-.5);
    result += .00001/(d*d+.00001)*step(uv.y,-.2);
    d = uv.x-(sin(-.2*10.+i+fGlobalTime)*.1+i*.1-.5);
    float y = uv.y+.2;
    result += .1/(d*d+y*y+.00001)*texture(texFFT,0).x;
    

  }


  out_color = result;

}