#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 iTex5;
uniform sampler2D iTex6;
uniform sampler2D iTex7;
uniform sampler2D iTex8;
uniform sampler2D iNoise;
uniform sampler2D iChecker;

// out_color must be written in order to see anything
//
layout(location = 0) out vec4 out_color;
///////////////////////////////////////////////////////////////////////////////
///////////

////////////////////////////////////////////////////////////////////

float box(vec3 p, vec3 s){
	vec3 p0 = abs(p) - s;
	return min(max(p0.x, max(p0.y, p0.z)), 0) - length(max(p0, 0));
}

vec3 ro(vec3 p, float a) {
	return mat3(1,0,0,0,cos(a),sin(a),0,-sin(a),cos(a)) * p;
}

float h(vec3 p)
	{
	p.z -= 10;
	 p =ro(p, (iFFTs[0] - iFFTs[4]));
	 p =ro(p.yxz, (iFFTs[6] - iFFTs[1]) * 3).xzy;
	p = ro(p, iGlobalTime / 2+ (p.z *iFFTs[1])/ 50 );
	p = ro(p.yxz, iGlobalTime/3 + (p.z *iFFTs[1])/ 50 ).yxz;
	p = mod(p - 5, 10) - 5;
	return length(p.xy) - .5 * (iFFTs[0] +iFFTs[4]) * 2;
}

void main(void)
{
	vec2 uv = vec2( gl_FragCoord.xy ) / iResolution;
	vec2 uv5 = uv - 0.5;
	vec2 m;
float d;
vec3 rd = normalize(vec3((gl_FragCoord.x/iResolution.x - .5)* iResolution.x/iResolution.y, gl_FragCoord.y/iResolution.y - .5,1 - iFFTs[0] + iFFTs[3] )), p = vec3(0);
	for(int i = 0; i< 256; i++){
		d = h(p);
		if(d < .001)
			break;
		p+=rd* d / 8;

	}
	m.x = atan(uv5.x / uv5.y);
	m.y = length(uv5);
	float f = texture( iFFTTexture, m.y  ).r * 5;
	m.y -= iGlobalTime;
	vec4 t = texture( iTex3, m.xy  );
	out_color =  vec4(h(p - vec3(.01)) * 20) * mix(vec4(.2,.7,.6,0), vec4(1), (iFFTs[0] * 2)) * sin(length(p)/ 15);
}