Smooth look on WebGPU: WGSL port fed by GPU inputs and CPU overrides (t88 phase 2c)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-27 22:42:12 -04:00
co-authored by Claude Opus 5.5
parent 65054e691b
commit 452b6aed32
26 changed files with 780 additions and 80 deletions
+15 -3
View File
@@ -67,7 +67,7 @@ diff -r /tmp/before /tmp/after
gamepad and world sizes. Screenshots go to
`shots/play/`. Pixel look by default; `python3 test/play.py shots/play smooth` uses the smooth
look.
- `test/t_smooth.py` checks that the WebGL2 smooth look compiles and draws, that it falls back
- `test/t_smooth.py` checks that the WebGPU smooth look compiles and draws, compares legacy at half resolution, and falls back
to pixels cleanly, and that the thermal lens works.
- Run them one at a time. Two headless browsers at once can starve each other, and
`t_smooth.py`'s half-resolution check then fails. `run_all.py` runs them one after the other.
@@ -110,8 +110,8 @@ python3 tools/shot.py shots/silo.png --setup tools/scenes/clear-sky.js \
`tools/scenes/clear-sky.js` clears a flat work area and sets `FLOOR`, `BX`, `BY` and `CAM`. Set
`CAM = [x, y]` to frame the shot.
- The HUD and the cursor previews are hidden unless you pass `--hud` or `--previews`.
- `--renderer webgpu|legacy` selects the pixel renderer (default WebGPU). WebGPU screenshots
fail clearly when no device is available; Smooth still uses WebGL2.
- `--renderer webgpu|legacy` selects the renderer for either look (default WebGPU). WebGPU screenshots
fail clearly when no device is available; Legacy smooth uses WebGL2; WebGPU smooth uses WGSL.
- `test/t_gpu.py` compares the rendered composite against Legacy for ordinary cells, built pieces,
ghosts, fog and all thermal palettes, and checks world replacement, resize, timing and device loss.
World-pixel tests use `worldPixelContext()` to read both stacked canvases. The helper
@@ -233,3 +233,15 @@ CPU. The GPU canvas draws the world; the transparent game canvas holds the exist
The comparison fixture is `tools/scenes/t88-renderer.js`. Capture with `--freeze --zoom 12`
(and 6 or 2), `--viewport 1920x1080`, and each `--renderer`. It includes terrain, water, fire,
magma, fog, a tree, flat/slope belts, screws, pipe, mold, bar and blueprint ghost.
WebGPU Phase 2c: both looks use WebGPU. `test/t_gpu.py` also reads all four smooth input
textures back and compares them against the legacy CPU buffers at zoom 12/6/2 with fog on/off:
classes, sky flags, field bits and geometry tags must match exactly; RGB can differ by one.
The smooth shader retains the legacy nine-tap glow filter and samples field AO at mip level 2.2;
three render passes generate field levels 1-3, including non-power-of-two view sizes.
Only smooth allocates/uploads the back/tree/field overrides and a separate presence mask.
`tools/perf.py` refuses a WebGPU fallback in either look and records WebGPU scale as 1.
The screenshot tool invalidates the shared parallax horizon after scene setup changes `surfY`,
so renderer startup timing cannot change the hills in a comparison. Mip pass references:
[Chrome's porting guide](https://developer.chrome.com/docs/web-platform/webgpu/from-webgl-to-webgpu#mipmap_generation)
and [WebGPU Fundamentals](https://webgpufundamentals.org/webgpu/lessons/webgpu-importing-textures.html#generating-mips-on-the-gpu).