UDN
Search public documentation:

MotionBlurSkinningJP
English Translation
中国翻译
한국어

Interested in the Unreal Engine?
Visit the Unreal Technology site.

Looking for jobs and company info?
Check out the Epic games site.

Questions about support via UDN?
Contact the UDN Staff

UE3 ホーム > ポストプロセス エフェクト > ポストプロセス機能 MotionBlurSkinning (モーション ブラー スキニング)


ポストプロセス機能 MotionBlurSkinning (モーション ブラー スキニング)


3small.png
異なる方向に動いている体の各部位によって、モーション ブラーが異なる方向で異なる強さで機能していることが分かります。

概要


モーション ブラー を参照してください。

モーション ブラー スキニング が実装される前は、カメラおよびオブジェクトのモーション (平行移動、回転、スケーリング) に基づいた 剛性モーション ブラー しかサポートされていませんでした。スキンメッシュは、オブジェクトのルートからオブジェクトのモーションを得ていました。これは、単純なオブジェクトについては有効な近似値となりましたが、キャラクターについてはそうではありませんでした。ボディの各部分が異なる方向に動くので、より洗練されたメソッドが必要となります。

PerBoneMotionBlur.jpg
左 : 機能が無効
中 : 機能が有効
右 : ピクセル単位の速度 (ベロシティ) がカラーで示されています。

スキン モーション ブラーによって、CPU および GPU 性能がさらに必要となり、メモリコストも余計にかかります。そのため、本当に必要な部分にのみ使用するべきです。他のすべてのオブジェクトについては、スキン モーション ブラーがまだ使用可能です。

機能を有効にする


この機能がプラットフォームによってサポートされている場合 (このテーマについては後のセクションをご覧ください)、機能を有効にするには、BaseEngine.ini の中にある ini 設定項目である MotionBlurSkinning を使用するか、あるいは、後ほどランタイム時に MotionBlurSkinning コンソールコマンドを使用します。

ini 設定項目で指定される数値は、コンソールコマンドで使用される数値と同じです。この値は、1 のときに機能を有効し、0 のときに無効にします。それに加えて、2 のときには、オブジェクト単位のフラグをオーバーライドすることによってすべてのオブジェクトに強制的にフラグを適用します。現在のステートとヘルプを表示するには、追加パラメータを付けずにコンソールコマンドを使用します。

ConsoleMotionBlurSkinning.jpg
MotionBlurSkinning コンソールコマンドを使用したときの様子です。

SkeletalMesh フラグを設定する


editorflag.jpg

実装


スキン モーション ブラーは、ピクセル単位のモーション ベクターを速度テクスチャに出力しています。(現在は、カメラ モーションについては黒、オブジェクト モーションについてはカラーとなっています。詳細は モーション ブラー をご参照ください) すべての速度がレンダリングされると、次のステップにおいては、 剛性モーション ブラースキン モーション ブラー に違いはありません。

フレームで使用されるすべてのオブジェクトのためのボーン データは、次のフレームで使用するために、テクスチャのフレームの中に保存されます。つまり、常に 2 つのテクスチャが必要となるということです。同一のフレームにおいて、1 つ は読み込み (GPU)、もう 1 つは書き出しです (CPU)。これによって、テクスチャのロック数を最小限に抑えられています。エンジンがトリプル バッファリングを使用するように変更して、バッファをもう 1 つ、このチェインに追加する必要が生じる可能性もあります。

頂点シェーダー定数を用いてこの機能を実装することができたかもしれませんが、これらの定数には制約があるため、データをシェーダーに入れるのは困難です。すでに、GPU のスキニングによってほぼすべての定数が使われています。スキン モーション ブラーのためにはその倍の量が必要になります (現在のボーン行列と前のボーン行列の両方が必要です)。データをパッキング化するのも選択肢の 1 つでしょう (例: クォータニオン + スケール + 位置)。しかし、更に複雑になることは避けられません。描画コールをボーン数の半分のチャンクに分割することも、問題を解決する 1 つの方法ですが、他のパスのためのレンダリングパフォーマンスが低速化し、コンテンツの準備 (クック/インポート) が複雑になります。

わたしたちは、頂点テクスチャ フェッチを使用して、スキン モーション ブラーを実装することにしました。この GPU の機能は、すべてのハードウェアでサポートされているとは限りません。特に、初期の ShaderModel 3.0 ハードウェア (AMD/ATI) では、サポートされていません。

CPU からボーン データをともなったテクスチャを更新します。テクスチャのキャッシュ パフォーマンスを考慮して、1D のテクスチャを使用します。

メッシュをチャンクに分けることによって、制限のあるボーン数 (制限のある頂点シェーダー定数) に配慮するとともに、マテリアルによってメッシュを分割しています。

チャンク単位のインデックスを使用するとともに、それがボーンのサブセットのインデックスになっている場合は、ボーンが二重に見える可能性があります。

正弦があるボーン数

ボーン データを保存するには 1D テクスチャを使用するため、ボーン数には制限があります。現在のところ、使用するテクスチャは幅 4096 であり、ボーン 1 つにつき 3 個のテクセルを保存する必要があります。この制限がゲームに影響するか否かを調べるには、 stat SceneUpdate (統計 シーン更新) コマンドを使用します。モーション ブラーは近くのオブジェクトについてしか実行されません。また、これによって問題が生じたことはありません。なお、顔のアニメーションのモーション ブラーでは、 MotionBlurSkinning 機能を必要としない場合が多い。

