#version 430 core

///////////////////////////////////////////////////////////////////////////////
// shader inputs/outputs
///////////////////////////////////////////////////////////////////////////////
uniform float iGlobalTime; // in seconds
uniform vec2 iResolution; // viewport resolution (in pixels) (1080p or 720p)
uniform mat4 iMidiPad; // 16 buttons of midi controller
uniform float iMidiPadValue; // sum of all elements in iMidiPad/16

// 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 hash(float n)
{
       return fract ( sin(n) * 45612.2134);
}


float h(vec3 p)
{
       p.z += 5 * iGlobalTime;
       p.y += sin(p.z + iFFTs[3]) ;
       p = mod(p-5, 10) - 5;
       return -length(p.xy) + 3 - iFFTs[0] * 3 ;
}

void main(void)
{
       float aspect = iResolution.x/iResolution.y;
       vec3 rd = normalize(vec3 (aspect*(gl_FragCoord.x / iResolution.x - .5), gl_FragCoord.y/iResolution.y - .5,1 + (20*iFFTs[1] - iFFTs[5]))), p=vec3(0);
       float d;
       for(int i = 0; i< 256; i++)
       {
               d = h(p);
               if(d<.001)
                       break;
               p += rd* d / 8;
       }
       vec2 uv = vec2( gl_FragCoord.xy ) / iResolution;
       float f = texture( iFFTTexture, uv.x  ).r * 100;
       out_color = vec4(.7,.2,.4,1) * vec4(h(p - vec3(.01) ) * 10) ;
}