SplatMeshDesc
The SplatMeshDesc class is a mesh descriptor that renders 3D Gaussian Splat assets (.spz, .ply, .sog, .rad, .splat, .ksplat).
It is registered as the "splat" mesh key by DefaultPlugin, so any view.addMesh({ splat: { ... } }) call routes to this descriptor.
In addition to the properties below, all common properties from the base class (position, rotation, scale, matrix, matrixWorld, visible) are available. See MeshDesc for details.
Properties
Section titled “Properties”Type: string
Description: URL of the splat file to load. Required. Provide either the URL of an externally hosted splat with a verified license, or a path to a self-hosted asset placed under your project’s public/splat/ directory (referenced as /splat/your-asset.ply).
On fetch failure, a console.warn is logged; no exception is thrown and no event is emitted. Implement retry / fallback in the application if needed.
Example:
{ splat: { url: "/splat/your-asset.ply", }}Type: boolean
Default: false
Description: Enable Level-of-Detail rendering to draw only the splats needed at the current camera distance. Works with any 3DGS asset at runtime; pre-building the LoD tree at asset preparation time speeds up the initial load and avoids runtime tree construction.
Example:
{ splat: { url: "/splat/your-asset.ply", lod: true, }}originCellSize
Section titled “originCellSize”Type: number
Default: 2000
Description: Cell edge, in meters, of the floating origin that keeps splats numerically stable at globe (ECEF) scale. Navara renders splats relative to an origin that follows the camera, snapped to a grid of this size, so the large ECEF coordinates never reach the renderer’s single-precision math — this is what prevents sub-meter jitter as the camera moves. This is automatic; the property only tunes the grid. Smaller values tighten precision near the camera but re-sort splats more often as the camera crosses cells; larger values re-sort less often. The value is shared per transparent scene: the first splat added fixes it for every splat on that renderer. Most applications never need to change the default.
Example:
{ splat: { url: "/splat/your-asset.ply", originCellSize: 500, }}
url,lod, andoriginCellSizeare fixed at construction time. Callinghandle.update()with a different value logs a warning; recreate the descriptor instead.
Usage Examples
Section titled “Usage Examples”Basic Usage
Section titled “Basic Usage”import ThreeView, { geodeticToVector3, degreeToRadian } from "@navaramap/three";import type { SplatMeshDesc } from "@navaramap/three_default_descs";import { DefaultPlugin, type DefaultDescriptions,} from "@navaramap/three_default_plugin";
const view = new ThreeView<DefaultDescriptions>();view.addPlugin(new DefaultPlugin()); // registers "splat" → SplatMeshDescawait view.init();
const pos = geodeticToVector3({ lat: degreeToRadian(35.7100), lng: degreeToRadian(139.8107), height: 10,});
const splat = view.addMesh<SplatMeshDesc>({ splat: { url: "/splat/your-asset.ply", }, position: { x: pos.x, y: pos.y, z: pos.z }, scale: { x: 30, y: 30, z: 30 },});Upside-down correction
Section titled “Upside-down correction”If a splat appears upside-down in the scene, apply a 180° rotation around the X axis to correct:
view.addMesh<SplatMeshDesc>({ splat: { url: "..." }, rotation: { x: Math.PI, y: 0, z: 0 },});Supported Specifications
Section titled “Supported Specifications”Navara supports the following Gaussian Splatting formats.
File formats
Section titled “File formats”| File format | Description |
|---|---|
.spz | Niantic SPZ format |
.ply | Plain Gaussian Splatting data |
.sog | PlayCanvas Scene Optimized Gaussians |
.rad | Pre-built LoD asset (output of build-lod) |
.splat | antimatter15 splat format |
.ksplat | mkkellogg GaussianSplats3D format |
Limitations
Section titled “Limitations”- No scene lighting: Lighting is baked into the splat data;
SunLight/AmbientLightdo not affect rendering. - No shadow / selective effect / picking: Splats render in the transparent pass and are not integrated with shadows,
SelectiveBloomEffect/SelectiveOutlineEffect, or Navara’s picking pipeline. - Very large scale can look unstable: A very large
scalemakes each splat span a large world region, so the depth sort order can change abruptly with small camera moves (visible as “boiling”). This is inherent to Gaussian Splatting and is unrelated to placement precision — author assets close to their intended world size rather than scaling them up heavily.