Namespace viewer

xeokit Viewer


The SDK's browser-based 3D/2D Viewer for xeokit Scenes


This module allows you to display and interact with a Scene in the browser.

If you’re new to xeokit’s model representation, start with:

  • scene | @xeokit/sdk/model/scene for geometry/material content, and
  • data | @xeokit/sdk/model/data for semantic graphs you can attach to models.

This Viewer module focuses on the interactive layer: Views, Cameras, picking, emphasis effects (highlight/selection/x-ray), section planes, lighting, and rendering modes.


%%{init:{"theme":"dark"}}%% classDiagram direction TB class Viewer { +scene : Scene +views : Map~id, View~ +events : ViewerEvents +attachScene(scene) +detachScene() +createView(params) SDKResult~View~ +destroyView(id) +destroy() } class View { +id : string +camera : Camera +objects : Map~id, ViewObject~ +layers : Map~id, ViewLayer~ +sectionPlanes: Map~id, SectionPlane~ +lights : Lights +effects : Effects +htmlElement : HTMLCanvasElement +setObjectsVisible / Highlighted / Selected / XRayed / Clippable / Pickable } class Camera { +eye / look / up +viewMatrix / projMatrix +projection / fovy / near / far } class ViewObject { +id / sceneObject +visible / highlighted / selected / xrayed +color / opacity } class ViewLayer { +id +objects : Map +setObjectsVisible(...) } class SectionPlane { +dir / dist / active } class Scene { <<scene>> } Viewer "1" *-- "*" View Viewer "1" *-- "1" ViewerEvents Viewer o-- Scene : attached View "1" *-- "1" Camera View "1" *-- "*" ViewObject View "1" *-- "*" ViewLayer View "1" *-- "*" SectionPlane
%%{init:{"theme":"default"}}%% classDiagram direction TB class Viewer { +scene : Scene +views : Map~id, View~ +events : ViewerEvents +attachScene(scene) +detachScene() +createView(params) SDKResult~View~ +destroyView(id) +destroy() } class View { +id : string +camera : Camera +objects : Map~id, ViewObject~ +layers : Map~id, ViewLayer~ +sectionPlanes: Map~id, SectionPlane~ +lights : Lights +effects : Effects +htmlElement : HTMLCanvasElement +setObjectsVisible / Highlighted / Selected / XRayed / Clippable / Pickable } class Camera { +eye / look / up +viewMatrix / projMatrix +projection / fovy / near / far } class ViewObject { +id / sceneObject +visible / highlighted / selected / xrayed +color / opacity } class ViewLayer { +id +objects : Map +setObjectsVisible(...) } class SectionPlane { +dir / dist / active } class Scene { <<scene>> } Viewer "1" *-- "*" View Viewer "1" *-- "1" ViewerEvents Viewer o-- Scene : attached View "1" *-- "1" Camera View "1" *-- "*" ViewObject View "1" *-- "*" ViewLayer View "1" *-- "*" SectionPlane
classDiagram
    direction TB
    class Viewer {
      +scene  : Scene
      +views  : Map~id, View~
      +events : ViewerEvents
      +attachScene(scene)
      +detachScene()
      +createView(params) SDKResult~View~
      +destroyView(id)
      +destroy()
    }
    class View {
      +id           : string
      +camera       : Camera
      +objects      : Map~id, ViewObject~
      +layers       : Map~id, ViewLayer~
      +sectionPlanes: Map~id, SectionPlane~
      +lights       : Lights
      +effects      : Effects
      +htmlElement  : HTMLCanvasElement
      +setObjectsVisible / Highlighted / Selected / XRayed / Clippable / Pickable
    }
    class Camera {
      +eye / look / up
      +viewMatrix / projMatrix
      +projection / fovy / near / far
    }
    class ViewObject {
      +id / sceneObject
      +visible / highlighted / selected / xrayed
      +color / opacity
    }
    class ViewLayer {
      +id
      +objects : Map
      +setObjectsVisible(...)
    }
    class SectionPlane {
      +dir / dist / active
    }
    class Scene {
      <<scene>>
    }
    Viewer "1" *-- "*" View
    Viewer "1" *-- "1" ViewerEvents
    Viewer o-- Scene : attached
    View "1" *-- "1" Camera
    View "1" *-- "*" ViewObject
    View "1" *-- "*" ViewLayer
    View "1" *-- "*" SectionPlane

  • One Viewer, many Views — a single Viewer can drive several Views, each painting into its own canvas. Useful for multi-pane workflows (plan + elevation + 3D side-by-side).
  • Per-object state — every Scene object surfaces as a ViewObject per View with independent visible / highlighted / selected / xrayed / clippable / pickable / colour / opacity flags. Toggle one object in one View without disturbing another.
  • ViewLayers — group ViewObjects into named ViewLayers (default, drawings, ghosted, …) so the host can hide / show / restyle a logical batch in one call.
  • Section planes — arbitrary world-space clipping planes per View; pair with sectionCaps to fill the cuts.
  • Emphasis effects — highlight, selection, x-ray, edges, all driven by per-object boolean flags and a per-View material palette.
  • Lighting + IBL + tonemap — directional / point / ambient lights plus image-based lighting; HDR pipeline with bloom + FXAA + tonemap (Reinhard / ACES / linear).
  • Rendering modesRealisticRender (full PBR + IBL + shadows), DetailedRender (engineering-style with hatched bodies + section caps), EdgeRender, etc.
  • PickingView.pickByCanvasPos routes through the spatial.picking strategies for BVH / GPU / snap-aware picking.
  • Snapshot captureView.getSnapshot() returns the View's canvas as an HTMLImageElement / dataURL / ImageBitmap for sharing or report generation.

