The Gaussian System in the Untold Engine is responsible for rendering Gaussian Splatting models. It enables you to visualize high-quality 3D reconstructions created from photogrammetry or neural rendering techniques, providing a modern approach to displaying complex 3D scenes.
Start by creating an entity that represents your Gaussian Splat object.
let myEntity = createEntity()To display a Gaussian Splat model, load its .ply file and link it to the entity using setEntityGaussian.
setEntityGaussian(entityId: myEntity, filename: "splat", withExtension: "ply")Parameters:
- entityId: The ID of the entity created earlier.
- filename: The name of the .ply file (without the extension).
- withExtension: The file extension, typically "ply".
Note: The Gaussian System renders point cloud data stored in the .ply format. Ensure your Gaussian Splat file is properly formatted and contains the necessary attributes (position, color, opacity, scale, rotation).
Once everything is set up:
- Run the project.
- Your Gaussian Splat model will appear in the game window.
- If the model is not visible or appears incorrect, revisit the file path and format to ensure everything is loaded correctly.
setEntityGaussian loads a splat immediately and keeps it resident for the lifetime of the
entity — fine for a small number of always-visible splats, but not what you want for props
scattered across a large tile-streamed scene (chairs, tables, decor inside a streamed
building). Loading every one of those up front defeats the point of streaming, and the
engine has no way to unload them again on its own.
For that case, use setEntityGaussianStreamable instead. It registers the entity with
GeometryStreamingSystem, which loads and unloads it automatically based on camera
distance — the same way it already handles the surrounding streamed tile geometry.
This only makes sense in a scene that is already using tile-based streaming — i.e. one
loaded with setEntityStreamScene (see Using the Geometry Streaming System).
setEntityGaussianStreamable attaches the splat to whichever tile stub's bounds contain
the entity's position, so it needs those tile stubs to already exist. Call it after
setEntityStreamScene's completion handler has fired — tile stubs are guaranteed to be
registered by then.
Position and orient the entity before registering it for streaming — the position at the
time you call setEntityGaussianStreamable is what determines which tile it gets attached
to.
let streamSplat = createEntity()
translateTo(entityId: streamSplat, position: simd_float3(2.0, 0.0, -4.0))
rotateTo(entityId: streamSplat, angle: 180.0, axis: simd_float3(1.0, 0.0, 0.0))setEntityGaussianStreamable(
entityId: streamSplat,
filename: "chair",
withExtension: "ply",
streamingRadius: 30.0,
unloadRadius: 45.0,
boundingBoxHalfExtent: simd_float3(0.5, 0.8, 0.5)
)Parameters:
entityId: The entity created and positioned in Step 1.filename/withExtension: Same assetEntityGaussian— the.plyfile to stream in once the camera is in range.streamingRadius: Distance from the camera at which the splat starts loading.unloadRadius: Distance beyond which the splat unloads. Should be larger thanstreamingRadiusto avoid load/unload thrashing at the boundary.boundingBoxHalfExtent: A local-space half-extent for the entity, roughly matching the splat's real-world size. This has no default and must be supplied. Without a real bounding box, the streaming system's frustum gate collapses to a zero-extent point at the entity's exact position — the splat may load once but then fail to reliably re-stream in after the camera moves away and back, because re-entry depends on the camera looking at that exact point rather than anywhere near the prop.priority: Optional. Higher-priority entities load first when multiple candidates are in range at once. Defaults to0.
Note: If no tile is found containing the entity's position,
setEntityGaussianStreamablelogs a warning and leaves the entity as a plain, non-streaming entity (noStreamingComponentis attached) — it will not crash, but it also will not load. Double-check the position against the streamed scene's tile bounds if this happens.
setEntityGaussian— load immediately, stays resident. Use for a small number of splats that should always be visible (e.g. a single hero object, a standalone demo scene).setEntityGaussianAsync— same immediate/resident behavior, but the parse and GPU upload happen off the main thread. Use for a one-off splat load where you don't want a frame hitch, but still don't need distance-based unloading.setEntityGaussianStreamable— registers the entity withGeometryStreamingSysteminstead of loading anything itself. Use for splat props inside a large, tile-streamed scene, where you want the same load-when-near/unload-when-far behavior the rest of the scene already gets.