docs: spec WebGL2 Mix visualizer renderer (Phase 10)

Replaces the 1-2 FPS Canvas 2D visualizer with a WebGL2 fragment-shader
renderer. Four-control row, morphing navy/moss field, in-shader glass.
Full spec in product-notes; PLAN.md Phase 10 points at it.
This commit is contained in:
daniel-c-harvey
2026-06-15 11:36:46 -04:00
parent 09f6dc88f7
commit ea8b97e47b
2 changed files with 443 additions and 0 deletions
+14
View File
@@ -178,6 +178,20 @@ Full track decomposition, acceptance criteria, and parallel/dependent analysis:
**Dependency shape:** 8.B is the foundation for the CMS tab work (8.A consumes the shared grid; 8.C/8.E layer on once 8.A lands). 8.L follows 8.G and coordinates with 8.E/8.F (same forms). 8.M (legacy-form retirement) follows 8.L and is architectural (route map + addressing decision). On the public side, 8.H (decided H2 — the new release-cardinal archive) gates 8.I. **All Wave 8 tracks are landed** — Phase-9-completion gate (8.A8.J + 8.L), 8.M, and the post-Phase-9 8.K Mix Visualizer redesign. **Landed tracks:** 8.A, 8.B, 8.C, 8.D, 8.E, 8.F, 8.G, 8.H, 8.I, 8.J, 8.L (2026-06-13); 8.M (2026-06-14); 8.K (2026-06-14).
## Phase 10 — Mix Visualizer WebGL2 Renderer
The landed Canvas 2D Mix visualizer (8.K) renders at 12 FPS and **cannot afford the planned effects** — a staff-engineer analysis found the per-frame killers (full-viewport `shadowBlur`, CSS `backdrop-filter`, per-frame `getBoundingClientRect`) structural to the approach, and the planned effects (bulge, lava-lamp detach, a morphing 2D color field, glass) are all per-pixel/per-frame work — exactly what Canvas 2D is worst at and a fragment shader is best at.
**Decision (Daniel, explicit): rebuild as a WebGL2 fragment-shader renderer. No Canvas 2D stopgap** — "WebGL as step 1, no pussyfooting." This supersedes 8.K §E's Canvas-2D-default recommendation; the "industry-standard, well-commented, no tricks" discipline carries forward as *textbook WebGL2 with a commented shader*. Target a smooth **60 FPS**. Strictly read-only (no playback-control changes); the duration-derived ~333 samples/sec datum (8.K §F) and the existing Blazor↔JS bridge are both preserved — the datum now lands as a GPU texture rather than a CPU-walked array.
Adds a **controls row** above the mix details / below the back button: four continuous, session-persistent sliders — **resolution** (relocated 8.K zoom), **bubblyness** (box→liquid bulge), **detach** ("unleash the lava lamp" — blobs pinch off and rise), **color-shift speed** (gradient morph rate). The headline visual is a living 2D **navy↔moss** gradient field (theme tokens from `DeepDrftPalettes`) that varies per-bar *and* shifts along time, never static; plus an in-shader **glass** treatment (specular/Fresnel/frosted/refraction — no CPU backdrop-filter). Persistence mirrors `MixVisualizerZoomState` (widen to a `MixVisualizerControlState` holding all four).
Full design, renderer architecture, the four effects, acceptance criteria, and phasing: `product-notes/mix-visualizer-webgl-renderer.md`.
**Sequenced as three waves.** Wave 1 (renderer swap at parity — prove WebGL2 on screen at 60 FPS, bridge intact, no new effects) is the load-bearing prerequisite. Wave 2 (controls row + widened state) and Wave 3 (the four effects in the shader) both follow Wave 1; the four effects within Wave 3 are independently shippable and tunable. **Deferred (Daniel):** control-range guards and motion-speed coupling to bubblyness — he tunes bad ranges by hand once on screen.
---
## Working with this file
- **Add items by extending an existing phase first**; only create a new phase when the addition genuinely doesn't fit any of 15. Phase numbers are organisational, not sequencing.