フレーム生成の基本
ShadingのMovie機能は、スクリプトを一度だけ実行して画面を変化させるのではなく、タイムライン上の各時刻から1フレームを組み立てます。描画の中心になるのはEventsカテゴリの render frame です。
render frame の役割
render frame は event_renderframe に対応するカスタムhatです。プレビュー、シーク、書き出しで対象フレームを構築するときに起動され、Objects、PenFX、通常の描画処理をそのフレームの処理として収集します。
書き出し中の時刻は、実時間ではなく次の値で決まります。
timeline time = renderFrameIndex / framerate
そのため、同じプロジェクト、出力サイズ、FPS、フレーム番号からは同じタイムライン時刻を使えます。再生中のプレビューは実時間から時刻をサンプルしますが、書き出しは決定的な時刻を使います。
初期化とフレームの構築
タイムライン書き出しでは、概ね次の順序で処理されます。
- 既存の音声、保留中の描画、VM実行を停止する
- 必要ならレンダラーを出力サイズへ変更し、
initializeを起動する - 初期化スレッド、資産読み込み、保留中のビジュアル処理を内部状態で待つ
- フレームごとにframe graphを開始し、タイムライン時刻を設定する
- 透明なstaging frameへ切り替えて既定背景を描画する
render frameを起動する- Objects、ビデオ、テキスト、モデル、PenFXの処理を完了する
- 音声イベントを確定し、Pen frameをcommitしてからフレームを保存する
停止、シーク、エラー、世代変更が起きた場合は、未完成のtransactionをcommitせずcancelします。これにより、フレーム途中の透明な画面やerase all直後の空白が一時的に表示されないようにします。
VMの実行契約
新規または変更されたMovieのcommand blockは、Scratch VMへPromiseを返しません。資産のデコード、GLSLのcompile/link、frame graphのflushなどの非同期処理は、MovieAssetManagerの内部状態として追跡されます。
したがって、render frameの中で非同期処理が保留中でも、同じフレームを再起動して時間を進めることはありません。完了後は既存のthreadを継続します。
Penのclearとstampも、frame graphの収集中はそれぞれclearノード、stampノードとして記録されます。レンダラー全体のdrawを抑制してタイミング問題を隠すのではなく、同じフレームtransactionの中で順序を保ちます。
プレビューと書き出し
タイムラインの再生・停止・シークは、Movieの現在時刻とプレビュー状態を操作します。書き出しは別のフレーム生成ライフサイクルを使い、指定したFPS、解像度、範囲、形式に従って各フレームを処理します。
出力形式、範囲、フレームキャッシュ、音声イベントについてはタイムラインと書き出しを参照してください。Objectsの描画順や深度はObjectsの基本、描画の原子性とframe graphはFrame graphとPenフレームを参照してください。