fix(dashboard): kill parallax size-pop at the z-wrap seam (DeepSeek V4-Pro audit)

4th-model pass (DeepSeek V4-Pro, max reasoning, steered at the GPU numerics the
other 3 didn't audit) found a NEW bug class none of them connected:

The compute pass soft-wraps ALL of pos including z into [-1,1]
(fract(pos*0.5+0.5)*2-1). The vertex shader derived particle depth/size from a
NON-periodic linear function of that wrapped z (depth = 1.7 + z*0.5), so every
time a particle crossed the z=+/-1 seam its depth jumped 2.2 -> 1.2 and its
rendered size ~doubled (1.83x) in a single frame — a continuous popping that
breaks the volumetric-cloud illusion.

Fix: make depth periodic across the seam with sin(z*pi)*0.5 — it's 0 at both
z=+/-1 (size continuous across the wrap) and still sweeps depth over [1.2, 2.2].
Verified continuous: depth(z=+1)=depth(z=-1)=1.7.

(Also fixed a self-inflicted gate catch: the explanatory comment originally
contained a backtick, which terminated the WGSL template literal early and broke
svelte-check — caught by the gate before commit, now ASCII-only.)

svelte-check 0 errors / 967 files. Visual capture still pending a live backend.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Sam Valladares 2026-06-27 15:22:32 -05:00
parent deb3b82134
commit b41b1b90de

View file

@ -174,8 +174,12 @@ fn vs(@builtin(vertex_index) vi: u32, @builtin(instance_index) ii: u32) -> VsOut
);
let c = corners[vi];
let p = parts[ii];
// gentle parallax depth so the cloud reads volumetric
let depth = 1.7 + p.pos.z * 0.5;
// gentle parallax depth so the cloud reads volumetric. NOTE: pos.z is
// soft-wrapped into [-1,1] by the compute pass, so depth MUST be periodic
// across the z=+/-1 seam. A linear (1.7 + z*0.5) made size pop ~1.83x in one
// frame every time a particle wrapped. sin(z*pi) is 0 at both z=+/-1 (depth
// continuous across the seam) and sweeps depth over [1.2, 2.2] in between.
let depth = 1.7 + sin(p.pos.z * 3.14159265) * 0.5;
let sizePx = (2.6 + p.pos.w * 3.4) / depth;
// Position fills the FULL clip box [-1,1]^2 — do NOT divide x by aspect
// (that squashed the field into the center ~56% on 16:9). Roundness comes