#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 fram
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 mapg( vec3 pt, float sp )
{
       pt.xz *= 3.7;
       return (sin( pt.x ) + cos( pt.y ) ) * sp;
}

float rmg( vec3 ro, vec3 rd, float h, float sp )
{
       float t = 0.0;
       for( int i = 0; i < 50; i++ )
       {
               vec3 pt = ro + rd * t;
               float h = abs( pt.y - mapg( pt, sp ) );
               if( h < 0.1 )
               {
                       break;
               }

               t += h * 0.3;
       }
       return t;
}

vec3 colorize( vec3 ro, vec3 rd, vec2 uv )
{
       float sp = texture( iFFTTexture, 0.0 ).r * 2.0 + 0.25;
       float t = rmg( ro, rd, 10.0, sp );


       vec3 pt = ro + rd * t;
       vec3 light = vec3( 0.0, 1.0, 0.0 );

       vec3 ed = normalize( pt - ro );
       float eps = 0.1;

       vec3 norm =  normalize( vec3( mapg( pt + vec3( eps, 0.0, 0.0 ), sp ) - mapg( pt, sp ), 1.0,
                                 mapg( pt + vec3( 0.0, 0.0, eps ), sp ) - mapg( pt, sp ) ) );

       vec3 r = reflect( light, norm );

       vec3 color = pt * ( sp + 0.1) + vec3( 1.0 + sp * 5.0, 1.0 - sp * 5.0, 1.0 ) * max( 0.0, dot( pt, r ) );
       return color;
}


void main(void)
{
       vec2 uv = vec2( gl_FragCoord.xy ) / iResolution;
       uv = uv - vec2( 0.5, 0.5 );

       float sp = texture( iFFTTexture, 0.0 ).r * 4.0 + 0.25;

       vec3 ro = vec3( 0.0, 0.0, 0.0 );
       vec3 rd = normalize( vec3 ( uv.x, uv.y, 1.0 ) );

       float d = 0.5-length( uv ) * 0.75;


       vec3 color = colorize( ro, rd, uv ) * ( d - sp * 0.3 );
                //+ colorize( ro + vec3( sp * 0.5, 0.0, 0.0 ), rd, uv ) * ( d - sp * 0.3 );

       out_color = vec4( color, 1.0 );
}