最初に
どうも、ろっさむです。**
今回は以下のUE4の学習コースでUE4でのポストプロセスを用いたアウトラインの作り方を学んだので自分用に残しておきます。
https://www.unrealengine.com/ja/onlinelearning-courses/stylize-renders-with-post-process-materials
シーンの深度の確認方法
作成には部分的にシーン深度Gバッファからの描画を利用するため、まずはゲームシーンの深度が確認できる方法を見ておきましょう。。
以下のように設定すると、暗い値は近くのもの、明るい値は遠くのものを表すようになります。
マテリアルで行う
まずはマテリアルの Material Domain
をPost Process
に変更しておきます。
次にDetails > Post Process Material > Blendable Location
をBefore Tonemapping(トーンマッピング前)
に設定します。
ちなみにここの項目の設定一覧は以下の通りです。
-
After Tonemapping(トーンマッピング後)
がデフォルトGバッファをポストプロセスパイプラインの最後にローダイナミックレンジ空間から抽出する。 -
Before Tonemapping(トーンマッピング前)
はベースカラーをハイダイナミックレンジ空間から抽出する。 -
Before Translucency(透過処理前)
は画像に透過処理が適用される前に行われる。 -
Replacing the Tonemapper(トーンマッパーの置き換え)
はトーンマッパーを完全に無効にする。 -
SSR Input(スクリーンスペース反射入力)
はGバッファなら何でもスクリーンスペース反射として使用する。
SceneTexture:SceneDepth

- Size:画像の解像度
- InvSize:エッジ検出やソーベル演算を可能にして、アウトラインを描画するためのもの。
UE4の画面空間ではUV座標が赤と緑のベクターに格納されています。InvSizeにRGだけの2ベクターを乗算すると、ピクセルのレンダリング先を操作できるようになります。この2成分ベクターがシーン深度とワールド法線情報を何ピクセル分オフセットするのかを変更できます。

UV座標として認識させるためにはテクスチャ座標ノード(TexCoord
)を追加します。また変更前のシーンデプスから減算する必要もあります。繋げると以下のようなノードになります。
この状態のマテリアルを適用すると以下のような状態になります。

他にも、ベースカラーを黒い値の場所にレンダリングする必要があります。そのために線形補間ノードを作成します。
法線マップで行う場合
ワールド空間法線を使用する方法です。法線マップを選択する理由は、ワールド空間の法線マップはオブジェクトの移動ではなくカメラとともに移動するので、正しいエッジ輪郭を取得できるからです。
Lit > WorldNormal
で表示される画像は全法線マップの合計となります。ワールド空間法線が表しているのはマテリアルに適用されているタンジェント空間法線マップを計算した後のワールド内で特定のピクセルが向いている方向(つまりベクター)で、RGBはXYZとなります。
このデータはレンダリング段階で計算され、ディファードレンダラによってライティング計算のGバッファとして使用されます。このGバッファデータをポストプロセスマテリアルで使用してシーンの法線に効果をレンダリングできます。
ロジックとしてはシーン深度のものと全く同じものを使用する。
SceneTexture:WorldNormal
のScene Texture Id
をWorldNormal
に変えることで法線の指定部をシェーディング可能となります。
アウトラインは黒なので最後に彩度を下げる処理を入れましょう。

Fraction
が0だと彩度は低下せず、フルカラーになります。1だと完全に低下します。
画像のちらつきに対処
ちらつきはポリゴンラインが原因となります。
ライティングのみにすると諸々確認しやすくなります。
ポリゴンラインの数値に対して、乗算を行い、画面に対してどの程度効果をかけるかを決めることができます。(掛ける値をパラメータに変換することで、リアルタイムでレンダリングの確認を行うことができます)

コントラストを追加する
アウトラインをクリーンアップすることができます。コントラストはPower(累乗)
ノードを使用しましょう。これは指数関数演算で、基数を受け取り指数乗します。このノードがコントラストの処理に最適な理由は数学演算の方法にあります。どのような値が基数に設定されても指数によってどのていど基数が暗くなるのか明るくなるかが決まるようです。基本的に暗い値はより暗く、明るい値はより明るくなります。程度は指数によって決まってきます。

太さを調節する
Gバッファのルックアップ時のオフセットの大きさを操作します。現在の状態だとGバッファをそれぞれの方向に1ピクセル移動してポリゴンと法線の上下左右にラインを描画します。この移動数値を変更することでアウトラインの太さを変更できます。

指定のアセットにのみ効果を適用する
キャラクターをマスクしてベースカラーだけをレンダリングし、環境にはPBRライティングでレンダリングします。
ここではSceneTexture:CustomDepth
を使用します。

このノードで可能なのはCustom Depth
トグルがオンの状態でレンダリングされるオブジェクトを検索してそのアセットだけをレンダリングすることです。トグルをオンにするにはステージ上のスケルタルメッシュのDetails
からCustom Depth
を検索します。

このノードを使って分離し、選択的にレンダリングできます。
カスタム深度からシーン深度を減算するとキャラクターのマスクができあがります。
深度を逆にするにはOneMinus
を使用しましょう。このノードは基本的に反転に使います。

マテリアルのBlendale Location
を**Before Translucency(透過処理前)
に変更する**必要もあります。被写界深度はレンダリングに透過処理を必要とするようです
アウトライン処理の最後にこの処理を付け足します。

アウトラインの太さを変えた場合、輪郭部分は変わらずメッシュ内部の境界線だけが太くなります。

理由としてはマテリアルに張り付けて効果上にオーバーレイするアルファとして使用しているマスクがポリゴンアウトラインのオフセットと連携していないため。連携させると、オフセットの値(アウトラインの太さ)に応じてキャラクターのマスクが収縮したり増幅し、アウトライン自体も変化します。

アウトラインを被写界深度の下にレンダリングしたい場合は、マテリアルのBlendable Location
からBefore Translucency
に変更しましょう。

これでキャラクターだけにアウトラインを実装するマテリアルができました。
またこのポストプロセスではマスク外の周囲の環境が暗くなってしまうのでその場合にはマスク外の環境を乗算して明るくしてください。
