#version 430 core

///////////////////////////////////////////////////////////////////////////////
// shader inputs/outputs
///////////////////////////////////////////////////////////////////////////////
uniform float iGlobalTime; // in seconds
uniform vec2 iResolution; // viewport resolution (in pixels) (1080p or 720p)

// all samplers have linear filtering applied, wraping set to repeat
//
uniform sampler1D iFFTTexture; // 1024
uniform float iFFT[8]; // latest frame
uniform float iFFTs[8]; // smoothed latest frame
uniform sampler2D iFFTsHistory; // smoothed fft history, 8x1024, x coord = bin, y coord n-frames earlier, y=0 is latest frame

// predefined textures
//
uniform sampler2D iTex1;
uniform sampler2D iTex2;
uniform sampler2D iTex3;
uniform sampler2D iTex4;
uniform sampler2D iNoise;
uniform sampler2D iChecker;

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

float m(vec3 pos){
       float t=iGlobalTime;
       pos *= mat3(1,0,0,0,cos(t),sin(t),0,-sin(t),cos(t));
       pos = abs(fract(pos*.1-.25+vec3(iFFTs[0]*2+.9,0,0))-.5)*10;
       float f = 1;
       for (int i=0;i<1;i++){
               pos *=1.02;
               f*=1.02;
               pos *= mat3(cos(t),sin(t),0,-sin(t),cos(t),0,0,0,1);
               pos = pos.yzx;
               pos = abs(fract(pos*.3-.25+vec3(iFFTs[0]*.4+.9,0,0))-.5)/.3;
       }
       pos/=f;
       return length(pos-vec3(iFFT[1],iFFT[2],iFFT[3])*.4)-.6+texture(iNoise,pos.xy)*.4+texture(iNoise,pos.yz)*.3;
}

vec3 norm(vec3 pos){
       vec2 v=vec2(1e-3,0);
       return normalize(vec3(m(pos+v.xyy),m(pos+v.yxy),m(pos+v.yyx))-m(pos));
}

int[] test={1,31,1,0,31,0,1,31,1,0,31,5,31,0,31,1,31};


void main(void)
{

       vec2 s = vec2( gl_FragCoord.xy ) / iResolution-.5;
       vec3 pos =vec3(0,0,-10+fract(iGlobalTime)*4);
       vec3 dir = normalize(vec3(s,1));
       float sum=0;
       for (int i = 0; i < 100; i++){
               float di=m(pos);
               pos+=dir*di;
               sum+=1/max(1e-4,di);
       }

       ivec2 v=ivec2(gl_FragCoord.xy/30+vec2(cos(iGlobalTime),sin(iGlobalTime))*5);
       v.y=20-v.y;
v.x-=10;
int v2=(test[v.x]>>v.y)&1;
       out_color = v2+vec4(sum*1e-6)*dot(norm(pos),vec3(.3,.3,-.9))*abs(cos(pos).xyzz);// + uv.xyxy * 0.5 * (sin( iGlobalTime ) + 1.5);
}