Commit a58b6c1
claude:perf: WebGL2 fragment shader for hero rune canvas
Replaces the optimized canvas-2D loop (sprite atlas + bin LUT +
bucketed cells) with a single WebGL2 fragment shader. The visual is
unchanged; the per-frame main-thread cost drops to ~one uniform
write + one drawArrays(6).
Architecture:
- Full-screen quad, one triangle pair. The fragment shader runs per
pixel in parallel on the GPU.
- Glyph atlas: a horizontal 10-char strip of the RAMP rendered in
white into a small offscreen canvas, uploaded once at init. The
shader multiplies by per-cell color, so one texture covers both
inside/outside variants.
- Rune mask: profile.svg rasterized into a runeW × runeH texture at
init + on resize. The shader samples it at the centered sprite
area to decide inside/outside per cell.
- Fragment shader: for each pixel, compute cell coords from
gl_FragCoord + cellSize, evaluate the two-octave radial wave
(sin × sin) for that cell's distance, pick a glyph index, sample
the atlas, sample the rune mask, multiply by white-or-gray.
Texture upload note: UNPACK_FLIP_Y_WEBGL stays off. The shader
already flips gl_FragCoord.y to keep cell math in top-origin /
canvas-2D-compatible coordinates; enabling FLIP_Y on top of that
would double-invert and render the rune (and glyph atlas) upside
down.
Per-frame main-thread cost:
- ~21K cells × ~30 ops + drawImage -> one gl.uniform1f + one
gl.drawArrays(6). All shading parallelized on the GPU.
Falls back to a blank (still functional) hero if WebGL2 is
unavailable; logs a console warning. WebGL2 has ~95%+ global
support including Safari 15+, so this is the agreed tradeoff.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>1 parent c2a83c6 commit a58b6c1
1 file changed
Lines changed: 229 additions & 220 deletions
0 commit comments