
ポストプロセッシングのためのモーションベクターパスの実装
新しいEvergineバージョン:モーションベクターは、Temporal Anti-Aliasing (TAA)やMotion Blurのようなポストプロセッシング技術を扱う上で不可欠な要素です。Evergineでは、モーションベクターパスにより、GPUがフレーム間でのオブジェクトとピクセルの動きを追跡し、より滑らかな視覚効果を実現します。

モーションベクターとは?
モーションベクターは、各ピクセルがフレーム間でどのように移動するかという情報を格納します。これはEvergineのTAAのようなポストプロセッシング技術において重要です。このアルゴリズムでは、複数フレームにわたってサンプルを蓄積し、エイリアシングアーティファクトを低減するために、モーションベクターテクスチャを使用して前のピクセル位置を追跡します。
同様に、Motion Blurエフェクトは、画面上での速度に基づいて動くオブジェクトの残像をシミュレートします。これらのエフェクトはどちらも、適切な視覚調整を計算するために正確なモーションベクターに大きく依存しています。
モーションベクターに対応するためのレンダーパスのアップグレード
デフォルトのRender Pathにおいて、EvergineはForward Renderingシステムを使用しています。しかし、ポストプロセッシングに有用な情報を格納するために、いくつかの追加パスも必要となります。これまでは、深度、メタルネス、ラフネス情報を含むテクスチャを生成するために、初期レンダーパス(ZPrePass)を使用していました。今回、モーションベクターテクスチャを生成する必要が生じたため、明確さと効率性を高めるためにRender Pathを再編成しました。次の図は、その変更点を示しています。

ZPrePass
現在、ZPrePassステージは1つのテクスチャのみを持ちます。
| 名前 | フォーマット | 説明 |
| Depth | D24S8 | 深度とステンシル情報。多くのポストプロセッシングエフェクトで有用です。 |

図1 DepthStencilテクスチャ
GBufferPass
以前のDistortionステージを削除し、より多くのフレームバッファを使用する新しいMRT(Multiple Render Target)パスを作成し、以前の情報を新しいMotion Vectorテクスチャに埋め込みました。
| テクスチャ | フォーマット | 説明 |
| RT 0 | R8G8B8A8_Unorm | 複数の情報を格納します。 – R, G: 法線、SSAOおよびSSRで使用。 – B: ラフネス、SSRで使用。 – A: メタルネス、SSRで使用。 |
| RT 1 | R16G16_Float | 新しいMotion Vectorテクスチャです。スクリーン空間におけるピクセルのXおよびY方向の速度を格納します。Temporal AntialiasingやMotion Blurのポストプロセスで使用されます。 |
| RT 2 | R8G8B8A8_Unorm | Distortionポストプロセスエフェクト用の歪み情報を保持します。 |

図2 Motion Vectorsテクスチャを通常のRGBテクスチャにクランプしたもの

図3 法線、ラフネス、メタルネステクスチャ
DefaultPass
前バージョンから変更はなく、ForwardライティングとPBRを用いて全てのオブジェクトをシーンにレンダリングするメインパスです。必要に応じて前段のパスを利用します。そのテクスチャは以下の通りです。
| 名前 | フォーマット | 説明 |
| Color | R16G16B16A16_Float | リニア空間の色を保持するHDRテクスチャです。 |
| Depth | D24S8 | 最終的な深度とステンシルを保持するテクスチャです。 |

図4 カラーテクスチャ(ポストプロセス前)、リニアカラー
ポストプロセスが適用され、色がガンマ空間に補正されると、最終結果が得られます。

エンジンの変更点
Evergineにモーションベクター機能を追加するにあたり、エンジンに以下の変更を加えました。
- Transform3Dは、前のピクセル位置を再構築できるように、前フレームのワールド行列(PreWorld)を保持するようになりました。
- SkinnedMeshRendererは、前フレームの全頂点位置を保持するようになりました。
- Effectsに、前フレームの行列[PreWorld]にアクセスするための新しいMetatagが追加されました。
- スキンメッシュの場合、前フレームの頂点位置はPosition1構文に格納されます(通常通り、Position_0には現在のフレームの位置が格納されます)。
