@bitruvius/splats
v0.3.1
Published
Bitruvius Gaussian-splat renderer: EWA splatting, spherical harmonics, depth-sorted WebGL2
Readme
@bitruvius/splats
The WebGL2 Gaussian-splat renderer behind the Bitruvius SDK: EWA splatting, spherical harmonics, depth-sorted.
Internal building block. This package exists so that
@bitruvius/sdk-maplibreand the Bitruvius codecs can resolve their dependencies on npm. It has no standalone product story. Unless you are deliberately building against it, install the SDK instead.
Why it is a separate package
Two halves of the SDK sit on opposite sides of a hard line: the codecs that turn bytes into splats, and the GL code that draws them. This package is the second half, and it is separate so the line holds.
The codecs must not pull in WebGL. They run in workers and are tested
headless. @bitruvius/tiles3d, the streaming engine that produces splat tiles,
does not depend on this package at all. When the global splat texture is
momentarily full, Tiles3DSplatRenderer throws SplatTextureFullError and the
engine recognizes it by error.name, treats it as transient backpressure and
retries after eviction. Backpressure crosses the seam without a dependency edge.
Several layers need the same renderer. The BVC, SPZ and single-model layers
draw standalone assets through SplatRenderer; the streaming 3D Tiles splat
layer drives Tiles3DSplatRenderer. None of them should depend on each other, so
the renderer has to sit below all of them. The point-cloud and mesh layers import
from here too, but only for Tiles3DBoundsRenderer, the OBB debug wireframe: it
now lives in @bitruvius/render-runtime, and this package re-exports it so those
imports keep resolving.
The renderer is viewer-agnostic, and that only stays true outside the viewer
package. SplatRenderer implements @bitruvius/geo-core's Renderer
contract and is driven through a ViewerAdapter:
export class SplatRenderer implements Renderer<DecodedSplatTile>, FootprintShadowCasterNothing in it knows about MapLibre. The same instance would run under a different adapter unchanged.
What is in it
Two renderers. SplatRenderer draws one decoded tile at a time against the
Renderer contract, for standalone assets. Tiles3DSplatRenderer is the
streaming path: one global texture pair, a first-fit row allocator, an
off-thread global depth sort, LOD-adaptive dilation, the tuned tone stack, clip
planes, vector drape, shadows and an exact-position pick pass.
Parity math, unit-tested. covariance, sh, packing and resort are
readable CPU references, and the GLSL ports them verbatim. The tests are the
oracle the shaders are held to, which is why @bitruvius/bvc pulls this package
in as a dev dependency: its decoder tests pack real output through
packPositions / packAttribs / packSh to prove it lands in the layout the
shader reads.
The GLSL, and the texture-layout constants (SPLATS_PER_ROW, TEX_W,
SH_TEX_W, MAX_SPLATS, TEXTURE_SAFE_SPLATS) that are the fixed packing
contract between producer and renderer.
The sort worker chunk. tiles3d-sort-worker.ts is published as its own chunk
so the global depth sort does not run on the render thread. Where it cannot be
spawned the renderer keeps sorting synchronously and warns once, rather than
letting the draw order go stale. A cross-origin CDN page cannot call
new Worker(cdnUrl), so the CDN build fetches the chunk over CORS and spawns it
from a same-origin Blob URL through __setSplatSortCdnRuntime.
Who should depend on it
Almost nobody. Install @bitruvius/sdk-maplibre,
which owns the layers, the streaming and the placement, and re-exports the
handful of types you would touch (SplatOptions, SplatColorMode).
Depending on this package directly makes sense in one case: you are writing your
own ViewerAdapter for a host other than MapLibre and want the splat renderer
without the MapLibre layer stack.
Its runtime dependencies are
@bitruvius/geo-core, which
owns the Renderer and ViewerAdapter contracts, and
@bitruvius/render-runtime,
which owns the clip, shadow and footprint GLSL shared with the mesh layers.
Trademarks
Cesium and 3D Tiles are trademarks of Cesium GS, Inc. Niantic and SPZ are trademarks of Niantic, Inc. Khronos and WebGL are trademarks of The Khronos Group Inc. MapLibre is a trademark of the MapLibre organization. All other marks are the property of their respective owners.
These names are used solely to describe the data formats this software interoperates with. Bitruvius is not affiliated with, sponsored by, or endorsed by any of them, and no such relationship is implied.
License
Proprietary. The full terms ship as LICENSE inside this package, and are readable
before installing at cdn.bitruvius.com/legal/sdk-license-v1.txt.
© Bitruvius, Inc.
