The scene module is xeokit's in-memory representation of 3D content, structured
as an extensible scene graph that runs identically in browsers and Node.js. It
separates renderable content (geometry, meshes, materials, textures) from logical
structure (objects, transforms) and lifecycle (creation, mutation, destruction), so
the same graph drives interactive viewing, headless conversion, and authoring
workflows from one source of truth.
Core capabilities:
Build content programmatically through builder-style APIs (createGeometry,
createMesh, createObject, β¦) or import it via the SDK format loaders
SceneMaterial / SceneTexture β PBR material with optional color, metallic-roughness, occlusion, and emissive textures
SceneTransform β Hierarchical transform applied to a SceneMesh
CoordinateSystem β Basis, units, origin, and scale for a Scene or SceneModel
SceneEvents β Event emitter for lifecycle and error notifications
Design Principles
Headless-first β The scene graph runs identically in browsers and Node.js.
Rendering is opt-in via Viewer +
WebGLRenderer; the same
SceneModel drives conversion pipelines, tests, and snapshots.
Buildable and serializable β Every component has a builder method
(createGeometry, createMesh, β¦) and a params
representation. SceneModels round-trip through
toParams /
fromParams losslessly.
Federated coordinate systems β A Scene carries its own
CoordinateSystem, and each SceneModel can declare its own.
Models from different sources combine without prior conversion; the SDK
aligns them at render time. See Federated Coordinate Systems below.
Double-precision throughout the CPU pipeline β All transforms and origin
coordinates are 64-bit; the GPU sees only camera-relative single-precision
deltas, so city-scale models render without jitter. See
Double-Precision Coordinates below.
Event-driven observation β Lifecycle changes flow through
SceneEvents so renderers and tools can react without the scene
having to know about them.
Importing, Exporting & Serialization
The scene graph is deliberately buildable and serializable:
Content can be created programmatically using the builder-style APIs.
Models can be imported from and exported to multiple industry formats
(e.g. gltf, las, cityjson,
xgf, dotbim, ifc).
SceneModels can be serialized to JSON and reconstructed later via
toParams / fromParams.
A Scene can be attached to a Viewer and
WebGLRenderer for interactive
rendering, or used headlessly in Node.js for conversion and processing workflows.
The builder APIs also support runtime mutation β changes are reflected
automatically in any attached Viewer and renderer.
Events
The SceneEvents system exposes lifecycle and error events, letting
applications observe and react to changes as models, objects, and resources
are created or destroyed. These events are consumed by components such as the
Viewer and
WebGLRenderer to drive rendering
and interaction, without the scene needing to be aware of those components.
Federated Coordinate Systems
A Scene uses a CoordinateSystem to specify its basis, units,
origin, and scale. Each SceneModel can also
carry its own CoordinateSystem, so models from different sources can be combined
without prior conversion. The SDK applies the necessary coordinate-system
transformations automatically during rendering and interaction, preserving each
model's original data.
Geometry Compression
SceneModel supports on-the-fly geometry compression (quantization) when creating
geometries from raw vertex / index data. For faster creation, pre-compress
geometry parameters using compressGeometryParams and create geometry
from those compressed parameters using SceneModel.createGeometryCompressed.
Double-Precision Coordinates
The Scene and SceneModel
APIs natively support double-precision (64-bit float) coordinates and transforms
throughout the scene graph. All transformation matrices are stored as
double-precision arrays, allowing accurate placement of models at any scale or
distance. Transformations can be nested hierarchically and dynamically updated
at runtime.
For rendering, the Viewer and
WebGLRenderer evaluate all
transforms in double-precision on the CPU. To maintain visual accuracy on the
GPU (which uses single-precision), the renderer uses camera-relative modeling
matrices and a tile-based system: scene objects are grouped into tiles, each
with a center and a modified view matrix. Data textures store these per-tile
view matrices, which shaders fetch to render multi-tile batches in a single
draw call. This approach keeps all GPU positions close to the origin,
minimizing floating-point error and supporting massive, real-world-scale models.
Limitations:
Geometry vertex positions must be single-precision (32-bit) floats.
Avoid double-precision scale transforms β these have the potential to cause inaccuracies when very large.
Installation
npminstall@xeokit/sdk
Quick Start (Tutorial)
This tutorial builds a simple βtableβ model (5 parts), attaches a Viewer, and shows how to read back created components.
4) Configure the Scene coordinate system (optional)
The Scene coordinate system is configured via Scene.coordinateSystem. By default, the Scene uses a
right-handed Z-Up coordinate system.
Each SceneModel may also specify its own SceneModel.coordinateSystem, allowing you to mix models
that originate in different coordinate systems without pre-processing them into a single common basis.
Example: set the Scene to a left-handed, Y-Up basis:
A Scene is renderer-agnostic. In Node.js you typically build/convert/export without rendering.
In the browser, attach the Scene to a Viewer and WebGLRenderer.
// 4) Create objects (logical entities). Each SceneObject references one or more meshes. sceneModel.createObject({ id:"redLegObject", meshIds: ["redLegMesh"] }); sceneModel.createObject({ id:"greenLegObject", meshIds: ["greenLegMesh"] }); sceneModel.createObject({ id:"blueLegObject", meshIds: ["blueLegMesh"] }); sceneModel.createObject({ id:"yellowLegObject", meshIds: ["yellowLegMesh"] }); sceneModel.createObject({ id:"tableTopObject", meshIds: ["tableTopMesh"] });
// SceneModel is now ready for use (rendering, picking, exporting, etc).
7) Read back components you created
The SceneModel stores its components in dictionaries keyed by ID.
Note: the Scene also indexes objects globally by ID, so you can access an object through either the model or the scene.
If you want faster SceneModel creation (or you already have geometry data offline), you can pre-compress
parameters using compressGeometryParams, then create geometry from those compressed parameters using
SceneModel.createGeometryCompressed.
if (!geometryResult2.ok) { console.error(geometryResult2.error); }
Using Dynamic Transforms
The SceneModel supports dynamic transforms via SceneTransform. Each SceneMesh can reference a parent
transform, and each SceneTransform can reference a parent transform, allowing you to build hierarchical
transform structures. Transforms support double-precision values, and can be updated at runtime to
achieve dynamic animation effects. The Viewer and WebGLRenderer automatically ensure that double-precion transforms
are rendered accurately on the GPU, even for huge transforms, as shown in the example below.
In this example, we create a mesh, attached to a transform with a large position to demonstrate double-precision support, then we
update its rotation over time to make it spin.
sceneModel.createTransform({ id:"myTransform", position: [100000000, 0, 0], // Large position to demonstrate double-precision support scale: [1, 1, 1], rotation: [0, 0, 0] // X,Y,Z Euler angles in degrees });
exporter.write({ sceneModel, dataModel, version:"1.1.0"// Optional; defaults to the latest supported version }).then(fileData=> { // Use fileData as needed }).catch(err=> { console.error(err); });
Importing a SceneModel from a file
Import SceneModels from several formats. For example, load DotBIM using
DotBIMLoader:
xeokit Scene Graph
A buildable, serializable scene graph for 3D content β geometry, materials, transforms, and renderable objects.
π Cheatsheet β model/scene at a glance
Overview
The
scenemodule is xeokit's in-memory representation of 3D content, structured as an extensible scene graph that runs identically in browsers and Node.js. It separates renderable content (geometry, meshes, materials, textures) from logical structure (objects, transforms) and lifecycle (creation, mutation, destruction), so the same graph drives interactive viewing, headless conversion, and authoring workflows from one source of truth.Core capabilities:
createGeometry,createMesh,createObject, β¦) or import it via the SDK format loadersArchitecture
Key components:
Design Principles
Headless-first β The scene graph runs identically in browsers and Node.js. Rendering is opt-in via Viewer + WebGLRenderer; the same SceneModel drives conversion pipelines, tests, and snapshots.
Buildable and serializable β Every component has a builder method (
createGeometry,createMesh, β¦) and a params representation. SceneModels round-trip through toParams / fromParams losslessly.Federated coordinate systems β A Scene carries its own CoordinateSystem, and each SceneModel can declare its own. Models from different sources combine without prior conversion; the SDK aligns them at render time. See Federated Coordinate Systems below.
Double-precision throughout the CPU pipeline β All transforms and origin coordinates are 64-bit; the GPU sees only camera-relative single-precision deltas, so city-scale models render without jitter. See Double-Precision Coordinates below.
Event-driven observation β Lifecycle changes flow through SceneEvents so renderers and tools can react without the scene having to know about them.
Importing, Exporting & Serialization
The scene graph is deliberately buildable and serializable:
Events
The SceneEvents system exposes lifecycle and error events, letting applications observe and react to changes as models, objects, and resources are created or destroyed. These events are consumed by components such as the Viewer and WebGLRenderer to drive rendering and interaction, without the scene needing to be aware of those components.
Federated Coordinate Systems
A Scene uses a CoordinateSystem to specify its basis, units, origin, and scale. Each SceneModel can also carry its own CoordinateSystem, so models from different sources can be combined without prior conversion. The SDK applies the necessary coordinate-system transformations automatically during rendering and interaction, preserving each model's original data.
Geometry Compression
SceneModel supports on-the-fly geometry compression (quantization) when creating geometries from raw vertex / index data. For faster creation, pre-compress geometry parameters using compressGeometryParams and create geometry from those compressed parameters using SceneModel.createGeometryCompressed.
Double-Precision Coordinates
The Scene and SceneModel APIs natively support double-precision (64-bit float) coordinates and transforms throughout the scene graph. All transformation matrices are stored as double-precision arrays, allowing accurate placement of models at any scale or distance. Transformations can be nested hierarchically and dynamically updated at runtime.
For rendering, the Viewer and WebGLRenderer evaluate all transforms in double-precision on the CPU. To maintain visual accuracy on the GPU (which uses single-precision), the renderer uses camera-relative modeling matrices and a tile-based system: scene objects are grouped into tiles, each with a center and a modified view matrix. Data textures store these per-tile view matrices, which shaders fetch to render multi-tile batches in a single draw call. This approach keeps all GPU positions close to the origin, minimizing floating-point error and supporting massive, real-world-scale models.
Limitations:
Installation
Quick Start (Tutorial)
This tutorial builds a simple βtableβ model (5 parts), attaches a Viewer, and shows how to read back created components.
1) Import the modules youβll use
2) Create a Scene
3) Subscribe to Scene lifecycle events (optional)
Everything that happens in a Scene is reported via the SceneEvents dispatcher at Scene.events.
4) Configure the Scene coordinate system (optional)
The Scene coordinate system is configured via Scene.coordinateSystem. By default, the Scene uses a right-handed Z-Up coordinate system.
Each SceneModel may also specify its own SceneModel.coordinateSystem, allowing you to mix models that originate in different coordinate systems without pre-processing them into a single common basis.
Example: set the Scene to a left-handed, Y-Up basis:
5) Attach a Viewer (browser only)
A Scene is renderer-agnostic. In Node.js you typically build/convert/export without rendering. In the browser, attach the Scene to a Viewer and WebGLRenderer.
A minimal setup uses:
6) Build a SceneModel (a simple βtableβ)
Next we create a SceneModel and populate it with:
Weβll also set a local coordinate system for this SceneModel (optional).
7) Read back components you created
The SceneModel stores its components in dictionaries keyed by ID. Note: the Scene also indexes objects globally by ID, so you can access an object through either the model or the scene.
Using Compressed Geometry
When you create a SceneGeometry via SceneModel.createGeometry, the SDK may perform on-the-fly processing and compression of geometry parameters.
If you want faster SceneModel creation (or you already have geometry data offline), you can pre-compress parameters using compressGeometryParams, then create geometry from those compressed parameters using SceneModel.createGeometryCompressed.
In the example below, compressGeometryParams converts SceneGeometryParams into SceneGeometryCompressedParams:
A SceneGeometryCompressedParams typically includes:
aabb) used to de-quantize in the ViewerCreate geometry from the compressed parameters:
Using Dynamic Transforms
The SceneModel supports dynamic transforms via SceneTransform. Each SceneMesh can reference a parent transform, and each SceneTransform can reference a parent transform, allowing you to build hierarchical transform structures. Transforms support double-precision values, and can be updated at runtime to achieve dynamic animation effects. The Viewer and WebGLRenderer automatically ensure that double-precion transforms are rendered accurately on the GPU, even for huge transforms, as shown in the example below.
In this example, we create a mesh, attached to a transform with a large position to demonstrate double-precision support, then we update its rotation over time to make it spin.
Exporting a SceneModel to a file
SceneModels can be exported to several formats. For example, export to DotBIM with DotBIMExporter :
Importing a SceneModel from a file
Import SceneModels from several formats. For example, load DotBIM using DotBIMLoader:
Serializing a SceneModel to JSON
Deserializing a SceneModel from JSON
Destroying a SceneModel