#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; // generic textures
uniform sampler2D iTex2;
uniform sampler2D iTex3;
uniform sampler2D iTex4;
uniform sampler2D iTex5;
uniform sampler2D iTex6; // noise
uniform sampler2D iTex7; // moqui
uniform sampler2D iTex8; // okkie
uniform sampler2D iNoise; // perlin noise
uniform sampler2D iChecker;

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

void main(void)
{
       vec2 uv = vec2( gl_FragCoord.xy -iResolution*.5) / iResolution.x;
       vec3 pos=vec3(sin(iGlobalTime),cos(iGlobalTime),iGlobalTime+iFFTs[0]*5.);
       vec3 dir=normalize(vec3(uv,1));
       float a=-.27;
       dir*=mat3(1,0,0,0,cos(a),sin(a),0,-sin(a),cos(a));

       vec3 vox=floor(pos);


       vec3 norm,hit;
       float bright;



       vec3 color=vec3(0);

       for(int i=0;i<50;i++){
               vec3 dist=vox-pos+step(vec3(0),dir);
               vec3 mx=dist/dir;
               norm=mx.x<mx.y&&mx.x<mx.z?vec3(1,0,0):mx.y<mx.z?vec3(0,1,0):vec3(0,0,1);
               vox += norm*sign(dir);
               hit=pos+dot(norm,mx)*dir;
               vec3 d=vox*.7;
               float dens=d.y*.5+texture(iNoise,d.xz*.1+iFFTs[0]).x*6.+.3;
               if (dens<0)break;
               bright=(49-i)/50.;
               float dens2=hit.y*.5+texture(iNoise,hit.xz*.1+iFFTs[0]).x*6.+.3;
               color += dot(.5-abs(fract(hit)-.5),vec3(1))*.2/dens+vec3(-1,-1,1)*step(fract(dens2),.004)*step(fract(dens),.1)*10.;
       }





       float f = texture( iFFTTexture, uv.y  ).r * 10;
       vec4 t = texture( iTex8, fract(-hit.xy)  )*norm.z+texture( iTex7, fract(-hit.xz)  )*norm.y;
       out_color = f*.2 + t*bright+(color.xyzz-6+vec4(iFFTs[1],iFFTs[2],iFFTs[3],0)*8.4)*.4;
}