Fixed-point scale of the P2G atomics. WebGPU has no float atomics, so P2G adds round(value × 2^20) as
i32 (order-independent, hence deterministic). Values are in normalised units: mass in "full cells of
1000 kg/m³" (a particle of density ρ weighs ρ/8000), momentum in that mass × m/s. Resolution: 2⁻²⁰ ≈ 1e-6
of a cell's mass. Any node with mass gets velocity p/m: a node with little mass has a noisy velocity, but
G2P weighs it by at most its mass share, so each particle's velocity error stays below ~0.5·27/(2²⁰·m_p)
≈ 1e-4 m/s (no mass threshold, which would leak momentum). Overflow bound: a node channel must stay below 2³¹/2²⁰ = 2048 units, i.e. a node's
mass × speed < 2048 (with speeds capped at maxSpeed = 10 m/s, a cell may hold up to ~200× water).
Conversions saturate (WGSL i32(f32) clamps; the CPU reference clamps too) and sums wrap like i32.
Fixed-point scale of the P2G atomics. WebGPU has no float atomics, so P2G adds
round(value × 2^20)as i32 (order-independent, hence deterministic). Values are in normalised units: mass in "full cells of 1000 kg/m³" (a particle of density ρ weighs ρ/8000), momentum in that mass × m/s. Resolution: 2⁻²⁰ ≈ 1e-6 of a cell's mass. Any node with mass gets velocity p/m: a node with little mass has a noisy velocity, but G2P weighs it by at most its mass share, so each particle's velocity error stays below ~0.5·27/(2²⁰·m_p) ≈ 1e-4 m/s (no mass threshold, which would leak momentum). Overflow bound: a node channel must stay below 2³¹/2²⁰ = 2048 units, i.e. a node's mass × speed < 2048 (with speeds capped atmaxSpeed= 10 m/s, a cell may hold up to ~200× water). Conversions saturate (WGSLi32(f32)clamps; the CPU reference clamps too) and sums wrap like i32.