Installation

npm install @xeokit/sdk

Tutorial

This tutorial walks through a minimal setup and then adds common interaction features step by step.


import { Scene } from "@xeokit/sdk/model/scene";
import { Viewer } from "@xeokit/sdk/viewing/viewer";
import { WebGLRenderer } from "@xeokit/sdk/viewing/webGLRenderer";
import { ViewController } from "@xeokit/sdk/viewing/viewController";

import {
OrthoProjectionType,
PerspectiveProjectionType,
TrianglesPrimitive,
LinearEncoding,
LinearFilter
} from "@xeokit/sdk/base/constants";

Start by creating a Scene. The Scene is the SDK’s in-memory scene graph: it owns the model representation (SceneModels, objects, meshes, geometries, textures) and is where model content is created, updated, imported, and exported. For a deeper introduction to Scene content and building/importing models, see scene | @xeokit/sdk/model/scene.

Next, create a Viewer. The Viewer is the browser-facing facade for interactive viewing: it manages one or more Views (canvases), user interaction state (camera control, picking, emphasis effects, section planes, render modes, etc), and it provides a Viewer-centric event stream that reflects interactions and viewer-side changes.

Finally, attach a WebGLRenderer. The WebGLRenderer is the rendering backend that listens to changes and draws the Scene into the View canvases using the browser’s WebGL API.

The runtime event flow is:

  • The Scene emits events when its content changes (models loaded, objects created/destroyed, transforms updated, etc).
  • The Viewer receives those Scene changes (via the attached Scene) and emits Viewer events as user interaction and view configuration changes occur (camera moves, section planes added, objects highlighted/selected/x-rayed, etc).
  • The WebGLRenderer listens to both streams to keep GPU resources in sync and re-render Views whenever something changes.
const scene = new Scene();

const viewer = new Viewer({
scene
});

const renderer = new WebGLRenderer({
viewer
});

A Viewer renders into one or more Views. Each View has its own canvas, camera, and per-object visual state.

const view1Result = viewer.createView({
id: "myView",
elementId: "myView1"
});

if (!view1Result.ok) {
console.error(view1Result.error);
// handle error...
}

const view1 = view1Result.value;

const viewController = new ViewController({
view: view1
});

view1.camera.eye = [-3.93, 2.85, 27.01];
view1.camera.look = [4.40, 3.72, 8.89];
view1.camera.up = [-0.01, 0.99, 0.03];

view1.projectionType = OrthoProjectionType;
// view1.projectionType = PerspectiveProjectionType;

view1.perspectiveProjection.fov = 60.0;
view1.orthoProjection.scale = 1.0;

