# three-blocks-benchmark

Reproducible Node.js benchmarks for Three Blocks, the official three.js r186
`GaussianSplat` addon, Spark, SuperSplat Viewer 1.31.2, SuperSplat Editor 3.0.0's
renderer, GaussianSplats3D, and Babylon.js.

The default `standard` suite uses fixed held-out cameras from Mip-NeRF 360
Bonsai and a pinned NerfBaselines Graphdeco 30K artifact. The synthetic
`micro` suite is performance-only.

Three Blocks uses its default and only preset, `quality`, at native resolution.
It uses full-precision depth keys and wider Gaussian support cropped at the
fragment alpha threshold. Load, frame time, memory, and image quality all use
that same configuration.

Published results and methodology:
<https://threejs-blocks.com/benchmark/gaussian>

## Run

Run the one-view standard validation from npm:

```sh
npx three-blocks-benchmark --suite standard --quick --output ./benchmark-results
```

Or run it with Bun:

```sh
bunx three-blocks-benchmark --suite standard --quick --output ./benchmark-results
```

Remove `--quick` for the publication run. Publication evidence requires a
physical GPU:

```sh
npx three-blocks-benchmark --suite standard --output ./benchmark-results
```

The standard suite range-downloads and caches only the stored PLY, selected
cameras, ground truth, upstream predictions, and provenance JSON. Use
`--cache <directory>` to choose the cache. The output directory receives local
renderer captures and `benchmark.json`; upstream and ground-truth PNGs stay in
the cache. Use `--omit-captures` for metrics-only output. Standard inputs,
references, and captures must not be redistributed without rights clearance.
The package contains no Bonsai dataset or model bytes; runtime downloads remain
subject to their upstream terms.

Run the generated performance microbenchmarks without network data:

```sh
bunx three-blocks-benchmark --suite micro --quick --output ./micro-results
```

Use `--report <file>` to place the JSON elsewhere and `--scene <id>` to select
a micro scene.
`--revision <value>` and `--dirty` add optional repository metadata; neither
Git nor a checkout is required.

The CLI renders in Node.js through native ANGLE (WebGL) and Dawn (WebGPU).
Publication runs reject software GPU adapters. Memory sampling records the
isolated Node process's RSS after forced GC, outside the load and frame clocks;
these values are not comparable to historical browser heap measurements.

Frame timing directly executes each renderer's frame, without waiting for a display
refresh, and cycles through the three held-out cameras. SuperSplat's complete viewer
tick is driven directly and uses its WebGPU GPU-sort pipeline. Every timed frame
completes its current-camera sort, index upload and GPU draw. GaussianSplats3D
forces a complete visible-set sort and waits for its applied worker result;
Babylon waits for the matching camera sort request to be applied. These are
serial camera-to-image latencies, not pipelined interactive FPS. Worker completion
counts are recorded, and a run fails if any timed frame lacks a complete sort.
Quality captures use a settled camera and are measured separately.

The September 9 timing correction replaces earlier draw-only figures: the tight
loop starved worker-result messages in GaussianSplats3D and Babylon.js. Those
old timings must not be compared with the current complete-frame measurements.
GaussianSplats3D supports SH2 maximum and therefore omits the third band of the
shared SH3 PLY; its effective degree is recorded and labeled on the website.

The Editor 3.0 column runs its verbatim projector, radix sorter and draw shaders
with sorted transparency and fp16 accumulation; it excludes editor UI and the
motion-adaptive stochastic mode. It consumes resident PLY bytes using the
loader's `MemoryReadFileSystem`, so page memory includes the retained source
PLY. This does not reproduce the editor's file-backed memory figures. See
`vendor/README.md` for provenance. The viewer is a separate product and column.

Use `--renderer <id>` for a focused check. A partial run is never labeled
publication evidence. All WebGL2 timings include a 1×1 GPU readback; WebGPU
timings wait for queue completion.

Standard reports contain neutral PSNR and dm_pix-compatible SSIM versus ground
truth. Metrics versus the pinned NerfBaselines Graphdeco 30K prediction are
separately labeled renderer conformance and only verify camera/projection
alignment. The three-view subset is not the canonical 37-view aggregate.
