Builds and tracing
Every number here says where it was measured. The package has two speed targets, the RTX 3060 Laptop and the Apple M5 Pro. The Intel UHD runs every check for correctness only. Numbers from the Apple M5 are indicative: its clocks drift by up to about 30% within a run, so those benches report ratios taken within one round, not absolute rates.
Method
- Rays: a grid of probes fills the scene's bounds, and each probe fires 256 rays in random directions from a fixed seed. Any-hit rays go from each closest hit toward a fixed direction. The rays are generated once and stored in a buffer, so every tracer gets the same input.
- Timing: GPU timestamps around the trace dispatch, the median of several runs after warm-ups. Without timestamps, a fence-based wall time over 20 dispatches, labelled as such.
- The GPU is loaded and clocks are checked. A run counts only if it started cool, fewer than 5% of its samples were thermally throttled, and it had enough samples ("the clock rule").
- three-mesh-bvh runs as a three
WebGPURenderercompute node reading the same ray buffer, its per-mesh trees built with{ strategy: SAH }explicitly (its default is CENTER). - The pages are
tests/gpu/pages/trace-bench*; results go inbench/results/trace.csv.
Sponza on the RTX 3060 Laptop
5,744,384 triangles in 132 meshes. Headless Chrome 156 on Windows.
three-mesh-bvh's trees converted to our layout traced at 96.7 Mrays/s and took 7.4 s to build, against 101.6 Mrays/s and
5.3 s for tinybvh's, in the same session. These runs predate the 2026-11 levers: instanced trees, f32 nodes.
The 2026-11 levers on the RTX 3060 Laptop
Sponza and Bistro interior surface-ray pages (trace-bench-surface-*), Windows, headless Chrome 157, 2026-11-13, three
runs each. Each lever is timed in paired rounds against the layout before it (instanced, f32 nodes, records, the
40-byte record, anyHitOrder: 'far'), with the order reversed every other round. A figure is the median over the runs of
each run's median-of-rounds ratio; the range covers surface and air rays, instanced and merged trees. Above 1 is faster.
Compact against full record, indexed against records and every any-hit order against far agreed on every ray. No
quantized t differed from the f32 one. Merged against instanced: closest hits named the instanced tree's instance and
triangle on 99.949-99.996% of rays; the rest are near-ties at a shared distance, where the merged walk can pick another
instance or triangle. Any hits blocked exactly the same rays.
On the Apple M5 (indicative)
The variants' trace speed on the M5 (surface-ray pages, paired rounds with the order reversed, against f32 nodes and
records): indexed leaves 0.83-0.99x with vec4 positions and 0.75-0.92x packed; quantized nodes 0.93-0.97x. The 40-byte
hit record measured 0.96-1.15x the 24-byte one.
Not measured yet
- On the RTX 3060: the correctness pages for the 2026-11 work,
SceneTreesmemory and the build-peak cap on D3D12, shader compile times, and quantized nodes and indexed leaves together. quantizedDecode: 'folded'(the folded decode of quantized nodes, opt-in) on any GPU: the surface-ray pages time it against the exact decode (folded_over_exact); it has only passed the correctness pages on SwiftShader.- The Intel UHD has not run the 2026-11 work at all.
- The comparison suite against three-mesh-bvh and others (
compare/) has run on the Apple M5 only.
Reproducing
pnpm test:gpu:page trace-bench-sponza(and the othertrace-bench-*pages, run by exact name) runs a trace bench on the machine's GPU. Sponza and Bistro need their assets; seetests/gpu/README.md.pnpm test:gpu:page scene-trees-sponzareportsSceneTreesload times and memory.node bench/three-raycast.ts,bench/query-parity.tsandbench/closest-point.tsrun the CPU benches in Node.
See also
- Memory: where the bytes go, which this page's rates don't show.
- Comparison with other libraries: the same queries through other libraries.
- Adding a builder from a paper: putting a new builder's rows next to these.