ScenegraphLayer renders complete glTF scene graphs with support for hierarchical node structures, animations, and physically-based rendering (PBR) materials. It's designed for complex 3D models that require advanced lighting and animation capabilities.
import { ScenegraphLayer } from "@deck.gl/mesh-layers";
import type { ScenegraphLayerProps } from "@deck.gl/mesh-layers";class ScenegraphLayer<DataT = any, ExtraPropsT extends {} = {}> extends Layer<
ExtraPropsT & Required<ScenegraphLayerProps<DataT>>
> {
constructor(props: ScenegraphLayerProps<DataT> & ExtraPropsT);
static readonly layerName: "ScenegraphLayer";
static readonly defaultProps: DefaultProps<ScenegraphLayerProps>;
}interface ScenegraphLayerProps<DataT = unknown> extends LayerProps {
// Data and scene
data: LayerDataSource<DataT>;
scenegraph: any;
// Scene management
getScene?: (
scenegraph: any,
context: {device?: Device; layer: ScenegraphLayer<DataT>}
) => GroupNode;
getAnimator?: (
scenegraph: any,
context: {device?: Device; layer: ScenegraphLayer<DataT>}
) => GLTFAnimator;
loaders?: any[];
// Styling
sizeScale?: number;
sizeMinPixels?: number;
sizeMaxPixels?: number;
// Lighting
_lighting?: 'flat' | 'pbr';
_imageBasedLightingEnvironment?:
| PBREnvironment
| ((context: {gl: WebGL2RenderingContext; layer: ScenegraphLayer<DataT>}) => PBREnvironment);
// Animation
_animations?: {
[name: number | string | '*']: {
playing?: boolean;
startTime?: number;
speed?: number;
};
} | null;
// Accessors
getPosition?: Accessor<DataT, Position>;
getColor?: Accessor<DataT, Color>;
getOrientation?: Accessor<DataT, Orientation>;
getScale?: Accessor<DataT, Scale>;
getTranslation?: Accessor<DataT, Translation>;
getTransformMatrix?: Accessor<DataT, number[]>;
}LayerDataSource<DataT>any(scenegraph, context) => GroupNode (optional)(scenegraph, context) => GLTFAnimator (optional)any[] (optional)[GLTFLoader]number (optional, default: 1)number (optional, default: 0)number (optional, default: Number.MAX_SAFE_INTEGER)'flat' | 'pbr' (optional, default: 'flat')PBREnvironment | Function (optional)Object | null (optional, default: null)playing: boolean - Whether the animation is playingstartTime: number - Start time of the animation (default: 0)speed: number - Speed multiplier of the animation (default: 1)Accessor<DataT, Position> (optional, default: x => x.position)[x, y, z]Accessor<DataT, Color> (optional, default: [255, 255, 255, 255])[r, g, b, a]Accessor<DataT, Orientation> (optional, default: [0, 0, 0])[pitch, yaw, roll] in degreesAccessor<DataT, Scale> (optional, default: [1, 1, 1])[x, y, z]Accessor<DataT, Translation> (optional, default: [0, 0, 0])[x, y, z] in metersAccessor<DataT, number[]> (optional, default: [])class ScenegraphLayer<DataT, ExtraPropsT> {
// Layer state
get isLoaded(): boolean;
// Rendering
getShaders(): ShaderModule;
initializeState(): void;
updateState(params: UpdateParameters<this>): void;
finalizeState(context: LayerContext): void;
draw(opts: {context: any}): void;
}import { ScenegraphLayer } from "@deck.gl/mesh-layers";
const data = [
{coordinates: [-122.4, 37.8, 0], name: "San Francisco"},
{coordinates: [-74.0, 40.7, 0], name: "New York"},
];
const layer = new ScenegraphLayer({
id: 'gltf-models',
data,
scenegraph: 'https://example.com/models/building.gltf',
getPosition: d => d.coordinates,
sizeScale: 500
});const layer = new ScenegraphLayer({
id: 'animated-scene',
data: myData,
scenegraph: '/path/to/animated-model.glb',
getPosition: d => d.position,
getOrientation: d => [0, d.heading, 0],
// Enable PBR lighting
_lighting: 'pbr',
_imageBasedLightingEnvironment: myPBREnvironment,
// Configure animations
_animations: {
'*': {playing: true, speed: 1.5}, // All animations at 1.5x speed
'walk': {playing: true, speed: 2.0}, // Walk animation at 2x speed
'idle': {playing: false} // Disable idle animation
}
});import { createScenegraphsFromGLTF } from "@luma.gl/gltf";
const layer = new ScenegraphLayer({
id: 'custom-scene',
data: myData,
scenegraph: myGLTFData,
// Custom scene extraction
getScene: (scenegraph, {device, layer}) => {
const gltfObjects = createScenegraphsFromGLTF(device, scenegraph, {
modelOptions: {
id: layer.props.id + '-model',
bufferLayout: layer.getAttributeManager()!.getBufferLayouts(),
...layer.getShaders()
}
});
return gltfObjects.scenes[0];
},
// Custom animator
getAnimator: (scenegraph) => {
return scenegraph.animator || null;
}
});// Start with stopped animations
const layer = new ScenegraphLayer({
id: 'controlled-animation',
data: myData,
scenegraph: myModel,
_animations: {
'*': {playing: false}
}
});
// Later, start specific animations
layer.setProps({
_animations: {
'run': {playing: true, startTime: Date.now() / 1000, speed: 1.2},
'jump': {playing: true, startTime: Date.now() / 1000 + 2.0, speed: 0.8}
}
});const layer = new ScenegraphLayer({
id: 'size-constrained',
data: myData,
scenegraph: myModel,
sizeScale: 1000,
sizeMinPixels: 10, // Never smaller than 10 pixels
sizeMaxPixels: 200, // Never larger than 200 pixels
getPosition: d => d.coordinates
});ScenegraphLayer supports various input formats:
Uses @loaders.gl/gltf for loading and processing glTF assets with automatic:
0, 1, 2 - Animation by index"walk", "idle" - Animation by name"*" - Affects all animationsAnimations use the deck.gl timeline system and automatically:
_animations is configured'flat')'pbr')_imageBasedLightingEnvironment for realistic resultssizeMinPixels/sizeMaxPixels to control level-of-detail