Matrix

Seven parallax layers of falling-glyph streams over a slowly drifting camera. Each layer runs its own column grid, its own scroll speed, and its own palette offset; depth-fog dims the far ones. The glyphs are a 32-symbol procedural font built out of signed distance fields — bars, crosses, arcs, dots, a smiley, a dog, a heart, a music note, and a couple of random-grid patterns for filler.

Every stream is periodic: each column carries a (streamLen, gapLen) pair, and the y-position is mod(cell.y + speed * time, period) — a seamless tile, so the “infinite” scroll never seams.

[glsl]: shader source
// Multi-layer falling-glyph rain over a drifting camera. Seven parallax
// depths, each with its own column grid and palette offset.
// @slider tempo 0.1 3.0 1.0 0.05
uniform float tempo;

float hash(vec2 p){
  return fract(sin(dot(p, vec2(127.1, 311.7))) * 43758.5453);
}

// smooth stroke — 1 inside a signed distance w, fading to 0 outside
float strokeLine(float d, float w){
  return 1.0 - smoothstep(w - 0.02, w + 0.03, d);
}

// procedural glyph: cellUV in [0,1], seed picks one of 32 shapes
float glyph(vec2 cellUV, float seed){
  vec2 p = cellUV - 0.5;
  float w = 0.065;

  int tt = int(floor(fract(seed * 7.31) * 32.0));
  float s = 0.0;

  if(tt == 0){                                       // vertical bar
    s = strokeLine(abs(p.x), w);
  } else if(tt == 1){                                // horizontal bar
    s = strokeLine(abs(p.y), w);
  } else if(tt == 2){                                // plus
    s = strokeLine(min(abs(p.x), abs(p.y)), w);
  } else if(tt == 3){                                // X cross
    s = strokeLine(min(abs(p.x - p.y), abs(p.x + p.y)) * 0.7071, w);
  } else if(tt == 4){                                // circle
    s = strokeLine(abs(length(p) - 0.28), w);
  } else if(tt == 5){                                // filled dot
    s = 1.0 - smoothstep(0.15, 0.19, length(p));
  } else if(tt == 6){                                // square outline
    float bx = max(abs(p.x), abs(p.y));
    s = strokeLine(abs(bx - 0.28), w);
  } else if(tt == 7){                                // three horizontal bars
    float d = min(min(abs(p.y - 0.22), abs(p.y)), abs(p.y + 0.22));
    s = strokeLine(d, w * 0.55);
  } else if(tt == 8){                                // double vertical bars
    s = strokeLine(min(abs(p.x - 0.14), abs(p.x + 0.14)), w);
  } else if(tt == 9){                                // diamond outline
    float dd = abs(p.x) + abs(p.y);
    s = strokeLine(abs(dd - 0.32), w);
  } else if(tt == 10){                               // asterisk (plus + X)
    float d1 = min(abs(p.x), abs(p.y));
    float d2 = min(abs(p.x - p.y), abs(p.x + p.y)) * 0.7071;
    s = strokeLine(min(d1, d2), w * 0.75);
  } else if(tt == 11){                               // equals
    float d = min(abs(p.y - 0.12), abs(p.y + 0.12));
    s = strokeLine(d, w);
  } else if(tt == 12){                               // top arc
    float cd = abs(length(p) - 0.3);
    s = strokeLine(cd, w) * smoothstep(-0.05, 0.05, p.y);
  } else if(tt == 13){                               // L (bottom-left corner)
    float vert  = strokeLine(abs(p.x + 0.15), w) * step(0.0, p.y);
    float horiz = strokeLine(abs(p.y), w) * step(-0.15, p.x);
    s = max(vert, horiz);
  } else if(tt == 14){                               // reverse-L
    float vert  = strokeLine(abs(p.x - 0.15), w) * step(p.y, 0.0);
    float horiz = strokeLine(abs(p.y), w) * step(p.x, 0.15);
    s = max(vert, horiz);
  } else if(tt == 15){                               // smiley
    float head  = strokeLine(abs(length(p) - 0.35), w * 0.7);
    float eyeL  = 1.0 - smoothstep(0.03, 0.06, length(p - vec2(-0.12, 0.1)));
    float eyeR  = 1.0 - smoothstep(0.03, 0.06, length(p - vec2( 0.12, 0.1)));
    float smile = strokeLine(abs(length(p - vec2(0.0, 0.04)) - 0.16), w * 0.5)
                * step(p.y, 0.04);
    s = max(head, max(max(eyeL, eyeR), smile));
  } else if(tt == 16){                               // dog face
    float head = strokeLine(abs(length(p * vec2(1.0, 1.1)) - 0.24), w * 0.7);
    float earL = 1.0 - smoothstep(0.06, 0.09, length(p - vec2(-0.2, 0.25)));
    float earR = 1.0 - smoothstep(0.06, 0.09, length(p - vec2( 0.2, 0.25)));
    float eyeL = 1.0 - smoothstep(0.02, 0.04, length(p - vec2(-0.09, 0.06)));
    float eyeR = 1.0 - smoothstep(0.02, 0.04, length(p - vec2( 0.09, 0.06)));
    float nose = 1.0 - smoothstep(0.03, 0.05, length(p - vec2( 0.0,  -0.06)));
    float tongue = strokeLine(abs(p.x), w * 0.4) * step(-0.22, p.y) * step(p.y, -0.13);
    s = max(head, max(max(earL, earR), max(max(eyeL, eyeR), max(nose, tongue))));
  } else if(tt == 17){                               // heart (filled)
    vec2 hp = (p + vec2(0.0, 0.35)) * 1.5;
    hp.x = abs(hp.x);
    float hd;
    if(hp.y + hp.x > 1.0){
      hd = length(hp - vec2(0.25, 0.75)) - 0.3536;
    } else {
      float a = length(hp - vec2(0.0, 1.0));
      float b = length(hp - vec2(0.5 * max(hp.x + hp.y, 0.0)));
      hd = min(a, b) * sign(hp.x - hp.y);
    }
    s = 1.0 - smoothstep(-0.02, 0.08, hd);
  } else if(tt == 18){                               // triangle up outline
    vec2 tp = vec2(abs(p.x), p.y + 0.05);
    float tri = max(-tp.y - 0.2, tp.x * 0.866 + tp.y * 0.5 - 0.22);
    s = strokeLine(abs(tri), w);
  } else if(tt == 19){                               // triangle down outline
    vec2 tp = vec2(abs(p.x), -p.y + 0.05);
    float tri = max(-tp.y - 0.2, tp.x * 0.866 + tp.y * 0.5 - 0.22);
    s = strokeLine(abs(tri), w);
  } else if(tt == 20){                               // arrow up
    float stem = strokeLine(abs(p.x), w) * step(p.y, 0.15);
    float chevron = strokeLine(abs(abs(p.x) + p.y - 0.35) * 0.707, w)
                  * step(0.12, p.y) * step(p.y, 0.4);
    s = max(stem, chevron);
  } else if(tt == 21){                               // arrow right
    float stem = strokeLine(abs(p.y), w) * step(p.x, 0.15);
    float chevron = strokeLine(abs(abs(p.y) + p.x - 0.35) * 0.707, w)
                  * step(0.12, p.x) * step(p.x, 0.4);
    s = max(stem, chevron);
  } else if(tt == 22){                               // music note
    float nh = 1.0 - smoothstep(0.08, 0.12, length((p - vec2(-0.05, -0.2)) * vec2(1.0, 1.5)));
    float stem = strokeLine(abs(p.x - 0.07), w * 0.6) * step(-0.2, p.y) * step(p.y, 0.3);
    float flag = strokeLine(abs(length(p - vec2(0.18, 0.2)) - 0.14), w * 0.5)
               * step(0.07, p.x) * step(0.12, p.y);
    s = max(nh, max(stem, flag));
  } else if(tt == 23){                               // crescent moon
    float outer = length(p) - 0.3;
    float inner = length(p - vec2(0.13, 0.0)) - 0.26;
    s = 1.0 - smoothstep(-0.02, 0.04, max(outer, -inner));
  } else if(tt == 24){                               // circle with plus
    float circ = strokeLine(abs(length(p) - 0.28), w * 0.7);
    float pl   = strokeLine(min(abs(p.x), abs(p.y)), w * 0.5);
    s = max(circ, pl);
  } else if(tt == 25){                               // square with cross
    float bx = max(abs(p.x), abs(p.y));
    float sq = strokeLine(abs(bx - 0.3), w * 0.7);
    float cr = strokeLine(min(abs(p.x), abs(p.y)), w * 0.5) * step(bx, 0.33);
    s = max(sq, cr);
  } else if(tt == 26){                               // T
    float vert  = strokeLine(abs(p.x), w) * step(p.y, 0.25);
    float horiz = strokeLine(abs(p.y - 0.25), w);
    s = max(vert, horiz);
  } else if(tt == 27){                               // Z
    float topBar = strokeLine(abs(p.y - 0.25), w);
    float botBar = strokeLine(abs(p.y + 0.25), w);
    float diag   = strokeLine(abs(p.x + p.y) * 0.707, w) * step(abs(p.y), 0.28);
    s = max(max(topBar, botBar), diag);
  } else if(tt == 28){                               // sine wave
    float wave = abs(p.y - 0.15 * sin(p.x * 10.0));
    s = strokeLine(wave, w);
  } else if(tt == 29){                               // bottom arc
    float cd = abs(length(p) - 0.3);
    s = strokeLine(cd, w) * smoothstep(0.05, -0.05, p.y);
  } else if(tt == 30){                               // dense 4×6 hash grid
    vec2 g = floor(cellUV * vec2(4.0, 6.0));
    float on = step(0.4, hash(g + seed * 23.7));
    vec2 f = fract(cellUV * vec2(4.0, 6.0));
    float mask = smoothstep(0.0, 0.18, f.x) * smoothstep(1.0, 0.82, f.x)
               * smoothstep(0.0, 0.18, f.y) * smoothstep(1.0, 0.82, f.y);
    s = on * mask;
  } else {                                           // 3×5 katakana-ish
    vec2 g = floor(cellUV * vec2(3.0, 5.0));
    float on = step(0.45, hash(g + seed * 17.3));
    vec2 f = fract(cellUV * vec2(3.0, 5.0));
    float mask = smoothstep(0.0, 0.15, f.x) * smoothstep(1.0, 0.85, f.x)
               * smoothstep(0.0, 0.15, f.y) * smoothstep(1.0, 0.85, f.y);
    s = on * mask;
  }

  // margin so glyphs never touch cell walls
  float margin = smoothstep(0.0, 0.08, cellUV.x) * smoothstep(1.0, 0.92, cellUV.x)
               * smoothstep(0.0, 0.08, cellUV.y) * smoothstep(1.0, 0.92, cellUV.y);
  return s * margin;
}

