precision mediump float; uniform float time; uniform vec2 resolution; const float pi = acos(-1.); const float pi2 = pi*2.; const float bpm = 120.; mat2 rot(float r) { return mat2(cos(r),sin(r),-sin(r),cos(r)); } vec2 pmod(vec2 p, float r) { float a = atan(p.x,p.y) + pi / r; float n = pi2 / r; a = floor(a/n)*n; return p*rot(-a); } float cube(vec3 p, vec3 s) { p = abs(p) - s; return max(max(p.x,p.y),p.z); } float crosscube(vec3 p, vec3 s) { vec3 v = vec3(1./3.,1./3.,4./3.); float d = cube(p,s*v.xyz); float d2 = cube(p,s*v.yzx); float d3 = cube(p,s*v.zxy); return min(min(d,d2),d3); } float background(vec3 p) { float tbpm = time * bpm / 60.; float seq = floor(tbpm); float count = mod(seq,4.); vec3 q = p; p.z -= tbpm+exp(sin(tbpm*1.6)); p.xy *= rot(0.1*p.z); p.xy *= rot((tbpm*0.1)); p.z = mod(p.z,4.)-2.; p.xy = pmod(p.xy,6.); float d = 1e5; float v = 1.; float scale = 1.1; float sum = scale; for(int i = 0; i < 7; i++) { p.xy = abs(p.xy)-3.; p.xy *= rot(pi*0.25); float td = cube(p,vec3(0.5)*v)/sum; d = min(d,td); v *= 1.1; p *= scale; sum *= scale; } d = max(d,-cube(q,vec3(5.))); return d; } float menger(vec3 p,vec3 s) { vec3 size = s; float d = cube(p,size); float cd = crosscube(p,size); d = max(d,-cd); for(int i = 0; i < 4; i++) { size *= 1./3.; float m = size.x*2.; p = mod(p-0.5*m,m)-0.5*m; cd = crosscube(p,size); d = max(d,-cd); } return d; } float map(vec3 p) { float tbpm = time * bpm / 60.; float seq = floor(tbpm); float count = mod(seq,4.); p.xz *= rot(sin(time)+exp(sin(time))); p.yz *= rot(cos(time)+exp(cos(time))); p.xy *= rot(pi*0.25*seq); if(count == 0.) { p.xy = pmod(p.xy,8.); } if(count == 1.) { p.xy = pmod(p.xy,8.); } if(count == 2.) { p.xy = pmod(p.xy,8.); } if(count == 3.) { p.xy = pmod(p.xy,8.); } vec3 q = p; float d = menger(q,vec3(1.)); float scale = 1.5; float sum = scale; for(int i = 0; i < 5; i++) { q.x = abs(q.x) - 1.; q.y = abs(q.y) - 1.; q.xy *= rot(pi*0.25); float td = menger(q,vec3(0.5))/sum; d = min(d,td); q*=scale; sum*=scale; } return d; } void main() { vec2 p = (gl_FragCoord.xy * 2. - resolution.xy) / min(resolution.x,resolution.y); vec3 cp = vec3(0.,0.,10.); cp.xz *= rot(sin(time*0.1)*0.6); cp.yz *= rot(cos(time*0.2)*0.3); vec3 ta = vec3(0.,0.,0.); vec3 cd = normalize(vec3(ta-cp)); vec3 cu = vec3(0.,1.,0.); vec3 cs = cross(cd,cu); float td = 1.; vec3 ray = normalize(p.x*cs+p.y*cu+cd*td); vec3 col = vec3(0.); float me = 0.; float se = 0.; float d,rl = 0.; float d2 = 0.; vec3 rp = cp; for(int i = 0; i < 128; i++) { d = map(rp); d2 = background(rp); if(d < d2) me += exp(abs(d)*-0.2); if(d > d2) se += exp(abs(d)*-0.2); d = min(d,d2); rl += d; rp = cp + rl * ray; if(d < 0.001) { break; } } col = vec3(0.3,0.6,0.8)*me*0.02; col += vec3(1.,1.1,1.2)*se*0.02; gl_FragColor = vec4(col,1.); }