ほげたつブログ

プログラムとアニメーションをかじって生きてる

UE4でカメラがキャラクターに近付き過ぎたら半透明にする

METAL GEAR SOLID V: The Phantom Pain をやってて、キャラクターに近付いたらディザリングで半透明っぽくして背景を見せてあげるのが丁寧だなって思ったのでUE4でやってみました。


MGS5のスクリーンショットです。

f:id:hogetatu:20151015221333p:plain


今回作ってみたものはこんな感じになります。

f:id:hogetatu:20151015223047p:plain

ディザリングとは

詳しくはもんしょさんの記事の冒頭で説明されています。

もんしょの巣穴blog [UE4] とりとめのないマテリアルネタ色々

つまりは不透明な物体を細かくドット抜きすることで、擬似的な半透明を表現する手法ですね。
UE4で採用されている Deferred Rendering では半透明を描画するときのコストが大きくなってしまうため、コストを抑えつつ半透明表現をしたい場合にはとても有用です。

実装方法

まず、グレーマンに使われているマテリアル(M_UE4Man_Body)を開きます。
いくつかのマテリアルファンクションを経由して、最終的に「M_UE4Man_Body」というノードに繋がっているのが確認できますね。
ではディザリングするために OpacityMask を変更する必要があるため、その直前に一つマテリアルファンクションを追加します。

f:id:hogetatu:20151015224001p:plain

やっていることはシンプルで、PixelDepth でピクセル深度を取り、距離によって DitherTemporalAA の AlphaThreshold に 0~1 の間で透明度を渡してあげているだけです。
あとは DitherTemporalAA が上手い感じにディザリングしてくれます。
その結果を OpacityMask を上書きする MatLayerBlend_OverrideOpacityMask に渡しています。

※ちなみにさっきMGS5の動画を見ていたら微妙に実装が違いそう(あっちはキャラクターのディザ抜きが均等にかかる)でした。
まぁこっちの手法の方がマテリアルの変更のみでお手軽感はあるので、完全に同じにしたいならBP側でカメラとアクターの距離をダイナミックパラメータとして入力して使用すればよいかと思います。

こんな感じになりました

youtu.be