#version 410 core
uniform float fGlobalTime; // in seconds
uniform vec2 v2Resolution; // viewport resolution (in pixels)
uniform float fFrameTime; // duration of the last frame, in seconds
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 texPreviousFrame; // screenshot of the previous frame
uniform sampler2D texChecker;
uniform sampler2D texNoise;
uniform sampler2D texTex1;
uniform sampler2D texTex2;
uniform sampler2D texTex3;
uniform sampler2D texTex4;
layout(location = 0) out vec4 out_color; // out_color must be written in order to see anything
vec3 getcam( vec3 cam, vec3 target, vec2 uv, float fov)
{
vec3 forward = normalize(target - cam);
vec3 right = normalize(cross(vec3(0,1,0), forward));
vec3 up = normalize(cross(forward, right));
return normalize( uv.x * right + uv.y * up + fov*forward);
}
vec3 repeat( vec3 p, vec3 q)
{
vec3 b = mod(p + 0.5*q,q) - 0.5*q;
return b;
}
float smin( float a, float b, float k)
{
float h = clamp(0.5 + 0.5 *(b-a)/k, 0.0, 1.0);
return mix( b,a,h) - k*h*(1.-h);
}
float box( vec3 p, vec3 b)
{
vec3 q = abs(p)-b;
return length (max(q,0.0)) + min(max(q.x,max(q.y,q.z)),0.0);
}
float sphere( vec3 p, float r )
{
return length(p) - r;
}
float ground( vec3 p, float y)
{
return p.y - y;
}
vec2 U(vec2 a, vec2 b)
{
return vec2( min(a.x, b.x), mix(a.y, b.y, step(b.x, a.x)));
}
vec3 map( vec3 p, float fft, float fftS)
{
float spoff = sin(p.x) + cos(p.z*5.+fGlobalTime+p.y*3.);
float sp1 = sphere( p-vec3(
sin(fGlobalTime*0.75+fftS*2.5),
1.5+cos(fGlobalTime*0.25),
cos(fGlobalTime*0.5)
), 0.5+spoff*0.05);
float sp2 = sphere( p-vec3(
sin(fGlobalTime*0.5),
1.5,
cos(fGlobalTime*0.55+fftS*2.5)
), 0.5+spoff*0.05);
sp1 = smin(sp1,sp2,0.5);
float sp3 = sphere( p-vec3(
sin(fGlobalTime*0.25),
1.5+cos(fGlobalTime*0.25+fftS*2.5)*0.5,
cos(fGlobalTime*0.35)
), 0.5+spoff*0.05);
sp1 = smin(sp3,sp1,0.5);
float h = texture(texNoise, p.xz*.1+vec2(fftS*0.06+fGlobalTime*0.01,-fftS*0.16+fGlobalTime*0.012 )).r*1.0;
h += texture(texNoise, p.xz*.1+vec2(fGlobalTime*0.017,+fGlobalTime*0.02 )).r*0.5;
float g1 = ground(p, h);
float b1 = box( p - vec3(3,0,0), vec3(1,10,1));
sp1 = min(b1,sp1);
vec2 obu = vec2( sp1, 0.0);
vec2 grn = vec2( g1, 1.0);
return vec3(U(obu,grn),h);
}
vec3 march( vec3 cam, vec3 rd, out vec3 p, float fft, float fftS)
{
float t = 0.0;
for(int i = 0; i < 200; i++)
{
p = cam + rd*t;
vec2 r = map(p,fft,fftS).xy;
t+=r.x;
if(r.x < 0.001)
{
return vec3(r,t);
}
if(t > 20.)
{
return vec3(0, -1,t);
}
}
}
vec3 normal(vec3 p, float fft, float fftS)
{
vec2 c = map(p,fft,fftS).xy;
vec2 e = vec2( 0.01, 0);
return normalize( vec3(
map(p+e.xyy,fft,fftS).x,
map(p+e.yxy,fft,fftS).x,
map(p+e.yyx,fft,fftS).x
) - c.x );
}
float light( vec3 n, vec3 p, vec3 l)
{
return max(0.0, dot( n, normalize( l - p)));
}
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);
float fft = texture(texFFT, 0.2).r;
float fftS = texture(texFFTIntegrated, 0.2).r;
vec3 cam = vec3(
sin(fftS*4)*2.,
1.25+cos( fftS* (0.25+sin(fGlobalTime*0.01)*0.25 ))*0.5,
8);
vec3 target = vec3(0,0.5+cam.y,0);
vec3 p = vec3(0);
vec3 rd = getcam(cam,target,uv,2.0+sin(fftS*3.)*1.85);
vec3 res = march(cam, rd, p, fft, fftS);
float ambient = 0.5;
vec3 light1 = vec3(
sin(fGlobalTime)*10,
10.,
cos(fGlobalTime*0.4)*10
);
vec3 col = vec3(0.);
if(res.y < -0.5)
{
col = vec3(0.25);
}
else if(res.y < 0.5)
{
vec3 n = normal(p, fft, fftS);
vec3 ref = reflect(rd,n);
vec3 pp = vec3( 0);
vec3 rr = march( p+n, ref,pp,fft, fftS);
if( rr.y < -0.5)
{
col += mix(vec3( 0.2, 0.2, 0.7), vec3(0.), sin( 55*p.x+5*p.z +fftS*5. )*cos( 35*p.x+65*p.z +fftS+fGlobalTime ));
}
else if(rr.y < 0.5)
{
vec3 nn = normal(pp,fft, fftS);
vec3 ref2 = reflect(ref,nn);
vec3 ppp = vec3( 0);
vec3 rrr = march( pp+nn, ref2,ppp,fft, fftS);
if( rrr.y < -0.5)
{
col = vec3(0.25);
}
else if(rrr.y < 0.5)
{
col = vec3(0.5);
}
else if(rrr.y < 1.5)
{
col = mix(vec3(1.0,0.6,0.),vec3(0.0,0.0,0.0),ppp.y*3.-fft*150.) * (ambient+light( normal(ppp,fft, fftS), ppp, light1));
}
col = mix( col, vec3(0.4) * (ambient+light( nn, pp, light1)), 0.5);
}
else if(rr.y < 1.5)
{
col = mix(vec3(1.0,0.6,0.),vec3(0.0,0.0,0.0),pp.y*3.-fft*150.) * (ambient+light( normal(pp,fft, fftS), pp, light1));
}
col = mix( col, vec3(0.0) * (ambient+light( n, p, light1)), 0.5);
//col *= vec3(1.0,1.05,1.) * (ambient+light( n, p, light1));
//col = vec3(0.4)*n * (ambient+light( n, p, light1));
}
else if(res.y < 1.5)
{
col = mix(vec3(1.0,0.76,0.),vec3(0.0,0.0,0.0),p.y*5.-fft*150.) * (ambient+light( normal(p,fft, fftS), p, light1));
}
col = mix( col, vec3(0.0,0.05,0.15), smoothstep( 0., 15., res.z));
out_color = vec4(col, 1.0);
}