シェーダーの置換

我々は、スキン モーション ブラーを持とうとする場合と持たないようにする場合について、シェーダー置換の回避を試みました。その目的は、ほとんどがコードの複雑化を緩和することにありましたが、同時に、シェーダーの数を全般的に少なくすることも目指していました。静的分岐 (ブール型定数で比較する) を使用することにしました。理由は、これによって問題が解決されるとともに、ドライバーによって最適化されてコードからオミットされるためです。

Xbox360 では、静的分岐を使用することによって、シェーダーの置換を回避しています。コンパイルアウトと同じくらい速いことが確かめられました。他のプラットフォームではまだこの方式が利用できません (最適化のセクションを参照してください)。

パフォーマンス

CPU データの更新

スキン モーション ブラーの CPU 負荷は高くありません。その理由は、前のフレームのデータが保存されて次のフレームに再利用されるからです。ダブル バッファしか用いていないため、テクスチャ ロック処理が遅延することはありません。ただし、念のために stat (統計) でこのことを確かめることができます。コンソールコマンドの stat SceneUpdate を使用して、この数字を参照することができます。

StatSceneUpdate.jpg
統計によって、ロックのための CPU 時間と更新されたボーン量が示されています。

描画コールの増加

モーション ブラーされたオブジェクトは、(ピクセル単位のモーション ベクターを保存するために) 速度レンダリング パスでレンダリングされる必要があります。非スキン モーション ブラーについては、これを実行する必要があるのは、オブジェクト モーションがある場合だけです。スキンされたオブジェクトがモーションを持っているか否かを調べるには、一層多くのデータをチェックする必要があります。この最適化はまだ行っていません。その実行は可能でしょうが、多数の動いているオブジェクトのワーストケースには無効でしょう。

つまり、動いていないオブジェクト (例: 動いていないボット) のためにスキン モーション ブラーを有効にする場合、レンダリングされる必要があり、それによってより多くの描画コールが加えられるということになります。

頂点テクスチャ フェッチの GPU 負荷

現在の方法では、12 の頂点テクスチャ フェッチを、非常に大きな頂点フォーマット (1 つの 4×3 ボーン行列のために 4 つの float 型、スキニングのために 4 つのボーン) に入れる必要があります。つまり、より多くの頂点がこのようにレンダリングされる必要があるならば、それだけレンダリングの速度が低下するということになります。近くのオブジェクトだけがこのようにレンダリングされ (速度レンダリングパス)、レンダリングの負荷が、近くのアクションでピークに達する可能性があります。

Xbox360 (モーフをともなった高密度トライアングル メッシュ) で速度レンダリングパスを概観してみると、レンダリングの速度が、剛性モーション ブラーに比べて 60% 低下することが分かりました。

メモリ


この機能によって占有されているメモリは一定です。理由は、データを保存している 2 つのテクスチャのサイズが固定されているからです。これによって、再割り当てによるパフォーマンス上のロスとメモリの断片化を防ぐことができます。どのくらいのメモリが使用されているかを調べるためにメモリを追跡します。 stat memory (統計 メモリ) コンソールコマンドを使ってこのデータを見ることができます。

StatMemory.jpg

さまざまなプラットフォームにおけるサポート


当社の実装は 頂点テクスチャ フェッチ に基づいていますが、これは必ずしもすべての GPU で使用可能であるとは限りません。現在、スキン モーション ブラーがサポートされているのは、 Direct3D 9 (ハードウェアがサポートしているならば) と Xbox360 においてです。Playstation 3 のためのサポートは容易に追加できるのですが、極端に遅くなることが予測されます (テクスチャ フェッチの実装と多大な頂点数を想定しています)。今後の DirectX のバージョンについては、いずれサポートされる予定です。モバイル ハードウェアにおけるサポートについては、現在のところ予定されていません (パフォーマンス上の理由です)。

スキン モーション ブラーがサポートされていない場合、エンジンは自動的に 剛性スキン モーション ブラー を使用します。

最適化


  • Xbox360 においては、頂点テクスチャ フェッチのかわりに、vfetch 機能を使用する。
  • 頂点 1 つにつきボーン ルックアップの実行を 4 つ未満にする。(クオリティは低下するものの許容範囲でしょう)
  • オブジェクトが動いていないことが分かっている場合に、ゲームコードを無効化するために、bPerBoneMotionBlur のチェックを実行時に行う。(単純だが、機能させるにはゲームコードに注力する必要がある)
  • PC および Playstation 3 において、静的なブランチングを利用する。エンジンにバグがあって、これを使用することができません。回避策として、float 型のステートをチェックすることによって、機能を無効化することができます。(すなわち、非スキン オブジェクトであっても、速度レンダリング パスにおいて重いシェーダーの負荷を負担することになります)。
  • 現在のところ、テクスチャは、その一部しか使用されていなくても全体がロックされます。
  • すべてのボーンと前のボーンとを比較することによって、速度レンダリングが必要であるかどうかをテストしてください。

便利なコンソール コマンド


MotionBlurSkinning
上記にて説明しています。