<!-- Generated from hooks/use-scene-config.mdx; edit the MDX source. -->

Package: @liveroom-tech/react-immersive@5.2.0
Canonical: https://react-immersive.liveroom.dev/docs/hooks/use-scene-config

# `useSceneConfig`

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

## Usage

```tsx
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.

```tsx
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`. To list lights in an initial config,
`sceneLight` from `@liveroom-tech/react-immersive/utils` fills in each light's
defaults.

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:

```tsx
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

| Name                | Description                                      |
| ------------------- | ------------------------------------------------ |
| `sceneConfig`       | Current scene configuration                      |
| `setSceneConfig`    | React state dispatcher for complete replacements |
| `updateSceneConfig` | Merge a nested patch into the current state      |
| `resetSceneConfig`  | Restore the initial scene configuration          |
| `lights`            | CRUD, visibility, color, intensity, and attachment operations |

## Externally owned state

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

```tsx
import { patchSceneConfig } from "@liveroom-tech/react-immersive/utils";

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.
