precision highp float; uniform vec2 resolution; uniform float time; #define audioLevel (0.5 + 0.5 * sin(time * 2.0)) #define audioLow (0.5 + 0.5 * sin(time * 1.3)) #define audioMid (0.5 + 0.5 * sin(time * 3.7)) #define audioHigh (0.5 + 0.5 * sin(time * 5.1)) #define PI 3.14159265359 #define TAU (2.0 * PI) #define MAX_STEPS 128 #define MAX_DIST 50.0 #define SURF_DIST 0.001 mat2 rot(float a) { float c = cos(a), s = sin(a); return mat2(c, s, -s, c); } vec3 hsv(float h, float s, float v) { vec3 c = vec3(h, h + 2.0/3.0, h + 1.0/3.0); c = fract(c) * 6.0 - 3.0; c = abs(c) - 1.0; c = clamp(c, 0.0, 1.0); return mix(vec3(1.0), c, s) * v; } float hash(vec2 p) { return fract(sin(dot(p, vec2(127.1, 311.7))) * 43758.5453); } float hash13(vec3 p) { p = fract(p * 0.1031); p += dot(p, p.yzx + 33.33); return fract((p.x + p.y) * p.z); } float noise(vec3 p) { vec3 i = floor(p); vec3 f = fract(p); f = f * f * (3.0 - 2.0 * f); return mix(mix(mix(hash13(i), hash13(i + vec3(1,0,0)), f.x), mix(hash13(i + vec3(0,1,0)), hash13(i + vec3(1,1,0)), f.x), f.y), mix(mix(hash13(i + vec3(0,0,1)), hash13(i + vec3(1,0,1)), f.x), mix(hash13(i + vec3(0,1,1)), hash13(i + vec3(1,1,1)), f.x), f.y), f.z); } float fbm(vec3 p) { float value = 0.0; float amplitude = 0.5; for (int i = 0; i < 6; i++) { value += amplitude * noise(p); p *= 2.0; amplitude *= 0.5; } return value; } float sdBox(vec2 p, vec2 b) { vec2 d = abs(p) - b; return length(max(d, 0.0)) + min(max(d.x, d.y), 0.0); } float sdBox3D(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 sdSphere(vec3 p, float r) { return length(p) - r; } float sdTorus(vec3 p, vec2 t) { vec2 q = vec2(length(p.xz) - t.x, p.y); return length(q) - t.y; } float sdS(vec2 p) { float d = 1e10; float t = 0.03; d = min(d, sdBox(p - vec2(0.0, 0.15), vec2(0.11, t))); d = min(d, sdBox(p - vec2(-0.08, 0.10), vec2(t, 0.08))); d = min(d, sdBox(p - vec2(0.0, 0.0), vec2(0.11, t))); d = min(d, sdBox(p - vec2(0.08, -0.10), vec2(t, 0.08))); d = min(d, sdBox(p - vec2(0.0, -0.15), vec2(0.11, t))); return d; } float sdE(vec2 p) { float d = 1e10; float t = 0.03; d = min(d, sdBox(p - vec2(-0.08, 0.0), vec2(t, 0.18))); d = min(d, sdBox(p - vec2(0.0, 0.15), vec2(0.11, t))); d = min(d, sdBox(p - vec2(0.0, 0.0), vec2(0.08, t))); d = min(d, sdBox(p - vec2(0.0, -0.15), vec2(0.11, t))); return d; } float sdI(vec2 p) { return sdBox(p, vec2(0.03, 0.18)); } float sdO(vec2 p) { return abs(sdBox(p, vec2(0.1, 0.15))) - 0.03; } float sdN(vec2 p) { float d = 1e10; float t = 0.03; d = min(d, sdBox(p - vec2(-0.08, 0.0), vec2(t, 0.18))); d = min(d, sdBox(p - vec2(0.08, 0.0), vec2(t, 0.18))); vec2 rotP = (p - vec2(0.0, 0.0)) * rot(0.45); d = min(d, sdBox(rotP, vec2(t * 1.2, 0.18))); return d; } float drawSESSIONS(vec2 p) { float d = 1e10; float spacing = 0.25; float offset = -spacing * 3.25; d = min(d, sdS(p - vec2(offset, 0.0))); offset += spacing; d = min(d, sdE(p - vec2(offset, 0.0))); offset += spacing; d = min(d, sdS(p - vec2(offset, 0.0))); offset += spacing; d = min(d, sdS(p - vec2(offset, 0.0))); offset += 0.17; d = min(d, sdI(p - vec2(offset, 0.0))); offset += 0.19; d = min(d, sdO(p - vec2(offset, 0.0))); offset += 0.27; d = min(d, sdN(p - vec2(offset, 0.0))); offset += spacing; d = min(d, sdS(p - vec2(offset, 0.0))); return d; } // Snowflake SDF with 6-fold symmetry float sdSnowflake(vec2 p, float size) { // Apply 6-fold radial symmetry float a = atan(p.y, p.x); float r = length(p); a = mod(a, PI / 3.0) - PI / 6.0; p = vec2(cos(a), sin(a)) * r; float d = 1e10; float w = size * 0.08; // branch width // Main branch d = min(d, sdBox(p - vec2(size * 0.4, 0.0), vec2(size * 0.4, w))); // Side branches at different positions vec2 p1 = p - vec2(size * 0.5, 0.0); p1 *= rot(PI / 4.0); d = min(d, sdBox(p1, vec2(size * 0.15, w * 0.8))); vec2 p2 = p - vec2(size * 0.5, 0.0); p2 *= rot(-PI / 4.0); d = min(d, sdBox(p2, vec2(size * 0.15, w * 0.8))); vec2 p3 = p - vec2(size * 0.3, 0.0); p3 *= rot(PI / 3.5); d = min(d, sdBox(p3, vec2(size * 0.12, w * 0.7))); vec2 p4 = p - vec2(size * 0.3, 0.0); p4 *= rot(-PI / 3.5); d = min(d, sdBox(p4, vec2(size * 0.12, w * 0.7))); // Center hexagon float hexA = atan(p.y, p.x); float hexR = length(p); hexA = mod(hexA, TAU / 6.0) - TAU / 12.0; float hexD = hexR * cos(hexA) - size * 0.15; d = min(d, hexD); return d; } // Mandelbulb distance estimator float sdMandelbulb(vec3 pos) { vec3 z = pos; float dr = 1.0; float r = 0.0; float power = 8.0 + audioLow * 4.0; for (int i = 0; i < 8; i++) { r = length(z); if (r > 2.0) break; float theta = acos(z.z / r); float phi = atan(z.y, z.x); dr = pow(r, power - 1.0) * power * dr + 1.0; float zr = pow(r, power); theta = theta * power; phi = phi * power; z = zr * vec3(sin(theta) * cos(phi), sin(phi) * sin(theta), cos(theta)); z += pos; } return 0.5 * log(r) * r / dr; } // Menger sponge float sdMenger(vec3 p) { float d = sdBox3D(p, vec3(1.0)); float s = 1.0; for (int m = 0; m < 3; m++) { vec3 a = mod(p * s, 2.0) - 1.0; s *= 3.0; vec3 r = abs(1.0 - 3.0 * abs(a)); float da = max(r.x, r.y); float db = max(r.y, r.z); float dc = max(r.z, r.x); float c = (min(da, min(db, dc)) - 1.0) / s; d = max(d, c); } return d; } // Scene distance function float sdScene(vec3 p, float sceneTime) { float d = 1e10; // Rotating and morphing shapes vec3 q = p; q.xz *= rot(sceneTime * 0.3 + audioMid * 2.0); q.yz *= rot(sceneTime * 0.5 + audioHigh * 1.5); // Mandelbulb d = min(d, sdMandelbulb(q * 2.0) * 0.5); // Repeating spheres vec3 s = p; s.x = mod(s.x + 1.0, 2.0) - 1.0; s.z = mod(s.z + 1.0, 2.0) - 1.0; d = min(d, sdSphere(s, 0.3 + audioLevel * 0.2)); return d; } vec3 getNormal(vec3 p, float sceneTime) { float d = sdScene(p, sceneTime); vec2 e = vec2(0.001, 0.0); vec3 n = d - vec3( sdScene(p - e.xyy, sceneTime), sdScene(p - e.yxy, sceneTime), sdScene(p - e.yyx, sceneTime) ); return normalize(n); } float rayMarch(vec3 ro, vec3 rd, float sceneTime) { float dO = 0.0; for (int i = 0; i < MAX_STEPS; i++) { vec3 p = ro + rd * dO; float dS = sdScene(p, sceneTime); dO += dS; if (dO > MAX_DIST || abs(dS) < SURF_DIST) break; } return dO; } void main() { // Scene management: 7 scenes × 10 seconds = 70 seconds loop float worldTime = mod(time, 70.0); float TIME = 0.0; float SAM = 0.0; int sceneID = -1; for (int i = 0; i < 7; i++) { TIME = max(TIME, (1.0 - step(SAM + 10.0, worldTime)) * (worldTime - SAM)); sceneID += int(step(SAM, worldTime)); SAM += 10.0; } vec2 uv = (gl_FragCoord.xy * 2.0 - resolution) / resolution.y; vec2 originalUV = uv; vec3 col = vec3(0.0); // === Scene 0: Fractal Tunnel with Wave === if (sceneID == 0) { vec2 p = uv; float zoom = TIME * 0.5 + audioLow * 2.0; for (int i = 0; i < 20; i++) { p = abs(p) / dot(p, p) - vec2(0.9 + audioMid * 0.2, 1.0 + audioHigh * 0.3); } float hue = length(p) * 0.1 + TIME * 0.1 + audioLevel * 0.3; col = hsv(hue, 0.8, 1.0) * (1.0 + audioLevel); // SESSIONS overlay with wave effect float wave = sin(uv.x * 3.0 + TIME * 2.0 + audioMid * 3.0) * (0.02 + audioHigh * 0.05); vec2 waveUV = uv - vec2(0.0, wave); float scale = 1.5 - audioLow * 0.2; float d = drawSESSIONS(waveUV / scale) * scale; vec3 sessColor = hsv(hue + 0.5, 0.8, 1.0); vec3 glow = sessColor * (0.03 / (abs(d) + 0.03)); col += glow * (0.6 + audioLevel * 0.4); col = mix(col, sessColor, smoothstep(0.02, 0.0, d) * 0.5); } // === Scene 1: Volumetric Raymarch with Rainbow Wave === else if (sceneID == 1) { vec3 ro = vec3(0.0, 0.0, -3.0 + sin(TIME * 0.3) * 2.0); vec3 rd = normalize(vec3(uv, 1.0)); float d = rayMarch(ro, rd, TIME); if (d < MAX_DIST) { vec3 p = ro + rd * d; vec3 n = getNormal(p, TIME); vec3 lightPos = vec3(sin(TIME), 2.0, cos(TIME)) * 3.0; vec3 lightDir = normalize(lightPos - p); float diff = max(dot(n, lightDir), 0.0); float hue = 0.5 + sin(p.y * 2.0 + TIME) * 0.3 + audioLevel * 0.2; vec3 baseColor = hsv(hue, 0.7, 0.9); col = baseColor * (diff + 0.3); col += pow(max(dot(reflect(rd, n), lightDir), 0.0), 32.0) * audioHigh; // Fog col = mix(col, vec3(0.0), 1.0 - exp(-d * 0.05)); } // SESSIONS overlay with rainbow wave float bigWave = sin(TIME * 1.5 + audioLow * 2.0) * (0.15 + audioMid * 0.1); vec2 waveUV = uv - vec2(0.0, bigWave); float scale = 1.2 - audioLevel * 0.2; float sessD = drawSESSIONS(waveUV / scale) * scale; float hue = TIME * 0.15 + uv.x * 0.3 + audioLevel * 0.3; vec3 sessGlow = hsv(hue, 0.8, 1.0) * (0.04 / (abs(sessD) + 0.04)); col += sessGlow * (0.7 + audioHigh * 0.5); col = mix(col, hsv(hue, 0.8, 1.0), smoothstep(0.02, 0.0, sessD) * 0.3); } // === Scene 2: Snowflake Storm with Glitch === else if (sceneID == 2) { // Glitch effect on UV vec2 glitchUV = uv; float glitchTime = floor(TIME * 8.0) / 8.0; float glitchStrength = audioHigh * 0.5; if (fract(glitchTime * 3.0) > 0.7 - glitchStrength) { float sliceY = floor(uv.y * 15.0) / 15.0; if (hash(vec2(sliceY, glitchTime)) > 0.7 - audioLevel * 0.3) { glitchUV.x += (hash(vec2(sliceY * 10.0, glitchTime)) - 0.5) * (0.2 + audioHigh * 0.3); } } for (float i = 0.0; i < 100.0; i++) { float seed = i * 0.1; vec3 pos = vec3( sin(TIME * 0.5 + seed * 10.0) * 2.0, cos(TIME * 0.7 + seed * 8.0) * 2.0, mod(TIME * 0.3 + seed * 5.0, 4.0) - 2.0 ); pos.xy += vec2(cos(seed * 50.0), sin(seed * 50.0)) * audioMid; vec2 screenPos = pos.xy / (pos.z + 3.0); vec2 localUV = (uv - screenPos) * (pos.z + 3.0); // Rotate each snowflake float rotation = TIME * 0.3 + seed * TAU; localUV *= rot(rotation); float size = 0.08 + audioHigh * 0.06; float snowflakeDist = sdSnowflake(localUV, size); // Blue-biased hue (cyan to blue range: 0.6-0.66) float hue = 0.62 + seed * 0.02 + TIME * 0.01 + audioLevel * 0.02; // Core snowflake with higher saturation for blue tint col += hsv(hue, 0.9, 1.0) * smoothstep(0.005, 0.0, snowflakeDist) * (1.0 + audioLevel * 2.0); // Glow with bright cyan shift col += hsv(hue + 0.03, 0.85, 0.8) * exp(-snowflakeDist * 20.0) * audioHigh * 0.5; } // SESSIONS text with chromatic aberration glitch float aberration = 0.01 + audioHigh * 0.02; float d = drawSESSIONS(glitchUV / 1.5) * 1.5; vec3 colR = vec3(1.0, 0.0, 0.0) * smoothstep(0.02, 0.0, d); vec3 colG = vec3(0.0, 1.0, 0.0) * smoothstep(0.02, 0.0, drawSESSIONS((glitchUV - vec2(aberration, 0.0)) / 1.5) * 1.5); vec3 colB = vec3(0.0, 0.0, 1.0) * smoothstep(0.02, 0.0, drawSESSIONS((glitchUV - vec2(-aberration, 0.0)) / 1.5) * 1.5); col += (colR + colG + colB) * 0.5; // Random noise glitch if (hash(vec2(originalUV.y * 100.0, glitchTime)) > 0.95 - audioLevel * 0.1) { col = mix(col, vec3(hash(originalUV + glitchTime)), 0.3); } } // === Scene 3: Infinite Grid with FBM and Mosaic === else if (sceneID == 3) { vec3 ro = vec3(0.0, 2.0 + sin(TIME * 0.3) * 1.0, TIME * 2.0); vec3 rd = normalize(vec3(uv * 2.0, -1.0)); // Ground intersection float t = -ro.y / rd.y; if (t > 0.0) { vec3 p = ro + rd * t; // FBM displacement float displacement = fbm(p * 0.5 + vec3(0.0, 0.0, TIME * 0.5)) * 2.0; displacement += audioLow * 0.5; // Grid vec2 grid = fract(p.xz * 2.0); float gridLine = step(0.95, max(grid.x, grid.y)); float hue = displacement * 0.3 + TIME * 0.1 + audioLevel * 0.2; col = hsv(hue, 0.7, 0.8) * (displacement * 0.5 + 0.3); col = mix(col, col * 1.5, gridLine); // Fog col = mix(col, vec3(0.0), 1.0 - exp(-t * 0.1)); } // SESSIONS with mosaic effect float pixelAmount = 20.0 + audioLevel * 30.0; vec2 pixelatedUV = floor(uv * pixelAmount) / pixelAmount; float colorSteps = 4.0 + audioMid * 8.0; vec2 skyUV = pixelatedUV + vec2(0.0, 0.5); float d = drawSESSIONS(skyUV / 1.5) * 1.5; float hue = 0.5 + audioLevel * 0.5; vec3 c = hsv(hue, 0.9, 1.0); vec3 glow = c * (0.03 / (abs(d) + 0.03)); glow = floor(glow * colorSteps) / colorSteps; col += glow * (0.4 + audioHigh * 0.4); vec3 sessColor = mix(col, c, smoothstep(0.02, 0.0, d)); sessColor = floor(sessColor * colorSteps) / colorSteps; // Blend mosaic text with background float textMask = smoothstep(0.02, 0.0, d); col = mix(col, sessColor, textMask * 0.5); // Pixel grid overlay vec2 pixelGrid = fract(uv * pixelAmount); float gridLinePixel = step(0.95, max(pixelGrid.x, pixelGrid.y)); col = mix(col, col * 0.5, gridLinePixel * 0.3); } // === Scene 4: Kaleidoscope with Tiled Pattern === else if (sceneID == 4) { // Background kaleidoscope vec2 p = uv; float a = atan(p.y, p.x); float r = length(p); float segments = 8.0 + floor(audioMid * 8.0); a = mod(a, TAU / segments); a = abs(a - TAU / segments * 0.5); p = vec2(cos(a), sin(a)) * r; // Nested shapes for (int i = 0; i < 10; i++) { p = abs(p); p -= vec2(0.5, 0.3); p *= rot(TIME * 0.5 + audioHigh * 2.0); } float d = drawSESSIONS(p * 2.0) * 0.5; float hue = r * 0.5 + TIME * 0.2 + audioLevel * 0.3; col = hsv(hue, 0.9, 1.0) * (0.05 / (abs(d) + 0.05)); // Tiled SESSIONS overlay float gridSizeX = 1.0; float gridSizeY = 0.4; vec2 gridUV = uv; gridUV.x = mod(gridUV.x + gridSizeX * 0.5, gridSizeX) - gridSizeX * 0.5; gridUV.y = mod(gridUV.y + gridSizeY * 0.5, gridSizeY) - gridSizeY * 0.5; vec2 cellID = floor((uv + vec2(gridSizeX * 0.5, gridSizeY * 0.5)) / vec2(gridSizeX, gridSizeY)); float cellHash = hash(cellID); float cellTime = TIME + cellHash * 3.0; // Wave effect per cell float wave = sin(cellTime * 2.0 + audioMid * 3.0) * (0.03 + audioHigh * 0.05); vec2 waveGridUV = gridUV - vec2(0.0, wave); float scale = 0.45 - audioLow * 0.1; float tileD = drawSESSIONS(waveGridUV / scale) * scale; float tileHue = cellHash + cellTime * 0.1 + audioLevel * 0.3; vec3 cellColor = hsv(tileHue, 0.8, 0.9); vec3 glow = cellColor * (0.02 / (abs(tileD) + 0.02)); col += glow * (0.4 + audioLevel * 0.3); col = mix(col, cellColor, smoothstep(0.015, 0.0, tileD) * 0.3); // Grid lines vec2 gridLine = abs(gridUV); float lineX = smoothstep(gridSizeX * 0.5 - 0.01, gridSizeX * 0.5, gridLine.x); float lineY = smoothstep(gridSizeY * 0.5 - 0.01, gridSizeY * 0.5, gridLine.y); col = mix(col, col * 0.3, max(lineX, lineY) * 0.5); } // === Scene 5: DNA Helix with Matrix Rain === else if (sceneID == 5) { for (float i = 0.0; i < 50.0; i++) { float t = i * 0.1; float z = t * 3.0 - TIME * 2.0; // Only draw if z is in visible range if (z > -2.0 && z < 5.0) { vec3 p1 = vec3(cos(z * 2.0 + audioLow * 2.0) * 0.6, sin(z * 3.0) * 0.3, z); vec3 p2 = vec3(-cos(z * 2.0 + audioLow * 2.0) * 0.6, -sin(z * 3.0) * 0.3, z); // Better projection float depth1 = 3.0 / (p1.z + 3.0); float depth2 = 3.0 / (p2.z + 3.0); vec2 s1 = p1.xy * depth1; vec2 s2 = p2.xy * depth2; float d1 = length(uv - s1); float d2 = length(uv - s2); float bridge = length(uv - mix(s1, s2, 0.5)); float size = (0.03 + audioMid * 0.04) * depth1; float hue = t * 0.5 + TIME * 0.1; // Enhanced visibility col += hsv(hue, 0.8, 1.0) * smoothstep(size, 0.0, d1) * (1.0 + audioHigh * 2.0); col += hsv(hue + 0.5, 0.8, 1.0) * smoothstep(size, 0.0, d2) * (1.0 + audioHigh * 2.0); col += hsv(hue + 0.25, 0.6, 0.7) * smoothstep(size * 0.5, 0.0, bridge) * (0.5 + audioMid * 1.5); // Glow col += hsv(hue, 0.9, 0.5) * exp(-d1 * 5.0) * audioLevel * 0.5; col += hsv(hue + 0.5, 0.9, 0.5) * exp(-d2 * 5.0) * audioLevel * 0.5; } } // Matrix Rain SESSIONS float numLanes = 5.0 + audioLevel * 3.0; for (float i = 0.0; i < 8.0; i++) { if (i >= numLanes) break; float laneX = (i / (numLanes - 1.0)) * 2.4 - 1.2; float speed = hash(vec2(i, 0.0)) * 1.5 + 0.8 + audioMid * 0.5; float yOffset = mod(TIME * speed + hash(vec2(i, 1.0)) * 2.0, 2.5) - 1.2; vec2 p = uv - vec2(laneX, yOffset); float d = drawSESSIONS(p / 0.5) * 0.5; float fade = 1.0 - smoothstep(0.3, 1.0, abs(yOffset)); float hue = 0.33 + audioLevel * 0.2; vec3 color = hsv(hue, 0.7, 1.0); // Trail effect for (float j = 0.1; j < 0.5; j += 0.1) { vec2 trailP = uv - vec2(laneX, yOffset + j); float trailD = drawSESSIONS(trailP / 0.5) * 0.5; float trailFade = (1.0 - j * 2.0) * fade * 0.3; col += color * (0.005 / (abs(trailD) + 0.005)) * trailFade; } col += color * (0.015 / (abs(d) + 0.015)) * fade * (0.4 + audioHigh * 0.4); col = mix(col, color * fade, smoothstep(0.015, 0.0, d) * 0.3); } } // === Scene 6: Kaleidoscope with Recursive SESSIONS === else if (sceneID == 6) { vec2 p = uv; float a = atan(p.y, p.x); float r = length(p); float segments = 8.0 + floor(audioMid * 8.0); a = mod(a, TAU / segments); a = abs(a - TAU / segments * 0.5); p = vec2(cos(a), sin(a)) * r; // Nested shapes for (int i = 0; i < 10; i++) { p = abs(p); p -= vec2(0.5, 0.3); p *= rot(TIME * 0.5 + audioHigh * 2.0); } float d = drawSESSIONS(p * 2.0) * 0.5; float hue = r * 0.5 + TIME * 0.2 + audioLevel * 0.3; col = hsv(hue, 0.9, 1.0) * (0.05 / (abs(d) + 0.05)); // Center recursive SESSIONS vec2 centerP = uv; vec3 accum = vec3(0.0); for (int i = 0; i < 15; i++) { float scale = pow(1.5, float(i)); float rotation = TIME * 0.3 * float(i) + audioMid * 2.0; vec2 q = centerP * scale; q *= rot(rotation); float recurD = drawSESSIONS(q) / scale; float recurHue = float(i) * 0.1 + TIME * 0.1 + audioLevel * 0.2; accum += hsv(recurHue, 0.8, 1.0) * (0.01 / (abs(recurD) + 0.01)) * exp(-float(i) * 0.3); } col += accum * (0.5 + audioLevel * 0.5); } // Chromatic aberration float aberration = audioHigh * 0.01; if (aberration > 0.001) { col *= vec3(0.8, 1.0, 0.8); } // Vignette float vignette = 1.0 - length(originalUV) * 0.3; col *= vignette; // Scanlines col *= 0.95 + 0.05 * sin(originalUV.y * 300.0 + time * 10.0); // Contrast boost col = pow(col, vec3(0.9)); gl_FragColor = vec4(col, 1.0); }