---
title: "gaussianSplat"
description: "A photographic capture of a real place, stored as a cloud of oriented 3D Gaussians rather than as triangles. Drop a .spz or .ply into the world and the importer turns it into one of these."
section: "Types"
slug: "types-gaussiansplat"
canonical: "https://origozero.ai/docs/types-gaussiansplat"
updated: "2026-08-22T07:41:55.989267682+00:00"
tags: ["asset-type", "reference"]
---

# gaussianSplat

```
room_01.gaussianSplat/
  room-01.spz    the capture — the primary the runtime decodes
  .metadata      count, bounds, SH degree, axis convention
  README.md
```

The capture keeps the name it arrived under, so the file you dropped in is the
file you find inside. Reach its bytes through the asset — `captureRef:getBytes()`
— rather than by spelling the filename.

## Putting a capture in the scene

A capture instantiates under the same name a bundle and an avatar do — the
entity drawing the cloud is spawned for you, in the axis convention the
container recorded:

```luau
local root = asset.resolve("room", "gaussianSplat"):instantiate()
local child = captureRef:instantiate(entity.spawn("mount"))  -- as an owner's child
```

It is scene-compatible (`ref:canInstantiate()` is true), so every consumer of
the scene contract takes one: `zero entityOps fromAsset <capture>` is the same
spawn as one packaged call, and an `Asset` component pointed at a capture
spawns and tears down the cloud with its owner.

To place the cloud by hand instead, point a `GaussianSplat` component at it:

```luau
local id = entity.spawn("scan").id
entity(id).component.add("GaussianSplat", { source = "captures/room.gaussianSplat" })
```

## Reading a cloud without decoding it

`.metadata` carries what a tool needs to reason about a capture — how many
splats it holds, the world-space box it occupies, whether it stores
view-dependent colour — so framing a camera on a cloud or reporting its cost
does not pay for a decode of the whole thing.

```json
{
  "count": 1920000,
  "boundsMin": [-24.48, -0.92, -22.19],
  "boundsMax": [27.52, 33.40, 16.81],
  "shDegree": 0,
  "convention": "rightDownFront",
  "recordBytes": 24
}
```

`boundsMin` / `boundsMax` are the full extent, outliers included. A capture of
a whole scene usually carries a sparse halo of stray Gaussians far outside the
part anyone looks at, so framing a camera on these bounds puts it outside the
scene looking at the halo. For a scene capture, place the camera **inside** it.

## Why the capture stays the primary

The engine's packed record pool is 24 bytes per splat — larger than the `.spz`
the capture arrived in, whose quantized encoding is what makes the format worth
using. Baking the pool into the container would spend storage to save a decode
that costs a few hundred milliseconds once per load.

## Guide

`guides { path = "topics/gaussian-splats" }` covers capturing, placing, and
tuning a cloud.
