フレームパス
PlayCanvas では、フレームグラフの各論理パスはフレームパスです。フレームパスはエンジンのオブジェクトで、フレームのレンダリング時にパスの処理を記録します。エンジンは自身のフレームをこの方法でレンダリングします。シャドウマップ、各カメラのシーン、ポストプロセスはすべてフレームパスです。また、独自のフレームパスを追加して、テクスチャにレンダリングしたり、カメラのレンダリング結果を処理したり、その結果に対してコンピュートシェーダーを実行したりできます。
エンジンは毎フレーム、フレームパスを順番にフレームグラフへ集め、それらを順に実行しながら、必要な物理パスを開始・終了します。物理パスを自分で開始・終了することはありません。
パスのクラス
すべてのフレームパスは、FramePass またはその派生クラスのインスタンスです。2 種類の物理パスには、それぞれ派生クラスが 1 つずつ対応します。レンダリング用の RenderPass と、コンピュートシェーダー用の ComputePass です。
| クラス | 用途 |
|---|---|
FramePass | 基底クラス。物理パスを必要としない処理、または他のフレームパスのグループ。 |
RenderPass | レンダーターゲット、またはバックバッファへのレンダリング。 |
ComputePass | フレーム内の特定の位置でのコンピュートシェーダーのディスパッチ。 |
RenderPass は論理レンダーパスで、そのドローコールを自身のレンダーターゲット用の物理レンダーパスに記録します。通常、エンジンは RenderPass ごとに物理レンダーパスを開始し、その後に終了します。連続する RenderPass オブジェクトが同じレンダーターゲットにレンダリングする場合は、代わりに単一の物理レンダーパスを共有します。フレームグラフを参照してください。同様に、エンジンは ComputePass のディスパッチを物理コンピュートパスに記録します。
エンジンは、レンダーターゲットのすべてのピクセルに対するシェーダーの実行やシーンのレンダリングなど、一般的な種類の描画のために RenderPass からクラスを派生させています。レンダーパスを参照してください。
フレームパスのライフサイクル
フレームパスは、自身が含まれる各フレームで 2 つのフェーズを経ます。フレームの構築中、何もレンダリングされる前に、エンジンはパスを更新し、フレームがどのパスをレンダリングするかを決定します。その後、フレームはパスを順番にレンダリングします。
サブクラスは、これらのメソッドをオーバーライドして処理を行います。
frameUpdateは、何もレンダリングされる前に、そのフレームに向けてパスを更新します。たとえば、レンダーターゲットのリサイズ、読み取るテクスチャの設定、前のパスや後のパスの追加や削除を行います。beforeとafterは、パスの処理の前後に実行されます。executeは処理を記録します。RenderPassの場合、自身のレンダーターゲット用の物理レンダーパスの中で実行されます。
onBefore と onAfter コールバックを使うと、サブクラスを作成せずにパスにフックできます。パスの実行直前にパラメーターを設定したり、パスが書き込むバッファをクリアしたり、実行直後にパスが書き込んだ内容を読み戻したりできます。
pass.onBefore = () => {
buffer.clear();
};
pass.onAfter = () => {
buffer.read().then((data) => {
// 結果は数フレーム後に届きます
});
};
enabled と executeEnabled
パスを無効にするプロパティは 2 つあり、ライフサイクルの異なる時点で作用します。
enabledを false に設定すると、フレームの構築時に、パスはその前のパスと後のパスとともにスキップされ、frameUpdateは呼び出されません。フレームが構築される前に変更してください。パスのframeUpdateで、そのパス自身を無効にすることはできません。executeEnabledを false に設定すると、executeのみがスキップされます。パスは引き続き更新され、前のパスと後のパスもレンダリングされ、before、after、onBefore、onAfterも呼び出されます。遅くともframeUpdateの中で設定してください。
前のパスと後のパス
すべてのパスは beforePasses と afterPasses を持ちます。これらは、パスがレンダリングされるフレームごとに、パスの直前と直後にレンダリングされます。
これによりパスをネストでき、素の FramePass で、まとめて有効化・無効化されるパスのグループを保持できます。
// 2 つのブラーパスのグループ:グループを無効にすると両方がスキップされます
const blur = new FramePass(app.graphicsDevice);
blur.name = 'Blur';
blur.beforePasses.push(horizontalBlurPass, verticalBlurPass);
blur.enabled = false;
カメラへのパスの追加
カメラは前のパス、次にカメラ自身のレンダリング(独自のフレームパスに置き換えることができます)、そして後のパスの順にレンダリングします。カメラパスを参照してください。
パスを単独でレンダリングする
render を呼び出すと、パスをフレームの外でレンダリングすることもできます。たとえば、テクスチャに一度だけレンダリングする場合です。before、onBefore、execute、after、onAfter は実行されますが、フレームによる準備は行われません。frameUpdate は呼び出されず、前のパスと後のパスもレンダリングされません。
pass.render();
パスの所有
パスが自動的に破棄されることはありません。カメラは自身のリスト内のパスを破棄せず、パスも自身の前のパスと後のパスを破棄しません。パスを作成したコードが、追加先のリストからパスを削除した後に destroy を呼び出して破棄します。破棄したパスは、それ以降使用しないでください。また、パスは、レンダーターゲットやシェーダーなど、渡されたものも破棄しません。
name で設定するパスの名前は、GPU プロファイリングやグラフィックスデバッガーでパスを識別するために使われます。デフォルトの名前はクラス名で、ミニファイされたビルドでは短縮されるため、明示的に設定してください。