JIT
Grid - Untitled
Matrix digital rain reimagined as viscous liquid chrome and glowing green mercury. The data streams are melting and dripping like heavy syrup, splashing upon contact with the bottom frame. Ripples of neon code distorting the reality behind it. Fluid simulation, metallic texture, reflective surfaces, ray tracing, hypnotic flow, cinematic lighting.
<html lang="en"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Mercury Matrix — Liquid Chrome Rain</title> <style> :root { color-scheme: dark; } html, body { margin: 0; height: 100%; background: radial-gradient(120% 120% at 50% 10%, #04130e 0%, #02070a 50%, #010307 100%); overflow: hidden; } .wrap { position: fixed; inset: 0; display: grid; place-items: center; } canvas { width: 100vw; height: 100vh; display: block; filter: saturate(110%) contrast(105%); } .title { position: fixed; inset: auto 0 2vh 0; text-align: center; font-family: ui-sans-serif, system-ui, -apple-system, Segoe UI, Roboto, Inter, "Helvetica Neue", Arial, "Noto Sans", "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; font-weight: 700; letter-spacing: 0.12em; color: rgba(140, 255, 200, 0.08); font-size: clamp(12px, 1.2vw, 18px); user-select: none; pointer-events: none; text-transform: uppercase; mix-blend-mode: screen; } </style> </head> <body> <div class="wrap"> <canvas id="c"></canvas> <div class="title">Mercury Matrix</div> </div> <script> (function(){ const canvas = document.getElementById('c'); const gl = canvas.getContext('webgl2', { antialias: false, depth: false, stencil: false, premultipliedAlpha: false, powerPreference: 'high-performance' }); if(!gl){ const fallback = document.createElement('div'); fallback.textContent = 'WebGL2 not supported'; fallback.style.cssText = 'color:#9effc9; font: 16px/1.4 monospace; position:fixed; inset:0; display:grid; place-items:center;'; document.body.appendChild(fallback); return; }

const dprCap = 2; let dpr = Math.min(window.devicePixelRatio || 1, dprCap);

function resize(){ dpr = Math.min(window.devicePixelRatio || 1, dprCap); const w = Math.max(1, Math.floor(window.innerWidth * dpr)); const h = Math.max(1, Math.floor(window.innerHeight * dpr)); if(canvas.width !== w || canvas.height !== h){ canvas.width = w; canvas.height = h; gl.viewport(0,0,w,h); } } window.addEventListener('resize', resize, { passive: true }); resize();

const vert = #version 300 es precision highp float; layout(location=0) in vec2 a_pos; out vec2 v_uv; void main(){ v_uv = a_pos*0.5 + 0.5; gl_Position = vec4(a_pos, 1.0); };

const frag = `#version 300 es precision highp float; out vec4 fragColor; in vec2 v_uv;

uniform vec2 u_res; uniform float u_time; uniform float u_dpr;

// Hash & noise helpers float hash11(float p){ vec3 p3 = fract(vec3(p) * 0.1031); p3 += dot(p3, p3.yzx + 33.33); return fract((p3.x + p3.y) * p3.z); } float hash21(vec2 p){ vec3 p3 = fract(vec3(p, p.x+p.y) * 0.1031); p3 += dot(p3, p3.yzx + 33.33); return fract((p3.x + p3.y) * p3.z); } vec2 hash22(vec2 p){ float n = sin(dot(p, vec2(41.2321, 289.133))) * 43758.5453; return fract(vec2(n, n*1.2154)); }

float noise(vec2 x){ vec2 p = floor(x); vec2 f = fract(x); f = ff(3.0-2.0*f); float a = hash21(p); float b = hash21(p + vec2(1.0, 0.0)); float c = hash21(p + vec2(0.0, 1.0)); float d = hash21(p + vec2(1.0, 1.0)); return mix(mix(a,b,f.x), mix(c,d,f.x), f.y); }

// Background "reality" texture: dark, cinematic, with grid and faint code haze vec3 realityBg(vec2 uv){ // Subtle parallax warp to feel like depth behind vec2 p = uv; float vign = smoothstep(1.1, 0.2, length(uv - 0.5) * 1.3); vec3 base = mix(vec3(0.01, 0.03, 0.05), vec3(0.0, 0.06, 0.03), uv.y); // Smart grid vec2 gUv = uv * vec2(1.0, 1.25); vec2 grid = abs(fract(gUv * vec2(32.0, 40.0)) - 0.5); float gridLine = smoothstep(0.49, 0.495, max(grid.x, grid.y)); vec3 gridCol = vec3(0.0, 0.2, 0.11) * gridLine * 0.08;

// Faint falling code haze
vec2 cell = floor(uv * vec2(80.0, 150.0));
float rnd = hash21(cell + floor(u_time*vec2(0.0, 4.0)));
float glow = smoothstep(0.98, 1.0, rnd) * 0.12;
float streak = smoothstep(0.0, 0.02, fract(uv.y*150.0 + rnd*10.0 + u_time*2.5) - 0.98);
vec3 haze = vec3(0.0, 0.9, 0.5) * (glow * streak);

// Diagonal bloom streaks
float diag = pow(max(0.0, 1.0 - abs(sin((uv.x - uv.y*1.2 + u_time*0.02)*20.0))), 6.0) * 0.05;

return base * vign + gridCol + haze + vec3(0.05, 0.12, 0.09) * diag;

}

// Environment map for chrome reflections (fake neon tubes and dark room) vec3 envMap(vec3 r){ // r assumed normalized, use XY for 2D env projection vec2 e = r.xy; float ang = atan(e.y, e.x); float rad = length(e); vec3 env = vec3(0.01, 0.02, 0.03);

// Neon arc
float arc = smoothstep(0.25, 0.0, abs(rad - 0.35));
float arc2 = smoothstep(0.25, 0.0, abs(rad - 0.7));
env += vec3(0.0, 0.9, 0.5) * (pow(max(0.0, arc), 2.0) * 0.4 + pow(max(0.0, arc2), 2.0) * 0.3);

// Vertical tubes
float stripe = smoothstep(0.015, 0.0, abs(fract(e.x * 8.0 - u_time*0.05) - 0.5) - 0.45);
env += vec3(0.2, 1.0, 0.7) * stripe * 0.2;

// Horizontal dim bars
float hbar = smoothstep(0.02, 0.0, abs(fract(e.y * 6.0 + 0.25) - 0.5) - 0.47);
env += vec3(0.03, 0.12, 0.09) * hbar * 0.15;

return env;

}

// Parameters controlling density float colCount(){ // Scale with resolution for consistent density float base = mix(10.0, 24.0, clamp(u_res.x / 1400.0, 0.0, 1.0)); return base; }

// Compute liquid heightfield at uv (0..1). Also returns optional local emissive intensity via out param. float liquidHeight(vec2 uv, out float emissive){ float N = colCount(); float idx = floor(uv.x * N); float h = 0.0; emissive = 0.0;

// Viscous base near bottom pooling
float poolZone = smoothstep(0.22, 0.0, uv.y); // stronger near bottom
h += 0.003 * pow(poolZone, 1.5);

// Neighbor columns sampling (metaball-like blending)
for(int k=-2;k<=2;k++){
  float i = idx + float(k);
  // wrap index to [0,N)
  float iw = mod(i + N*10.0, N);
  float phase = hash11(iw*13.37) * 6.28318;
  float cx = (iw + 0.5)/N;
  // Wobble/wave
  float wob = sin((uv.y*18.0 - u_time*0.7) + iw*1.7) * 0.006;
  cx += wob;

  float speed = mix(0.08, 0.18, hash11(iw*3.17));
  float life = fract(1.0 - u_time*speed + phase*0.1);
  float headY = life * 1.25 + 0.05; // spawn above and drip down

  // radial thickness around column center
  float baseR = mix(0.007, 0.018, hash11(iw*0.73));
  float dx = abs(uv.x - cx);
  // lateral distortion from turbulence
  dx -= (noise(vec2(uv.y*10.0 + iw*0.7, u_time*0.4)) - 0.5) * 0.01;

  // Viscous core and shoulder
  float core = smoothstep(baseR*1.2, 0.0, dx);
  float shoulder = smoothstep(baseR*2.5, baseR*1.2, dx) * 0.5;

  // Vertical extent: below head only (melting trail)
  float trail = smoothstep(0.0, 0.18, headY - uv.y);

  // Drip bulb near head
  float headMask = exp(-pow((uv.y - headY) / (0.03 + baseR*1.2), 2.0));
  float bulb = core * headMask * 0.9;

  // Accumulate height contribution with syrup heaviness
  float local = (core*0.9 + shoulder*0.6) * trail + bulb;
  // Thicken near bottom due to pooling
  local += core * smoothstep(0.08, 0.0, uv.y) * 0.4;

  // Splash ripples near bottom
  float rippleZone = smoothstep(0.22, 0.0, uv.y);
  float r = distance(vec2(uv.x, uv.y*4.0), vec2(cx, 0.0));
  float ripple = sin(r*60.0 - u_time*8.0 + phase) * exp(-r*6.5) * rippleZone * 0.006;

  // Dripping globules separated from main stream (occasional)
  float glob = 0.0;
  if(headY < 1.1){
    float dropPhase = fract(u_time*speed*0.5 + phase);
    float gy = headY - dropPhase * 0.4;
    float gmask = exp(-pow((uv.y - gy)/(0.02 + baseR), 2.0));
    glob = smoothstep(baseR*1.5, 0.0, dx) * gmask * 0.7;
  }

  // Total local thickness
  float th = local * 0.02 + glob * 0.03 + ripple;

  h += th;

  // Emissive glyph glow along column
  // Discretize along y to cells and use random bits per cell
  float cellH = mix(0.012, 0.018, hash11(iw*5.19));
  float row = floor(uv.y / cellH);
  float col = floor((uv.x - cx + 0.5/N) * N * 1.8 + 0.5);
  float rnd = hash21(vec2(iw*37.1 + row, col*11.3));
  float bit = step(0.73, rnd);
  // Flicker
  float flick = 0.7 + 0.3 * sin(u_time*20.0 + iw + row*0.7);
  float glyph = bit * core * trail * flick;

  // Glow falloff from center
  float glowRad = smoothstep(baseR*2.2, 0.0, dx);
  emissive += glyph * glowRad * 0.15;
}

// Clamp to avoid explosion
return clamp(h, 0.0, 0.25);

}

// Compute normals from heightfield vec3 heightNormal(vec2 uv){ float dummy; float e = 1.0 / max(u_res.x, u_res.y); float hC = liquidHeight(uv, dummy); float hX = liquidHeight(uv + vec2(e, 0.0), dummy) - hC; float hY = liquidHeight(uv + vec2(0.0, e), dummy) - hC; vec3 n = normalize(vec3(-hX600.0, -hY600.0, 1.0)); return n; }

void main(){ vec2 uv = v_uv; // Device-pixel aware AA epsilon float px = 1.0 / u_res.x;

// Liquid field
float emi;
float h = liquidHeight(uv, emi);
vec3 n = heightNormal(uv);

// Refraction of background by surface normals
vec2 refractOffset = n.xy * clamp(h*2.5, 0.0, 0.08);
vec3 bg0 = realityBg(clamp(uv + refractOffset, 0.0, 1.0));
vec3 bg1 = realityBg(clamp(uv - refractOffset*0.35, 0.0, 1.0));
vec3 bg = mix(bg0, bg1, 0.25);

// Chrome reflection
vec3 V = normalize(vec3(0.0, 0.0, 1.6));
vec3 N = n;
vec3 R = reflect(-V, N);
float ndv = max(dot(N, V), 0.0);
float fres = pow(1.0 - ndv, 5.0);
vec3 env = envMap(R);

// Specular glints
float gloss = 900.0;
float spec = pow(max(dot(normalize(vec3(0.2, 0.4, 1.0)), N), 0.0), gloss) * 1.4
           + pow(max(dot(normalize(vec3(-0.3, 0.1, 1.0)), N), 0.0), 600.0) * 0.9;

// Base chrome/mercury tone
vec3 chrome = env * (0.35 + 0.65 * fres) + vec3(0.9) * spec * 0.7;

// Glowing mercury-green emissive on streams
vec3 neon = vec3(0.25, 1.0, 0.65) * emi * (0.8 + 0.2 * sin(u_time*10.0));

// Cheap bloom for emissive
float bloom = emi;
for(int i=0;i<8;i++){
  float a = float(i) * 6.28318 / 8.0;
  vec2 o = vec2(cos(a), sin(a)) * (2.5 + float(i))*px*1.8;
  float e2;
  bloom += liquidHeight(uv + o, e2), bloom += e2;
}
bloom = bloom * 0.06;

vec3 col = bg;

// Composite: refracted background under liquid, then reflective chrome, then emissive with bloom
float cover = smoothstep(0.0005, 0.002, h); // presence mask
col = mix(col, col * 0.9 + chrome, cover); // put chrome on liquid
col += neon * 0.8 + vec3(0.15, 0.75, 0.5) * bloom;

// Ripples distort the background even where thin
col = mix(col, col*vec3(0.95,1.02,0.98), clamp(h*12.0, 0.0, 0.35));

// Vignette and grading
float vign = smoothstep(1.3, 0.35, length(uv - 0.5) * 1.2);
col *= vign;

// Grain
float grain = hash21(uv * u_res + u_time)*0.015;
col += grain;

// Tone map
col = col / (col + vec3(1.0));

fragColor = vec4(col, 1.0);

}`;

function createProgram(gl, vs, fs){ function compile(type, src){ const s = gl.createShader(type); gl.shaderSource(s, src); gl.compileShader(s); if(!gl.getShaderParameter(s, gl.COMPILE_STATUS)){ const info = gl.getShaderInfoLog(s); gl.deleteShader(s); throw new Error(info); } return s; } const v = compile(gl.VERTEX_SHADER, vs); const f = compile(gl.FRAGMENT_SHADER, fs); const p = gl.createProgram(); gl.attachShader(p, v); gl.attachShader(p, f); gl.linkProgram(p); if(!gl.getProgramParameter(p, gl.LINK_STATUS)){ const info = gl.getProgramInfoLog(p); gl.deleteProgram(p); throw new Error(info); } gl.deleteShader(v); gl.deleteShader(f); return p; }

const program = createProgram(gl, vert, frag); const loc = { res: gl.getUniformLocation(program, 'u_res'), time: gl.getUniformLocation(program, 'u_time'), dpr: gl.getUniformLocation(program, 'u_dpr') };

// Fullscreen triangle const vao = gl.createVertexArray(); gl.bindVertexArray(vao); const vbo = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, vbo); const tri = new Float32Array([ -1, -1, 3, -1, -1, 3 ]); gl.bufferData(gl.ARRAY_BUFFER, tri, gl.STATIC_DRAW); gl.enableVertexAttribArray(0); gl.vertexAttribPointer(0, 2, gl.FLOAT, false, 0, 0); gl.bindVertexArray(null);

gl.disable(gl.DEPTH_TEST); gl.disable(gl.BLEND);

let start = performance.now(); function frame(t){ const now = performance.now(); const time = (now - start) * 0.001;

resize();
gl.viewport(0,0,canvas.width, canvas.height);
gl.useProgram(program);
gl.bindVertexArray(vao);
gl.uniform2f(loc.res, canvas.width, canvas.height);
gl.uniform1f(loc.time, time);
gl.uniform1f(loc.dpr, dpr);
gl.drawArrays(gl.TRIANGLES, 0, 3);
gl.bindVertexArray(null);
requestAnimationFrame(frame);

} requestAnimationFrame(frame); })(); </script>

</body> </html>_
Updated files
v1