Skip to main content

Scene controllers

Scene controllers in @luma.gl/engine operate on engine nodes, materials, and resolved resource bindings. Applications can construct these inputs directly. glTF is a core supported source: @luma.gl/gltf maps its asset records and extensions into the same engine APIs.

APIInputsPer-frame operationOwnership
SkinControllerScenes and SkinBinding[] with mesh nodes, joint nodes, inverse bind matrices, and palette storageupdate() refreshes mesh-local joint palettes and bound model uniformsdestroy() releases supplied palette GPU transports; model and joint nodes remain caller-owned
MaterialVariantsNamed variants and per-model material/parameter mappingsselectVariant(name) or resetVariant() changes existing modelsMaterials and models remain caller-owned
BillboardControllerScenes and node orientation bindingsgetDrawEntries({viewMatrix, cameraId}) returns camera-facing transforms without mutating nodesdestroy() clears controller state; nodes remain caller-owned
AreaLightControllerScenes and area-light bindings with shape, width, height, color, and intensitygetLights(sceneIndex) resolves visible lights using current transformsdestroy() clears bindings; nodes remain caller-owned
AudioControllerScene, audio/source/emitter definitions, node bindings, optional processing graphs and environmentsupdate(listenerMatrix) updates listener and emitter spatial stateThe controller owns its processing nodes and sources; the application owns and activates its BaseAudioContext
InteractivityTyped operation graphs and a host property adapterstart(), tick(timeSeconds), and host events execute the graphHost properties and scene objects remain caller-owned

Construct engine inputs directly​

A rectangle light uses width and height directly. It does not need a source document or extension object:

import {AreaLightController, GroupNode} from '@luma.gl/engine';

const lightNode = new GroupNode({position: [0, 3, 0]});
const scene = new GroupNode({children: [lightNode]});
const lights = new AreaLightController({
scenes: [scene],
bindings: [{
node: lightNode,
definition: {type: 'rect', width: 4, height: 2, intensity: 1000}
}]
});

// After updating animated node transforms, pass these to your lighting shader inputs.
const currentLights = lights.getLights();

BillboardOrientation.rotationAxis accepts 'all' or 'y'. MaterialVariants accepts explicit ModelNode bindings, avoiding source-specific metadata lookups. SkinController.getBinding(node) uses the resolved mesh node rather than an asset index.

Supporting audio APIs​

AudioGraph constructs processing nodes and connects scheduled sources to borrowed emitter inputs. AudioReverbBus, createParametricAudioResponse(), and selectAudioEnvironmentZone() provide reusable reverb and spatial-zone behavior. They do not load glTF documents.

The audio context must be resumed from a user gesture before realtime playback. AudioController.initialize() fetches and decodes resources, play() starts sources, stop() stops playback, and destroy() releases owned processing resources. Audio is opt-in and independent of the graphics backend.

glTF mapping​

createScenegraphsFromGLTF() returns engine skins and variants controllers automatically. Optional features use parsers that return engine construction props:

import {AreaLightController, AudioController, BillboardController} from '@luma.gl/engine';
import {parseGLTFAreaLights, parseGLTFAudio, parseGLTFBillboards} from '@luma.gl/gltf';

const areaLights = new AreaLightController(parseGLTFAreaLights(scenegraphs));
const billboards = new BillboardController(parseGLTFBillboards(scenegraphs));
const audio = new AudioController(parseGLTFAudio({
scenegraphs,
audioContext,
baseUrl: modelUrl
}));

The parsers resolve extension names, source indices, scene attachments, and embedded buffer views. The engine controllers receive nodes, dimensions, typed graphs, and audio bytes. This keeps loading and source-format interpretation in glTF while runtime behavior belongs to engine.

See the glTF integration references for billboards, area lights, audio, and native extensions for supported extension profiles and limits.