Configure Camera.worldAxis | worldAxis to match your domain’s coordinate system. This affects navigation behavior when using ViewController.

+Y up (+X right, -Z forward):

view1.camera.worldAxis = [
1, 0, 0, // Right
0, 1, 0, // Up
0, 0, -1 // Forward
];

+Z up (+X right, -Y forward):

view1.camera.worldAxis = [
1, 0, 0, // Right
0, 0, 1, // Up
0, -1, 0 // Forward
];

For a full walkthrough on creating and importing geometry, see scene | @xeokit/sdk/model/scene. Below is a tiny example that creates a model with a few objects so you can try interactions immediately:

const sceneModelResult = scene.createModel({
id: "myModel"
});

if (!sceneModelResult.ok) {
console.error(sceneModelResult.error);
// handle error...
}

const sceneModel = sceneModelResult.value;

sceneModel.createGeometry({
id: "myGeometry",
primitive: TrianglesPrimitive,
positions: [202, 202, 202, 200, 202, 202 ...],
indices: [0, 1, 2, 0, 2, 3 ...]
});

sceneModel.createTexture({
id: "myColorTexture",
src: "myTexture",
encoding: LinearEncoding,
magFilter: LinearFilter,
minFilter: LinearFilter
});

sceneModel.createMaterial({
id: "myMaterial",
colorTextureId: "myColorTexture"
});

sceneModel.createLayerMesh({
id: "myMesh1",
geometryId: "myGeometry",
materialId: "myMaterial"
});

sceneModel.createLayerMesh({
id: "myMesh2",
geometryId: "myGeometry",
materialId: "myMaterial"
});

sceneModel.createLayerMesh({
id: "myMesh3",
geometryId: "myGeometry",
materialId: "myMaterial"
});

sceneModel.createObject({
id: "myObject1",
meshIds: ["myMesh1"]
});

sceneModel.createObject({
id: "myObject2",
meshIds: ["myMesh2"]
});

sceneModel.createObject({
id: "myObject3",
meshIds: ["myMesh3"]
});

Toggle effects in batches:

view1.setObjectsHighlighted(["myObject1"], true);
view1.setObjectsSelected(["myObject2"], true);
view1.setObjectsXRayed(["myObject3"], true);
view1.setObjectsColorized(["myObject1"], [1, 0, 0]);

Or set state directly on a ViewObject:

view1.objects["myObject1"].highlighted = true;
view1.objects["myObject2"].selected = true;
view1.objects["myObject3"].xrayed = true;

view1.objects["myObject1"].colorize = [1, 0, 0];
view1.objects["myObject1"].colorize = null; // clear

Create a SectionPlane:

const sectionPlaneResult = view1.createSectionPlane({
id: "sectionPlane1",
pos: [0, 0, 0],
dir: [-1, -1, -1]
});

if (!sectionPlaneResult.ok) {
console.error(sectionPlaneResult.error);
// handle error...
}

const sectionPlane1 = sectionPlaneResult.value;

Animate it:

sectionPlane1.dir = [-1, -1, 1];
sectionPlane1.pos = [1, 0, 0];

Keep specific objects unaffected:

view1.setObjectsClippable(["myObject1"], false);
// or:
view1.objects["myObject1"].clippable = false;

view1.clearLights();

const lightResult = view1.createDirLight({
id: "dirLight1",
dir: [-1, -1, -1],
color: [0.9, 0.9, 0.9],
intensity: 0.9
});

if (!lightResult.ok) {
console.error(lightResult.error);
// handle error...
}

view1.createPointLight({
id: "pointLight1",
pos: [-100, 10, -100],
color: [0.9, 0.9, 1.0],
intensity: 1.0,
constantAttenuation: 0.8,
linearAttenuation: 0.9,
quadraticAttenuation: 0.9
});

view1.createAmbientLight({
id: "ambientLight1",
color: [0.5, 0.5, 0.6],
intensity: 0.7
});

Multiple Views can render the same Scene with different camera positions and visual states.

const view2Result = viewer.createView({
id: "myView2",
elementId: "myView2"
});

if (!view2Result.ok) {
console.error(view2Result.error);
// handle error...
}

