docs(phase-10-reframe): fold Wave R2 eval into lava spec + PLAN (7th control, flat coalescing fluid, up-and-out collision)

This commit is contained in:
daniel-c-harvey
2026-06-16 12:47:44 -04:00
parent 09309630cb
commit 5fb7d85019
2 changed files with 205 additions and 91 deletions
+6 -4
View File
@@ -207,15 +207,17 @@ A **major reframe of the Mix visualizer's effects, controls, and color model**,
**This supersedes the original Phase 10 (Waves 14) effects/controls/color design**`product-notes/mix-visualizer-webgl-renderer.md` §4 (effects) and §7 (popover-controls) are marked superseded with a pointer to the reframe spec. The renderer *infrastructure* carries forward unchanged.
**The three reframes:**
- **Lava → CPU-physics wax blobs.** Keep the single-pass WebGL2 fragment renderer; add a small CPU-side per-frame physics step modeling ~1632 Lagrangian "wax blobs" (position/velocity/temperature/radius) uploaded as uniforms and blended with `smin` SDF metaballs. The waveform and lava share **the same plane WITH real 2D elastic collision** (blob↔waveform-boundary + blob↔blob) — the waveform pushes the fluid out of its way (read-only authority preserved; the fluid never deforms the waveform). At heat 0 the wax rests at the bottom and only collision moves it (collision always on, independent of heat); at heat max many bubbles rise/morph per second. **Rejected: a full ping-pong FBO Navier-Stokes fluid sim** — a lava lamp is high-viscosity/low-turbulence, the opposite regime; large rewrite for unwanted realism. Deliberate later upgrade only.
- **Lava → CPU-physics wax blobs.** Keep the single-pass WebGL2 fragment renderer; add a small CPU-side per-frame physics step modeling ~1632 Lagrangian "wax blobs" (position/velocity/temperature/radius) uploaded as uniforms and blended with `smin` SDF metaballs. The waveform and lava share **the same plane WITH real 2D elastic collision** (blob↔waveform-boundary + blob↔blob) — the waveform pushes the fluid out of its way (read-only authority preserved; the fluid never deforms the waveform). **Refined by Daniel's Wave R2 eval:** the fluid must read **flat** (an evenly-lit unified body, NOT blobs with bright pointed centers / cone-like radial gradients) and **melt into one fluid** (low viscosity / strong coalescence — "behave more like a fluid," not stiff globs in contact; the slow wax-like *motion* damping and the freely-coalescing *surface* are independent). **Energy-coupled dynamics:** higher heat/energy → **smaller bubbles + more turbulence** (many small lively turbulent bubbles at high heat; fewer, larger, calmer wax at low heat) — the lamp should feel dynamic and fun. At heat 0 the wax rests on the floor and only collision moves it (collision always on, independent of heat); at heat max many small turbulent bubbles rise/morph per second. **Tuning anchor: Daniel's sweet spot is ~20% gravity / ~100% heat** — calibrate defaults/ranges so that combination lands lively. **Rejected: a full ping-pong FBO Navier-Stokes fluid sim** — a lava lamp is high-viscosity/low-turbulence, the opposite regime; large rewrite for unwanted realism. Deliberate later upgrade only.
- **Color → three-color OKLab gradient with three motions.** One source of truth (`DeepDrftPalettes`), no hardcoded hexes. Always A→B linear from the center line outward. Three combined motions: (1) anchors A/B **rotate among three theme colors X/Y/Z** at the rotation-speed control's rate — **OKLab interpolation, never through the rainbow** (the cyan fix is structural, not a tuning dial); (2) per-bar sinusoidal variation **baked at segment entry and fixed as the segment scrolls** — realized by **keying the sinusoid to mix-time** so it travels with the segment by construction (decided 2026-06-16; the explicit ring-buffer alternative is rejected for maintainability); (3) per-bar gradient curve shifts with scroll height (mostly A at bottom → mostly B at top). The static noise/frost texture is **removed** (Daniel: makes the screen look dirty).
- **Controls → six knobs in an inline collapse/expand knob-bar.** Replaces the four: (1) waveform scroll speed [replaces resolution/zoom as a standalone control], (2) gradient rotation speed, (3) lava gravity, (4) lava heat, (5) blob density/size, (6) collision strength (soft→hard). **NOT a popover or drawer — an inline collapse/expand knob-bar** (decided 2026-06-16): an `@if`-guarded **animated flex row of the six `RadialKnob`s** living inline in the controls area, expanding/collapsing **in place** (CSS width/opacity/transform transition) so it reads as the controls collapsing/expanding, not a floating surface. The lava-lamp icon button toggles a bound bool — no MudPopover/MudDrawer. Styled to **match the NowPlaying hero aesthetic** (the session-detail hero overlay — translucent dark glass, overlay-label typography, `Color.Secondary`). Also: overflow-clip the visualizer to the **dynamic footer height** (the player bar changes height minimized/expanded) so visuals stop cleanly above it; the clip line is also the lava rest line.
- **Controls → seven knobs in an inline collapse/expand knob-bar.** Replaces the four: (1) waveform scroll speed [replaces resolution/zoom as a standalone control], (2) gradient rotation speed, (3) lava gravity, (4) lava heat, (5) blob density/size, (6) collision strength (soft mush→hard up-and-out throw), (7) **waveform width** [added in the Wave R2 eval — narrows the waveform band so the lava fluid has more room to move on loud/busy songs; scales the waveform's amplitude→width mapping and its collision boundary]. **NOT a popover or drawer — an inline collapse/expand knob-bar** (decided 2026-06-16): an `@if`-guarded **animated flex row of the seven `RadialKnob`s** living inline in the controls area, expanding/collapsing **in place** (CSS width/opacity/transform transition) so it reads as the controls collapsing/expanding, not a floating surface. The lava-lamp icon button toggles a bound bool — no MudPopover/MudDrawer. Styled to **match the NowPlaying hero aesthetic** (the session-detail hero overlay — translucent dark glass, overlay-label typography, `Color.Secondary`). Also: overflow-clip the visualizer to the **dynamic footer height** (the player bar changes height minimized/expanded) so visuals stop cleanly above it; the clip line is also the lava rest line.
**Plus: redraw the lava-lamp glyph.** The current `DDIcons.LavaLamp` is rejected (Daniel: "form is shit, colors are shit"). Redraw to the classic 1970s silhouette — a wide truncated-cone metal **base**, a bulbous→roundedly-pointed teardrop **glass body**, a small cone **cap** ("offset cones") — with **navy fluid + moss blobs** (the theme's blue+green, faithful to the reference and on-theme) and a neutral/metallic base+cap. Authored in `DeepDrftShared.Client/Common/DDIcons.cs` as inner SVG markup (no `<svg>` wrapper; 24×24 viewBox); body silhouette `currentColor`, the two accent fills are commented literals traced to their `DeepDrftPalettes` source (SVG cannot resolve `var()`).
Heat→intensity and collision soft↔hard transfer functions are **staff-engineer tuning tasks** (endpoints fixed in the spec, formulas not). Full design, the wax-blob model, the collision model, the three-motion color model, the inline knob-bar, the icon redraw, observable acceptance criteria, and phasing: `product-notes/phase-10-mix-visualizer-lava-reframe.md`.
Heat→intensity and collision soft↔hard transfer functions are **staff-engineer tuning tasks** (endpoints fixed in the spec — heat 0 = wax rests on floor / heat max = many small turbulent rising bubbles; collision soft = gentle mush / hard = high-elasticity up-and-out throw, wide range, smooth/no jitter — formulas not). Full design, the wax-blob model, the collision model, the three-motion color model, the inline knob-bar, the icon redraw, observable acceptance criteria, and phasing: `product-notes/phase-10-mix-visualizer-lava-reframe.md`.
**Sequenced as four reframe waves.** `Wave R1 → Wave R2 → (Wave R3 ‖ Wave R4)`. Wave R1 (de-noise + dynamic footer clip + icon redraw) is a cheap unblock for a clean substrate. Wave R2 (wax-blob physics + 2D collision) is the load-bearing prerequisite — prove the lava before the color and the UI. Wave R3 (OKLab three-color gradient, the three motions) and Wave R4 (six controls + NowPlaying-styled inline knob-bar + widened state to six properties + extended bridge handle) both depend on Wave R2 but are independent of each other. **Both prior open Daniel calls are now decided:** controls-UI is an inline collapse/expand knob-bar (not popover/drawer); per-segment color is mix-time-keyed.
**Open / undecided (spec §10):** (a) **pause behavior** — whether the lava keeps convecting while audio is *paused* (lamp "always on") vs. the current freeze-on-pause (rAF gated on `isPlaying`) is an **undecided Daniel call**; default to freeze-on-pause until decided, switching is a localized gating change, not a model change. (b) **Future enhancement (deferred, NOT in R1R4 scope):** a per-control **"auto-modulate" checkbox** that slowly oscillates each knob's value via a low-frequency oscillator so the visualizer drifts on its own — Daniel flagged it as a cool future idea; the knob-bar layout leaves room but nothing builds it now.
**Sequenced as four reframe waves.** `Wave R1 → Wave R2 → (Wave R3 ‖ Wave R4)`. Wave R1 (de-noise + dynamic footer clip + icon redraw) is a cheap unblock for a clean substrate. Wave R2 (wax-blob physics + 2D collision) is the load-bearing prerequisite — prove the lava before the color and the UI. Wave R3 (OKLab three-color gradient, the three motions) and Wave R4 (seven controls — including the new waveform-width knob — + NowPlaying-styled inline knob-bar + widened state to seven properties + extended bridge handle) both depend on Wave R2 but are independent of each other. **Both prior open Daniel calls are now decided:** controls-UI is an inline collapse/expand knob-bar (not popover/drawer); per-segment color is mix-time-keyed.
---