void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
  float syncTime = iTime * tempo;
  float beatPulse = exp(-fract(syncTime) * 4.0);

  // cinematic camera drift + tiny rotation
  float camX = syncTime * 15.0 + sin(syncTime * 0.2) * 60.0;
  float camY = sin(syncTime * 0.15) * 30.0 + cos(syncTime * 0.1) * 20.0;
  float angle = sin(syncTime * 0.09) * 0.04;

  vec3 c1 = iAccent;
  vec3 c2 = vec3(0.35, 0.75, 1.00);
  vec3 c3 = vec3(1.00, 0.35, 0.55);
  vec3 c4 = vec3(0.55, 0.25, 0.85);

  vec3 totalColor = vec3(0.0);

  for(int i = 0; i < 7; i++){
    float fi = float(i);
    float depth    = 0.4 + fi * 0.45;
    float invDepth = 1.0 / depth;
    float fog      = 1.0 / (1.0 + fi * 0.5);

    // more columns (smaller glyphs) at farther depths
    float cols  = 14.0 + fi * 4.0;
    float cellW = iResolution.x / cols;
    float cellH = cellW * 1.6;

    // parallax offset + per-layer rotation about screen center
    vec2 offset = vec2(camX, camY) * invDepth;
    float a = angle * invDepth;
    vec2 centered = fragCoord - iResolution.xy * 0.5;
    vec2 rotated = vec2(
      centered.x * cos(a) - centered.y * sin(a),
      centered.x * sin(a) + centered.y * cos(a));
    vec2 fragPos = rotated + iResolution.xy * 0.5 + offset;

    vec2 cell   = vec2(floor(fragPos.x / cellW), floor(fragPos.y / cellH));
    vec2 cellUV = vec2(fract(fragPos.x / cellW), fract(fragPos.y / cellH));

    // per-column stream: length, gap, speed, phase — all hash-derived
    float colSeed = hash(vec2(cell.x, fi * 73.13));
    float speed = (1.5 + colSeed * 2.5) * tempo;
    float phase = colSeed * 100.0;
    float streamLen = 4.0 + colSeed * 8.0;
    float gapLen   = 14.0 + colSeed * 20.0;
    float period   = streamLen + gapLen;
    // seamless tile: y-position wraps every (streamLen + gapLen)
    float cyclePos = mod(cell.y + syncTime * speed + phase, period);

    if(cyclePos >= streamLen) continue;
    float dist = cyclePos;

    // glyph flickers on a hashed clock
    float charSeed = hash(cell + vec2(fi * 37.0, floor(syncTime * (2.0 + colSeed * 3.0) * tempo)));
    float g = glyph(cellUV, charSeed);

    // head white-hot, tail fades quadratically
    float brightness;
    if(dist < 1.0){
      brightness = 1.0;
    } else {
      brightness = max(0.05, 1.0 - (dist - 1.0) / (streamLen - 1.0));
      brightness *= brightness;
    }

    // palette per column, offset per layer
    int colorIdx = int(mod(cell.x + fi, 4.0));
    vec3 baseColor;
    if(colorIdx == 0)      baseColor = c1;
    else if(colorIdx == 1) baseColor = c2;
    else if(colorIdx == 2) baseColor = c3;
    else                   baseColor = c4;

    vec3 neon = baseColor * 1.5;
    vec3 col = dist < 1.0 ? mix(neon, vec3(1.0), 0.7) : neon * brightness;
    totalColor += col * g * fog;
  }

  // beat-ish brightness + filmic tone map
  totalColor *= 1.0 + beatPulse * 0.15;
  totalColor = 1.0 - exp(-totalColor * 1.5);
  fragColor = vec4(totalColor, 1.0);
}
// settings
theme:
fx: