precision mediump float; uniform vec2 resolution; uniform float time; #define EPS 0.0013 #define MAX 9999.0 #define PI 3.14159265359 #define BPM 50.0 #define AO_NUM 4.0 #define MARCHING_NUM 64 #define CAMERA_DEPTH 1.0 #define TUNNEL_END vec3(0.0, 0.0, 50.0) #define ROOM_POS vec3(0.0, 0.0, 60.0) #define FLOOR_CENTER vec3(150.0, 0.0, 0.0) #define COLUMN_CENTER vec3(-150.0, 0.0, 0.0) #define TUNNEL_AREA_MIN vec3(-10.0, -50.0, -10.0) #define TUNNEL_AREA_MAX vec3(10.0, 50.0, 50.0) #define ROOM_AREA_MIN vec3(-10.0, -50.0, 50.0) #define ROOM_AREA_MAX vec3(10.0, 50.0, 70.0) #define FLOOR_AREA_MIN vec3(100.0, -100.0, -100.0) #define FLOOR_AREA_MAX vec3(200.0, 100.0, 100.0) #define COLUMN_AREA_MIN vec3(-200.0, -100.0, -100.0) #define COLUMN_AREA_MAX vec3(-100.0, 100.0, 100.0) #define PHASE0_TIME 0.0 #define PHASE1_TIME 60.0 / BPM * 4.0 + 60.0 / BPM * 0.5 #define PHASE2_TIME 60.0 / BPM * 4.0 * 2.0 + 60.0 / BPM * 0.5 #define PHASE3_TIME 60.0 / BPM * 4.0 * 3.0 + 60.0 / BPM * 0.5 #define PHASE4_TIME 60.0 / BPM * 4.0 * 6.0 + 60.0 / BPM * 0.5 #define PHASE5_TIME 60.0 / BPM * 4.0 * 8.0 + 60.0 / BPM * 0.5 #define PHASE6_TIME 60.0 / BPM * 4.0 * 10.0 + 60.0 / BPM * 0.5 #define PHASE7_TIME 60.0 / BPM * 4.0 * 15.0 + 60.0 / BPM * 0.5 #define PHASE8_TIME 120.0 #define PHASE0_POS vec3(0.0) #define PHASE1_POS vec3(0.0, 0.0, 60.0) #define PHASE2_POS vec3(150.0, 0.0, 0.0) #define PHASE3_POS vec3(-158.0, 0.0, -0.5) #define PHASE4_POS vec3(0.0) #define PHASE5_POS vec3(150.0, 0.0, 0.0) #define PHASE6_POS vec3(-160.0, 0.0, 0.0) #define PHASE7_POS vec3(0.0, 0.0, 45.0) #define PHASE8_POS vec3(0.0, 0.0, 60.0) struct surface { float dist; int id; }; float Hash(float s) { return fract(sin(12.9898 * s) * 43.54); } float Noise(float s) { return (mix(Hash(floor(s)),Hash(ceil(s)),smoothstep(0.0, 1.0, fract(s))) * 2.0 - 1.0); } mat2 Rotate(float t) { return mat2(cos(t), -sin(t), sin(t), cos(t)); } float randomSeed; float Random() { return randomSeed = Hash(randomSeed); } float phase1Frag; float phase2Frag; float phase3Frag; float phase4Frag; float phase5Frag; float phase6Frag; float phase7Frag; float phase8Frag; float Phase1Frag(){ return step(PHASE0_TIME, time) * step(time, PHASE1_TIME); } float Phase2Frag(){ return step(PHASE1_TIME, time) * step(time, PHASE2_TIME); } float Phase3Frag(){ return step(PHASE2_TIME, time) * step(time, PHASE3_TIME); } float Phase4Frag(){ return step(PHASE3_TIME, time) * step(time, PHASE4_TIME); } float Phase5Frag(){ return step(PHASE4_TIME, time) * step(time, PHASE5_TIME); } float Phase6Frag(){ return step(PHASE5_TIME, time) * step(time, PHASE6_TIME); } float Phase7Frag(){ return step(PHASE6_TIME, time) * step(time, PHASE7_TIME); } float Phase8Frag(){ return step(PHASE7_TIME, time) * step(time, PHASE8_TIME); } float phaseTime; float PhaseTime() { return phase1Frag * (time - PHASE0_TIME) + phase2Frag * (time - PHASE1_TIME) + phase3Frag * (time - PHASE2_TIME) + phase4Frag * (time - PHASE3_TIME) + phase5Frag * (time - PHASE4_TIME) + phase6Frag * (time - PHASE5_TIME) + phase7Frag * (time - PHASE6_TIME) + phase8Frag * (time - PHASE7_TIME); } float phaseRate; float PhaseRate() { return phaseTime / (phase1Frag * (PHASE1_TIME - PHASE0_TIME) + phase2Frag * (PHASE2_TIME - PHASE1_TIME) + phase3Frag * (PHASE3_TIME - PHASE2_TIME) + phase4Frag * (PHASE4_TIME - PHASE3_TIME) + phase5Frag * (PHASE5_TIME - PHASE4_TIME) + phase6Frag * (PHASE6_TIME - PHASE5_TIME) + phase7Frag * (PHASE7_TIME - PHASE6_TIME) + phase8Frag * (PHASE8_TIME - PHASE7_TIME)); } int scene; int Scene() { return int( phase1Frag * 2.0 + phase2Frag * 3.0 + phase3Frag * 4.0 + phase4Frag * 1.0 + phase5Frag * 3.0 + phase6Frag * 4.0 + phase7Frag * 2.0 + phase8Frag * 2.0 + 0.1); } float beatTime; float BeatTime() { float scaledTime = time * BPM / 60.0; return floor(scaledTime) + pow(smoothstep(0.0, 1.0, fract(scaledTime)), 20.0); } vec3 cameraPos; vec3 CameraPos() { vec3 shake = vec3(Random(),Random(),Random()) * 0.03; return phase1Frag * (PHASE1_POS + shake * 0.2 + vec3(0.6, 0.3, 0.5) * vec3(Noise(phaseTime * 0.7), Noise(phaseTime * 0.3), Noise(phaseTime * 0.4))) + phase2Frag * (PHASE2_POS + shake) + phase3Frag * (PHASE3_POS + shake * (4.0, 2.0, 1.0)) + phase4Frag * (PHASE4_POS + shake * 0.4 + vec3(0.1 * Noise(phaseTime * 2.7), 0.1 * Noise(phaseTime * 2.3), 0.1 * Noise(phaseTime * 2.4) + (phaseTime - 5.8) * 0.5) * smoothstep(5.8, 7.0, phaseTime)) + phase5Frag * (PHASE5_POS + shake + 3.0 * vec3(0.0,0.0,phaseTime) + shake + vec3(5.6, 7.3, 8.5) * vec3(Noise(phaseTime * 0.7), Noise(phaseTime * 0.3), Noise(phaseTime * 0.4))) + phase6Frag * (PHASE6_POS + shake + vec3(0.0,0.0,phaseTime) + shake + vec3(0.6, 0.3, 0.5) * vec3(Noise(phaseTime * 0.7), Noise(phaseTime * 0.3), Noise(phaseTime * 0.4))) + phase7Frag * ( ((PHASE7_POS + shake * 0.4 + smoothstep(5.0, 10.0, phaseTime) * vec3(9.0, 9.0, 2.0) * vec3(Noise(phaseTime * 0.3 + 9.0), Noise(phaseTime * 0.2 + 15.0), Noise(phaseTime * 0.4 + 12.0)) + vec3(0.0, 0.0, mix(phaseTime, 5.0 + phaseTime * 0.2, smoothstep(5.0, 6.0, phaseTime)))) * (1.0 - smoothstep(0.8, 1.0, phaseRate)) + smoothstep(0.8, 1.0, phaseRate) * ROOM_POS) ) + phase8Frag * PHASE8_POS; } vec3 cameraDir; vec3 CameraDir() { return phase1Frag * normalize(ROOM_POS + vec3(0.0, 0.0, 1.0) - cameraPos) + phase2Frag * normalize(vec3(-0.3,-0.5,1.)) + phase3Frag * normalize(vec3(0.4,0.0,1.)) + phase4Frag * normalize(vec3(0.,0.,1.)) + phase5Frag * normalize(vec3(0.,0.,1.)) + phase6Frag * normalize(vec3(0.,0.,1.)) + phase7Frag * (normalize(ROOM_POS - cameraPos + EPS) * (1.0 - smoothstep(0.8, 1.0, phaseRate)) + smoothstep(0.8, 1.0, phaseRate) * normalize(vec3(0.,0.,1.))) + phase8Frag * normalize(vec3(0.,0.,1.)); } vec3 cameraUp; vec3 CameraUp() { return mix(vec3(0.0, 1.0, 0.0), vec3(-0.5, 1.0, -0.1), phase5Frag); } vec3 cameraSide; vec3 CameraSide() { return -cross(cameraDir,cameraUp); } vec3 HSV2RGB(float h, float s, float v) { vec4 t = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0); vec3 p = abs(fract(vec3(h) + t.xyz) * 6.0 - vec3(t.w)); return v * mix(vec3(t.x), clamp(p - vec3(t.x), 0.0, 1.0), s); } 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); } vec2 FoldRotate(vec2 p, float s) { float t = PI * 2.0 / s; float a = -atan(p.x, p.y) + PI / 2.0 + t / 2.0; a = mod(a, t) - t / 2.0; a = abs(a); return length(p) * vec2(cos(a), sin(a)); } surface Sponge(vec3 p0, float foldXY, float foldYZ, float offset) { vec4 p = vec4(p0, 1.0); int id = int(Hash(floor((p0.y * 0.5 + 0.5) * 3.0)) * 3.0); for (int n = 0; n < 3; n++) { p.xy = FoldRotate(p.xy, foldXY); p.yz = FoldRotate(p.yz, foldYZ); p = abs(p); p *= 3.0; p.xyz -= 2.0; p.z += 1.0; p.z = abs(p.z); p.z -= 1.0; } return surface(Box(p.xyz, vec3(1.0)) / p.w + offset, id); } surface Map(vec3 p) { float t = step(TUNNEL_AREA_MIN.x, p.x) * step(TUNNEL_AREA_MIN.y, p.y) * step(TUNNEL_AREA_MIN.z, p.z) * step(p.x, TUNNEL_AREA_MAX.x) * step(p.y, TUNNEL_AREA_MAX.y) * step(p.z, TUNNEL_AREA_MAX.z); float r = step(ROOM_AREA_MIN.x, p.x) * step(ROOM_AREA_MIN.y, p.y) * step(ROOM_AREA_MIN.z, p.z) * step(p.x, ROOM_AREA_MAX.x) * step(p.y, ROOM_AREA_MAX.y) * step(p.z, ROOM_AREA_MAX.z); float f = step(FLOOR_AREA_MIN.x, p.x) * step(FLOOR_AREA_MIN.y, p.y) * step(FLOOR_AREA_MIN.z, p.z) * step(p.x, FLOOR_AREA_MAX.x) * step(p.y, FLOOR_AREA_MAX.y) * step(p.z, FLOOR_AREA_MAX.z); float c = step(COLUMN_AREA_MIN.x, p.x) * step(COLUMN_AREA_MIN.y, p.y) * step(COLUMN_AREA_MIN.z, p.z) * step(p.x, COLUMN_AREA_MAX.x) * step(p.y, COLUMN_AREA_MAX.y) * step(p.z, COLUMN_AREA_MAX.z); float x = mix(4.0, 4.0 + sin(beatTime), t + r); float y = mix(4.0, 8.0 + 3.0 * cos(beatTime), t + r); float z = mix(0.0, abs(Noise(phaseTime * 0.5)) * 0.03, t + r); z = mix(z, abs(Noise(phaseTime * 0.5)) * 0.03, c); z = mix(z, smoothstep(0.4, 0.0, phaseTime * 0.2 + 0.2) , phase1Frag); z = mix(z, smoothstep(0.4, 0.0, phaseTime * 0.2) , phase2Frag); z = mix(z, smoothstep(0.4, 0.0, (phaseTime * 0.2 + 0.05) * step(0.0, p.z) * step(p.z, 3.0)) * smoothstep(0.4, 0.0, (phaseTime * 0.2 - 0.2) * step(3.0, p.z) * step(p.z, 6.0)) * smoothstep(0.4, 0.0, (phaseTime * 0.2 - 0.45) * step(6.0, p.z) * step(p.z, 9.0)) * smoothstep(0.4, 0.0, (phaseTime * 0.2 - 0.7) * step(9.0, p.z) * step(p.z, 12.0)), step(PHASE2_TIME, time) * step(time, PHASE3_TIME) ); z = mix(z, smoothstep(0.4, 0.0, phaseTime * 0.2 + 0.05) , phase4Frag); //Tunnel p.z = mix(p.z, mod(p.z, 2.0) - 1.0, t); p.xy = mix(p.xy, FoldRotate(p.xy, 10.0 + 4.0 * Noise(2.0 + beatTime)), t); p.x -= mix(0.0, (2.0 + 0.5 * Noise(beatTime)), t); //Room p -= mix(vec3(0.0), ROOM_POS, r); p.xy = mix(p.xy, FoldRotate(p.xy, 12.0), r); p.xz = mix(p.xz, FoldRotate(p.xz, 12.0), r); p.x -= mix(0.0, 3.5, r); //Floor p.y = mix(mix(p.y, abs(p.y), f), p.y, phase5Frag) ; p.y -= mix(0.0, 10.0, f); vec2 s = mix(floor((p.xz - mod(p.xz, 2.0))), floor((p.xz - mod(p.xz, 3.5))),phase5Frag); p.xz = mix(mix(p.xz, mod(p.xz, 2.0) - 1.0, f), mod(p.xz, 3.5) - 1.75, phase5Frag); p.y += mix(mix(0.0, 3.0 * Noise((Hash(s.y) + Hash(s.x)) * 20.0 + beatTime) * 2.0 + (Hash(s.y) + Hash(s.x)), f), 0.0, phase5Frag); p.y += mix(0.0, -(Hash(s.y) * Hash(s.x)) * 100.0 + 10.0 + 30. * (Hash(s.y) * Hash(s.y + 0.5) * Hash(s.x) * Hash(s.x + 0.5)) * phaseTime, phase5Frag); p.xz = mix(p.xz, Rotate((Hash(s.y) * Hash(s.x)) * 3.0 * beatTime) * p.xz, phase5Frag); p.xy = mix(p.xy, Rotate((Hash(s.y) + Hash(s.x)) * 3.0 * beatTime) * p.xy, phase5Frag); z = mix(z, smoothstep(0.4, 0.0, (phaseTime + 30.0 + (Hash(s.y) * Hash(s.x)) * 40.0 - 40.0) * 0.2) , phase5Frag); //Column p -= mix(vec3(0.0), COLUMN_CENTER, c); float s1 = floor(p.z - mod(p.z, 3.0)); p.x += mix(0., Hash(s1) * 60.0 - 30.0, phase6Frag); p.xy = mix(p.xy, Rotate(PI * Hash(2.4 + s1)) * p.xy, c); p.y = mix(p.y, mod(p.y, 2.0) - 1.0, c); p.z = mix(p.z, mod(p.z, 3.0) - 1.5, c); p *= mix(1.0, 0.5 * (sin(beatTime * PI * 2.0) * 0.5 + 0.5) + 0.5, phase6Frag); return Sponge(p, x, y, z); } vec3 Normal(vec3 p) { vec2 e = vec2(1.0, -1.0) * 0.5773 * EPS; return normalize( Map(p + e.xyy).dist * e.xyy + Map(p + e.yyx).dist * e.yyx + Map(p + e.yxy).dist * e.yxy + Map(p + e.xxx).dist * e.xxx ); } float AO(vec3 p, vec3 n) { float l = EPS; float h = 0.0; vec3 p2 = p; float s = 1.0; for(float i = 0.0; i < AO_NUM; i++) { p2 = p + l * n; l += EPS * 40.0; h += abs(l - Map(p2).dist) * s; } h = 1.0 - clamp(h, 0.0, 1.0); return pow(h, 2.5) * 2.0; } void RayMarch(vec2 c, inout vec3 color) { float d = 0.0; vec3 r = normalize(cameraSide * c.x + cameraUp * c.y + cameraDir * CAMERA_DEPTH); vec3 p0 = cameraPos; vec3 p = p0; float l = 0.0; float ml = 50.0; for(int i = 0; i < MARCHING_NUM; i++) { surface s = Map(p); d = s.dist; color += 0.001 / s.dist * HSV2RGB(beatTime, 0.6, 1.0); if(l > ml)break; if(abs(d) < EPS) { vec3 n = Normal(p + vec3(EPS, 0.0, 0.0)); vec3 nx = Normal(p + vec3(EPS, 0.0, 0.0)); vec3 ny = Normal(p + vec3(0.0, EPS, 0.0)); vec3 nz = Normal(p + vec3(0.0, 0.0, EPS)); vec3 ec = HSV2RGB(beatTime, 1.0, 1.0) * abs(sin(phaseTime * 3.0 + p.z)); vec3 sc = s.id == 0 ||s.id == 1 ? vec3(0.7, 0.3,0.2) : vec3(0.95, 0.9, 0.75); sc *= AO(p,n); color = length(nx - ny) > EPS || length(ny - nz) > EPS || length(nz - nx) > EPS ? ec : sc; //color = sc; color *= time > PHASE3_TIME ? 1.0 - HSV2RGB(n.x * n.y * n.z * 10.0, 0.7, 0.7) * smoothstep(0.9, 1.0, abs(sin(time * 1.5 + p.z))) : vec3(1.0); color += HSV2RGB(Hash(p.y + phaseTime), 1.0, Hash(Hash(p.x + phaseTime) + p.z / 100.0) - 0.5); break; } l += mix(mix(mix(mix(d, min(min((2.0 * step(0.0, r.x) - mod(p.x, 2.0)) / r.x, (2.0 * step(0.0, r.z) - mod(p.z, 2.0)) / r.z) + EPS, d), phase2Frag), min((3.0 * step(0.0, r.z) - mod(p.z, 3.0)) / r.z + EPS, d), step(PHASE2_TIME, time) * step(time, PHASE3_TIME)), min(min((3.5 * step(0.0, r.x) - mod(p.x, 3.5)) / r.x, (3.5 * step(0.0, r.z) - mod(p.z, 3.5)) / r.z) + EPS, d), phase5Frag), min((3.0 * step(0.0, r.z) - mod(p.z, 3.0)) / r.z + EPS, d), phase6Frag); p = p0 + r * l; } return; } void Glitch(vec2 uv, float threshold, inout vec3 color) { for(float i = 0.0; i < 2.0; i++) { uv = (uv * 3.0 + 20.0); float r = Noise(uv.x * Hash(uv.y) + Random()) * 0.5 + 0.5; color *= r > threshold ? vec3(1.0) : HSV2RGB(Hash(r), 1.0, 1.0) * 2.0; } } void PostEffect(vec2 uv, inout vec3 color) { Glitch(uv * vec2(0.2, 0.0002), 0.5 * step(time, PHASE1_TIME) * step(PHASE1_TIME - 0.6, time), color); Glitch(uv * vec2(0.2, 0.0002), 0.5 * step(time, PHASE2_TIME) * step(PHASE2_TIME - 0.5, time), color); Glitch(uv * vec2(0.2, 0.0002), 0.5 * step(time, PHASE3_TIME) * step(PHASE3_TIME - 0.5, time), color); Glitch(uv * vec2(0.2, 0.0002), 0.5 * step(time, PHASE4_TIME) * step(PHASE4_TIME - 0.5, time), color); Glitch(uv * vec2(0.2, 0.0002), 0.5 * step(time, PHASE5_TIME) * step(PHASE5_TIME - 0.5, time), color); Glitch(uv * vec2(0.2, 0.0002), 0.5 * step(time, PHASE6_TIME) * step(PHASE6_TIME - 0.5, time), color); color *= 1.0 - smoothstep(0.4, 0.8, length(uv- vec2(0.5))); } void main() { randomSeed = Hash(time); phase1Frag = Phase1Frag(); phase2Frag = Phase2Frag(); phase3Frag = Phase3Frag(); phase4Frag = Phase4Frag(); phase5Frag = Phase5Frag(); phase6Frag = Phase6Frag(); phase7Frag = Phase7Frag(); phase8Frag = Phase8Frag(); phaseTime = PhaseTime(); phaseRate = PhaseRate(); scene = Scene(); beatTime = BeatTime(); cameraPos = CameraPos(); cameraDir = CameraDir(); cameraUp = CameraUp(); cameraSide = CameraSide(); vec2 r=resolution.xy; vec2 c=(gl_FragCoord.xy * 2.0-r)/min(r.x,r.y); vec3 color = HSV2RGB(Hash(c.y + phaseTime), Hash(c.y + phaseTime), Hash(Hash(c.x + phaseTime) + c.x / 100.0) - 0.5) + vec3(0.0, 0.15, 0.25); RayMarch(c, color); vec2 uv = gl_FragCoord.xy/r; PostEffect(uv, color); gl_FragColor=vec4(color, 1); }