realizeStage function

Future<void> realizeStage(
  1. SceneDocument document,
  2. Scene scene, {
  3. AssetBundle? bundle,
  4. EnvironmentAssetLoader? environmentLoader,
})

Applies document's stage render settings to scene: environment, environment intensity, exposure, tone mapping, skybox, and sky lighting.

When the stage binds sky lighting (skyEnvironment), the binding owns Scene.environment and the stage's environment is not applied. A skybox and a sky-lighting binding whose sources describe the same sky share one live source, so mutating it (or hot reloading its .fmat) updates both.

GPU-bound and async (an asset environment decodes its image, an fmat sky loads by source path from bundle, default the root bundle).

environmentLoader builds an AssetEnvironment's map from outside the asset bundle (the editor resolves a user-picked file from disk and builds the prefiltered cube), so a disk environment is owned by the environment's own realization rather than patched in afterwards. It honors the current EnvironmentMap.radianceCubeSize.

Implementation

Future<void> realizeStage(
  SceneDocument document,
  Scene scene, {
  AssetBundle? bundle,
  EnvironmentAssetLoader? environmentLoader,
}) async {
  final stage = document.stage;
  // A self-contained build inlines environment images into payload chunks; the
  // realize resolves them from this document's payload table.
  PayloadSpec? payloadLookup(LocalId id) => document.payload(id);
  scene.antiAliasingMode = _byName(
    AntiAliasingMode.values,
    stage.antiAliasingMode,
    AntiAliasingMode.auto,
  );
  scene.renderScale = stage.renderScale;
  scene.filterQuality = _byName(
    ui.FilterQuality.values,
    stage.filterQuality,
    ui.FilterQuality.medium,
  );

  // The stage's global look is its referenced environment resource; a missing
  // or unresolved reference falls back to the studio default.
  final envRef = stage.environmentRef;
  final resource = envRef == null ? null : document.resource(envRef);
  final look = resource is EnvironmentResource ? resource : null;
  (await realizeEnvironmentSettings(
    environment: look?.environment ?? const StudioEnvironment(),
    environmentIntensity: look?.environmentIntensity ?? 1.0,
    exposure: look?.exposure ?? 1.0,
    toneMapping: look?.toneMapping ?? 'pbrNeutral',
    radianceCubeSize: look?.radianceCubeSize,
    skybox: look?.skybox,
    skyEnvironment: look?.skyEnvironment,
    bundle: bundle,
    environmentLoader: environmentLoader,
    payloadLookup: payloadLookup,
  )).applyTo(scene);

  // Spatial environment-volume components blend over the stage as the global
  // base. Capture the just-applied stage look as that base so the components
  // have something to blend over; the per-frame blend is skipped when no volume
  // component is active, so the live fields are used directly in the common
  // case. The manual `Scene.environmentVolumes` list is code-driven, not carried
  // by the document, so a realize clears it.
  scene.baseEnvironment = EnvironmentSettings.fromScene(scene);
  scene.environmentVolumes.clear();
}