realizeStage function
- SceneDocument document,
- Scene scene, {
- AssetBundle? bundle,
- 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();
}