feat(webgpu-rt): atomic pixel accumulator + raysPerPixel for >1 ray/pixel/bounce (#30)
wfAccum becomes array<atomic<u32>> (4 slots/pixel, f32 bit patterns — same 16 B/pixel footprint) and rtAccumulate CASes each channel, so N rays for one pixel may resolve in the same SHADE pass without the read-modify-write racing. GENERATE clears with atomicStore (bitcast(0.0) == 0u); RESOLVE atomicLoads + bitcasts the vec4 it hands runResolve. Capacity half: RTPass::raysPerPixel (default 1) scales the wavefront ray/hit/payload buffers to raysPerPixel·W·H rays per bounce so the per-light emits actually fit instead of being dropped by rtEmitRay's capacity guard. The accumulator stays per-pixel. No flag-gating: uncontended the CAS succeeds first try — RTStress SHADE stays at its documented ~1.0 ms and master-vs-branch renders are byte-identical, so single-ray consumers pay nothing. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
c58424d519
commit
27d7e84cb3
6 changed files with 89 additions and 19 deletions
|
|
@ -101,7 +101,9 @@ shaded through an intersection shader with an any-hit cut-out.
|
|||
bounce loop (`dispatchWorkgroupsIndirect`). TRACE carries zero user
|
||||
code (traversal + intersection only); user raygen calls
|
||||
`rtEmitPrimaryRay`, and closesthit / miss run in SHADE where they
|
||||
`rtEmitRay` continuation/shadow rays and `rtAccumulate` radiance. An
|
||||
`rtEmitRay` continuation/shadow rays and `rtAccumulate` radiance
|
||||
(atomic — any number of rays per pixel per bounce, e.g. one shadow
|
||||
ray per light). An
|
||||
optional Resolve shader tonemaps the linear accumulator. See
|
||||
[WAVEFRONT-DESIGN.md](WAVEFRONT-DESIGN.md).
|
||||
- **ComputeShader / WebGPUComputeShader** — Tier 1 wrapper used by the
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue