serializeStage function

void serializeStage(
  1. Scene scene,
  2. SceneDocument document
)

Reads scene's stage render settings back into document, writing the look into the stage's environment resource (creating and linking one when the stage has none).

The reverse of realizeStage. An environment the realizer produced recovers its source spec, and an fmat sky loaded through loadFmatSky recovers its source path plus every parameter assigned through its typed setters; a hand-built EnvironmentMap serializes as the studio default and a custom ShaderSkySource is dropped, each with a warning.

Implementation

void serializeStage(Scene scene, SceneDocument document) {
  final stage = document.stage;
  stage.antiAliasingMode = scene.antiAliasingMode.name;
  stage.renderScale = scene.renderScale;
  stage.filterQuality = scene.filterQuality.name;

  final resource = _ensureStageEnvironment(document);
  resource.environmentIntensity = scene.environmentIntensity;
  resource.exposure = scene.exposure;
  resource.toneMapping = scene.toneMapping.name;

  final skyEnvironment = scene.skyEnvironment;
  if (skyEnvironment == null) {
    resource.skyEnvironment = null;
    final environment = scene.environment;
    var spec = environment == null ? null : _environmentSpec[environment];
    if (spec == null && environment != null) {
      // An environment the app loaded itself still recovers when it carries
      // its asset-path stamp (EnvironmentMap.fromEquirectImageAsset).
      final assetPath = environmentAssetPathOf(environment);
      if (assetPath != null) spec = AssetEnvironment(AssetRef(assetPath));
    }
    if (spec != null) {
      resource.environment = spec;
    } else {
      if (environment != null) {
        debugPrint(
          'fscene: the scene environment was not produced by realizeStage '
          'or EnvironmentMap.fromEquirectImageAsset and cannot be recovered; '
          'serializing the studio default',
        );
      }
      resource.environment = const StudioEnvironment();
    }
  } else {
    final source = _serializeSkySource(skyEnvironment.source);
    // A sun light counts as "the sky casts shadows" only when it is driven by
    // the same sky source the lighting is, the binding this realizer produces.
    final castsSkyShadows = identical(
      scene.sunLight?.source,
      skyEnvironment.source,
    );
    resource.skyEnvironment = source == null
        ? null
        : SkyEnvironmentSpec(
            source,
            refresh: skyEnvironment.refresh.name,
            intervalSeconds: skyEnvironment.interval.inMicroseconds / 1e6,
            faceResolution: skyEnvironment.faceResolution,
            equirectWidth: skyEnvironment.equirectWidth,
            castShadows: castsSkyShadows,
          );
  }

  final skybox = scene.skybox;
  if (skybox == null) {
    resource.skybox = null;
  } else {
    final source = _serializeSkySource(skybox.source);
    resource.skybox = source == null
        ? null
        : SkyboxSpec(source, intensity: skybox.intensity);
  }
}