const view2 = view2Result.value;

view2.camera.eye = [-3.933, 2.855, 27.018];
view2.camera.look = [4.400, 3.724, 8.899];
view2.camera.up = [-0.018, 0.999, 0.039];

const cameraControl2 = new ViewController({
view: view2
});

view2.objects["myObject1"].highlighted = true;

ViewLayers let you apply operations to groups of objects (visibility, selection, clipping, etc). ViewLayers are created in a View and are populated based on the layerId of the underlying SceneObjects.

const environmentLayerRes = view1.createLayer({
id: "myEnvironmentViewLayer"
});

if (!environmentLayerRes.ok) {
console.error(environmentLayerRes.error);
}

const environmentLayer = environmentLayerRes.value;

Hide everything in a layer:

environmentLayer.setObjectsVisible(environmentLayer.objectIds, false);

Use BCF to exchange viewpoints with other BIM tools. For background and semantic context, see data | @xeokit/sdk/model/data.

import { saveBCFViewpoint, loadBCFViewpoint } from "@xeokit/sdk/interop/bcf";

const bcfViewpointResult = saveBCFViewpoint({
view: view1,
excludeViewLayerIds: ["myEnvironmentViewLayer"]
});

if (!bcfViewpointResult.ok) {
console.log("Error saving BCF viewpoint:", bcfViewpointResult.error);
}

const bcfViewpoint = bcfViewpointResult.value;

const loadBCFResult = loadBCFViewpoint({
bcfViewpoint,
view: view1,
excludeViewLayerIds: ["myEnvironmentViewLayer"]
});

if (!loadBCFResult.ok) {
console.log("Error loading BCF viewpoint:", loadBCFResult.error);
}

Rendering modes let you enable/disable effects as a group (eg. quality vs performance).

import { NavigationRender, DetailedRender, RealisticRender } from "@xeokit/sdk/base/constants";

view1.edges.renderModes = [DetailedRender];
view1.sao.renderModes = [DetailedRender, RealisticRender];
view1.resolutionScale.renderModes = [NavigationRender];

view1.renderMode = NavigationRender;
view1.renderMode = DetailedRender;
view1.renderMode = RealisticRender;

Use Viewer.toParams and Viewer.fromParams to copy Viewer configuration between instances (Views, Cameras, SectionPlanes, Lights, materials, and more).

const viewerParamsResult = viewer.toParams();
const viewerParams = viewerParamsResult.value;

const viewer2 = new Viewer({
scene: new Scene()
});

const renderer2 = new WebGLRenderer({
viewer: viewer2
});

const fromParamsResult = viewer2.fromParams(viewerParams);
if (!fromParamsResult.ok) {
console.error("Error loading ViewerParams:", fromParamsResult.error);
}

Other

AmbientLight
AntiAliasing
Bloom
BodyHatch
Camera
CustomProjection
DirLight
Edges
Effect
Effects
FrustumProjection
HemisphereAmbient
IBL
Lights
LinesMaterial
OrthoProjection
PerspectiveProjection
PickResult
PointLight
PointsMaterial
ResolutionScale
SAO
SectionPlane
SectionPlaneCaps
Shadows
Sky
SnapshotResult
Texturing
Tonemap
View
Viewer
ViewerEvents
ViewLayer
ViewObject
ViewTransform
ViewTransformParams
AmbientLightParams
AntiAliasingParams
BloomParams
CameraParams
CustomProjectionParams
DirLightParams
EdgesParams
EffectParams
EffectsParams
FrustumProjectionParams
HDRImage
HemisphereAmbientParams
IBLParams
LightsParams
OrthoProjectionParams
PerspectiveProjectionParams
PickParams
PointLightParams
PointsMaterialParams
Projection
ResolutionScaleParams
SAOParams
SectionPlaneParams
ShadowsParams
SkyParams
SnapshotFinishedEvent
SnapshotParams
SnapshotStartedEvent
TickParams
TonemapParams
ViewerParams
ViewLayerParams
ViewParams
AntiAliasingMode
LineJoinStyle
TonemapMode
parseHDR
LineStyle → model.scene.LineStyle

materials

MaterialPresets