facett-map3d-flight/.nornir/assets/scatter-lut-gpu.svg
<svg xmlns="http://www.w3.org/2000/svg" width="900" height="330" viewBox="0 0 900 330" font-family="monospace" font-size="12">
<rect width="900" height="330" fill="#0e1116"/>
<text x="20" y="30" fill="#e6edf3" font-size="15" font-weight="bold">facett-map3d-flight · GPU scattering-LUT precompute (FLIGHT-SIM #7)</text>
<defs>
<marker id="a" markerWidth="9" markerHeight="9" refX="7" refY="3" orient="auto">
<path d="M0 0 L7 3 L0 6 z" fill="#6fd3f5"/>
</marker>
</defs>
<!-- pipeline boxes -->
<g stroke="#6fd3f5" fill="#12313a">
<rect x="20" y="70" width="150" height="56" rx="6"/>
<rect x="215" y="70" width="160" height="56" rx="6"/>
<rect x="420" y="70" width="150" height="56" rx="6"/>
<rect x="615" y="70" width="150" height="56" rx="6"/>
<rect x="800" y="70" width="80" height="56" rx="6"/>
</g>
<g fill="#e6edf3" text-anchor="middle">
<text x="95" y="92">LutParams</text><text x="95" y="110" fill="#8fb3c0">h·mu·steps</text>
<text x="295" y="92">cs_transmittance</text><text x="295" y="110" fill="#8fb3c0">compute · ray-march</text>
<text x="495" y="92">storage buffer</text><text x="495" y="110" fill="#8fb3c0">array<vec4<f32>></text>
<text x="690" y="92">readback + upload</text><text x="690" y="110" fill="#8fb3c0">→ Rgba32Float tex</text>
<text x="840" y="90">sky.wgsl</text><text x="840" y="106" fill="#8fb3c0">seam</text>
</g>
<g stroke="#6fd3f5" fill="none" marker-end="url(#a)">
<line x1="170" y1="98" x2="211" y2="98"/>
<line x1="375" y1="98" x2="416" y2="98"/>
<line x1="570" y1="98" x2="611" y2="98"/>
<line x1="765" y1="98" x2="796" y2="98"/>
</g>
<text x="840" y="140" fill="#7f8b98" text-anchor="middle" font-size="10">(deferred wiring)</text>
<!-- CPU oracle -->
<rect x="215" y="185" width="160" height="66" rx="6" stroke="#8fd18f" fill="#132a13"/>
<text x="295" y="208" fill="#8fd18f" text-anchor="middle" font-weight="bold">atmos.rs (CPU)</text>
<text x="295" y="226" fill="#e6edf3" text-anchor="middle">TransmittanceLut</text>
<text x="295" y="242" fill="#8fb3c0" text-anchor="middle">::precompute — the ORACLE</text>
<path d="M295 185 L295 128" stroke="#8fd18f" fill="none" stroke-dasharray="4 3"/>
<text x="295" y="165" fill="#8fd18f" text-anchor="middle" font-size="10">same march, same constants</text>
<!-- parity gate -->
<rect x="420" y="185" width="345" height="66" rx="6" stroke="#f2b84b" fill="#2a2410"/>
<text x="592" y="208" fill="#f2b84b" text-anchor="middle" font-weight="bold">parity_vs(cpu) — GPU-less-safe proof</text>
<text x="592" y="226" fill="#e6edf3" text-anchor="middle">max_err_upper (μ≥0) < 5e-4 · outliers ≤ h+2</text>
<text x="592" y="242" fill="#8fb3c0" text-anchor="middle">horizon-tangent knife-edge confined below μ=0</text>
<path d="M495 126 L495 183" stroke="#f2b84b" fill="none" stroke-dasharray="3 3"/>
<path d="M375 218 L418 218" stroke="#f2b84b" fill="none" marker-end="url(#a)"/>
<text x="20" y="300" fill="#8fb3c0" font-size="11">no adapter → test self-skips with a recorded sentinel; the CPU oracle stays the render fallback + RED-when-broken check (runs anywhere).</text>
<text x="20" y="318" fill="#7f8b98" font-size="11">behind the `wgpu` feature · L2 additive: the landed 21-pass pipeline is untouched.</text>
</svg>