Skip to Content
HooksuseSceneConfig

useSceneConfig

Own scene-wide configuration state and update nested settings without repetitive object spreads.

Usage

import { ModelViewer, useSceneConfig, } from "@liveroom-tech/react-immersive"; import { sceneConfig as initialSceneConfig } from "./sceneConfig"; const { sceneConfig, setSceneConfig, updateSceneConfig, resetSceneConfig, lights, } = useSceneConfig(initialSceneConfig); const enableUvChecker = () => { updateSceneConfig({ model: { renderer: "uv-checker" }, }); updateSceneConfig({ lighting: { ambient: { intensity: 0.5 }, }, }); }; <ModelViewer sceneConfig={sceneConfig} ... /> <button onClick={enableUvChecker}>Show UV checker</button>

Every update runs through a functional React state updater, so consecutive calls in the same tick compose safely.

Scene lights

lights is a namespaced controller for persistent scene lights. Its operations use the same functional state pipeline as updateSceneConfig, so several light changes in one event compose safely.

lights.add({ id: "bulb-light", type: "point", color: "#ffd27d", intensity: 4, distance: 5, }); lights.setIntensity("bulb-light", 6); lights.setColor("bulb-light", "#fff1c2"); lights.toggle("bulb-light"); lights.attach("bulb-light", { objectId: "bulb-filament", offset: [0, -0.2, 0], });

An attached light follows the model object’s complete world transform. The objectId can be a binding key, binding id, modelObjectId, or raw model node name. The offset is measured in the object’s local space. Use lights.detach to return to the light’s stored world position.

Pass sceneConfig to ModelViewer and leave the custom lights prop unset. That prop is an advanced replacement for the scene-config lighting tree, so scene-light controller changes do not affect custom React light elements.

The controller provides:

  • items and get
  • add, update, and remove
  • setIntensity and setColor
  • show, hide, and toggle
  • attach and detach

Updating from current state

Pass a function when an update depends on the current configuration:

const speedUpWalk = () => updateSceneConfig((current) => ({ animations: { clips: current.animations.clips.map((clip) => clip.sourceName === "Walk" ? { ...clip, speed: 1.5 } : clip, ), }, }));

Merge behavior

  • Nested configuration objects are merged recursively.
  • Arrays and tuples are replaced wholesale.
  • The input configuration and patch are not mutated.
  • resetSceneConfig restores the configuration supplied when the hook mounted.
  • setSceneConfig remains available when the complete configuration must be replaced.

Arrays include lights, animation clips, annotations, and cinematic waypoints. Supply the complete replacement array when updating one of these fields.

Returns

NameDescription
sceneConfigCurrent scene configuration
setSceneConfigReact state dispatcher for complete replacements
updateSceneConfigMerge a nested patch into the current state
resetSceneConfigRestore the initial scene configuration
lightsCRUD, visibility, color, intensity, and attachment operations

Externally owned state

Use the pure patchSceneConfig function when a store or parent owns the state:

import { patchSceneConfig } from "@liveroom-tech/react-immersive"; const next = patchSceneConfig(sceneConfig, { background: { enabled: true, type: "color", color: "#111827", }, }); onSceneConfigChange(next);

The library also exports DEFAULT_SCENE_CONFIG and the SceneConfigPatch, SceneConfigUpdate, SceneConfigController, SceneLightInput, SceneLightPatch, and SceneLightsController types.