#version 430 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 sampler2D texBricks;
uniform sampler2D texGrunge;
uniform sampler2D texHello;
uniform sampler2D texMono;
uniform sampler2D texNoise;
uniform sampler2D texNormal;
uniform sampler2D texPaper;

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

vec4 plas( vec2 v, float time )
{
  float c = 0.5 + sin( v.x * 10.0 ) + cos( sin( time + v.y ) * 20.0 );
  return vec4( sin(c * 0.2 + cos(time)), c * 0.15, cos( c * 0.1 + time / .4 ) * .25, 1.0 );
}

float sphere(vec3 p)
{
  float foo = length(p) - 0.5f;
float f = sin(fGlobalTime) * 2.f;
  float d = sin(p.x * f)  * sin(p.y * f) * sin(p.z * f);
  return foo + d;
}

vec3 calcNormal(in vec3 p)
{
  vec3 norm;
  vec3 esp = vec3(0.1f, 0, 0);
  norm.x = sphere(p + esp.xyz) - sphere(p - esp.xyz);
  norm.y = sphere(p + esp.yxz) - sphere(p - esp.yxz);
  norm.z = sphere(p + esp.zzx) - sphere(p - esp.zzx);
return normalize(norm);
}

void main(void)
{
  vec2 uv = vec2(gl_FragCoord.x / v2Resolution.x, gl_FragCoord.y / v2Resolution.y);
  uv -= 0.5;
  uv /= vec2(v2Resolution.y / v2Resolution.x, 1);

  vec3 rayO = vec3(0,0,1.0);
  vec3 rayD = vec3(uv, -1.0);
  float to = 0;
  vec4 color = vec4(0,0,0,1);
  for(int i = 0;i < 32;++i)
  {
    vec3 p =rayO + rayD*to;
    float d = sphere(p);
    if(d < 0.01f)
    {
      vec3 normal = calcNormal(p);
      vec2 texCoord = vec2(asin(normal.x) * 0.5 + 0.5, 1 - (asin(normal.y) * 0.5 + 0.5));
      texCoord.x += fGlobalTime;
      color = dot(normal, vec3(0.33)) * texture2D(texHello, texCoord);
    }
    to += d;
  }

  out_color = color + 0.5*texture2D(texGrunge, uv + vec2(fGlobalTime, fGlobalTime*0.5));
}