#version 410 core

uniform float fGlobalTime; // in seconds
uniform vec2 v2Resolution; // viewport resolution (in pixels)

uniform sampler1D texFFT; // towards 0.0 is bass / lower freq, towards 1.0 is higher / treble freq
uniform sampler1D texFFTSmoothed; // this one has longer falloff and less harsh transients
uniform sampler1D texFFTIntegrated; // this is continually increasing
uniform sampler2D texChecker;
uniform sampler2D texNoise;
uniform sampler2D texParty;
uniform sampler2D texTex1;
uniform sampler2D texTex2;
uniform sampler2D texTex3;
uniform sampler2D texTex4;
uniform sampler2D texUm;

layout(location = 0) out vec4 out_color; // out_color must be written in order to see anything

#define PI 3.1415926

float box(vec3 p, vec3 b) {
    vec3 d = abs(p) - b;
    return min(max(d.x, max(d.y, d.z)), 0.) + length(max(d, 0.));
}

mat2 r(float a) {
    float c = cos(a), s = sin(a);
    return mat2(c, -s, s,c);
}

vec3 palette(float t, vec3 a, vec3 b, vec3 c, vec3 d)
{
    return a + b * cos(c + d *t);
}

float map(vec3 p) {
    float music = texture(texFFTSmoothed, 1.).x;
    p.z += cos(p.x*.4 + fGlobalTime) + cos(p.y*.4);
    p.y += cos(p.x*p.x*.23 + fGlobalTime);
    //xy *= r(p.z*.1);
    p.z -= fGlobalTime*10.;
    p = mod(p, 2.)-1.;
    //p.z -= fGlobalTime + 10.*music;
    float d;
    d = box(p, vec3(.4, .5, .1));
    return d;
}

float trace(vec3 ro, vec3 rd) {
    float t = 0.;
    for (int i = 0; i < 100; i++) {
        vec3 p = ro + rd * t;
        float m = map(p);
        t += m*.5;
        if (t > 20. || m < .005) break;
    }
    return t;
}

vec3 calcNormal(vec3 p) {
    vec2 e = vec2(0.005, 0.);
    return normalize(vec3(
     map(p+e.xyy)-map(p-e.xyy),
     map(p+e.yxy)-map(p-e.yxy),
    map(p+e.yyx)-map(p-e.yyx)));
}

void main(void)
{
  vec2 uv = (2.*gl_FragCoord.xy-v2Resolution.xy)/v2Resolution.y;

    vec3 ro = vec3(0, 0, 1), rd = normalize(vec3(uv, -1));
    float t = trace(ro, rd);
    vec3 lp = vec3(1, 4, 6);
    vec3 p = ro + rd * t;
    vec3 ld = normalize(lp - p);
    vec3 n = calcNormal(p);
    vec3 col = palette(fGlobalTime, vec3(.5, .23, .1), vec3(.8, .2, .6), vec3(.8, .2, .1), vec3(.1, .5, .2)) * dot(ld, n);
    col = mix(col, vec3(1.), smoothstep(5., 7., t));
  out_color = vec4(col, 1.0);
}