// [FBP] fbp-web · direction: dream · exact wsp.baby fragment shader // Source: https://wsp.baby/_next/static/chunks/4783-9515bda8d152c361.js (module 41577) #ifdef GL_FRAGMENT_PRECISION_HIGH precision highp float; #else precision mediump float; #endif uniform vec2 uRes; // canvas size in device px uniform vec2 uCell; // cell size in device px uniform float uTime; uniform vec2 uMouse; // device px from the top-left (far away = off) uniform sampler2D uAtlas; uniform float uGlyphs; uniform vec3 uColor; uniform vec3 uGround; uniform float uIntensity; uniform float uFade; // 1 = fade the bottom half out uniform float uHeroRows;// rows in the first screen (bars sit at its bottom) uniform sampler2D uSpec; uniform float uLevel; // 0..1 loudness (adaptive) uniform float uBeatAge; // seconds since the last beat (big = none) uniform vec2 uBeatPos; // tap position in device px (far away = none) uniform float uGlow; // cursor glow on/off float hash(vec2 c){ return fract(sin(dot(c, vec2(12.9898, 78.233))) * 43758.5453); } void main(){ vec2 px = vec2(gl_FragCoord.x, uRes.y - gl_FragCoord.y); vec2 cell = floor(px / uCell); vec2 local = fract(px / uCell); vec2 grid = floor(uRes / uCell); float x = cell.x, y = cell.y; // Harmonic wave field with subtle slow vortex drift. float cx = grid.x * 0.5 + sin(uTime * 0.22) * grid.x * 0.08; float cy = grid.y * 0.42 + cos(uTime * 0.17) * grid.y * 0.06; vec2 dv = vec2(x - cx, (y - cy) * 1.85); float d = length(dv); float ang = atan(dv.y, dv.x); float t = uTime; float lift = uLevel * 0.35; float v = sin(x * 0.055 + t * 0.72) + sin(y * 0.13 - t * 0.48) + sin((x + y * 1.7) * 0.036 + t * 0.38) + sin(d * 0.155 - t * (1.42 + uLevel * 0.6) + sin(ang * 2.0 + t * 0.25) * 0.35) * 1.25; v = clamp((v + 4.25 + lift) / 8.5, 0.0, 1.0); v = pow(v, 2.05) * uIntensity; // Bottom fade (the hero's field runs on past the first screen). float fade = 1.0; if (uFade > 0.5) { float k = y / grid.y; fade = k < 0.46 ? 1.0 : pow(max(0.0, 1.0 - (k - 0.46) / 0.54), 1.55); } // Cursor & touch glow + subtle concentric wake ripple. float cursorBoost = 0.0; if (uGlow > 0.5) { vec2 m = uMouse / uCell; vec2 md = vec2(x - m.x, (y - m.y) * 1.85); float md2 = dot(md, md); float mdLen = sqrt(md2); float core = exp(-md2 / 92.0) * 0.92; float wake = sin(mdLen * 0.55 - t * 3.8) * exp(-md2 / 260.0) * 0.18; cursorBoost = max(0.0, core + wake); v = min(1.0, v + cursorBoost); } // Beat / tap pulse ring radiating out from the tap point, not the center. // Distance is measured in cells from uBeatPos so the wave starts at the cursor. if (uBeatAge < 1.6) { vec2 b = uBeatPos / uCell; vec2 bd = vec2(x - b.x, (y - b.y) * 1.85); float bdLen = length(bd); float r = uBeatAge * 46.0; float q = (bdLen - r) / 2.3; float ring = exp(-q * q) * (1.0 - uBeatAge / 1.6); v = min(1.0, v + ring * 0.38); } if (uLevel > 0.001) { float band = pow(x / grid.x, 0.75); float s = texture2D(uSpec, vec2(band, 0.5)).r; float top = uHeroRows - s * uHeroRows * 0.22; if (y > top && y < uHeroRows + 1.0) { float k = 1.0 - (y - top) / max(1.0, uHeroRows - top + 1.0); v = max(v, (0.08 + s * 0.32) * (0.5 + 0.5 * k)); } } v *= fade; // Each cell's letter: brighter cells take denser glyphs; the seed shifts smoothly. float h = hash(cell); float seed = hash(cell + floor(t * 0.035 + h * 13.0)); float g = floor(min(uGlyphs - 1.0, (v * 0.9 + seed * 0.14) * uGlyphs)); float lvl = min(11.0, floor(v * 12.0)) / 11.0; vec3 dim = vec3(0.042, 0.038, 0.078); vec3 mid = uColor * vec3(1.04, 0.96, 1.08); vec3 peak = vec3(0.86, 0.78, 1.0); vec3 col = mix(dim, mid, pow(lvl, 1.05)); col = mix(col, peak, smoothstep(0.68, 1.0, lvl) * 0.52 + cursorBoost * 0.28); float a = texture2D(uAtlas, vec2((g + local.x) / uGlyphs, local.y)).a; gl_FragColor = vec4(mix(uGround, col, a), 1.0); }