[UE4] PostProcessでObjectにOutlineをつける~前編~[UE4.18]

#概要
UE4でLevel内のオブジェクトにOutlineを付けるための必要最低限の手順をまとめています。後編では、前編の内容を基に、より実践的な実装を行います。以下が前編での完成イメージです。手前のオブジェクトに黒いOutlineが描画されています。
![10.jpg](https://qiita-image-store.s3.amazonaws.com/0/245572/e00a945c-e843-20f0-7c5d-78e2b4700779.jpeg)


#下準備
まずは、Outlineを表示するために必要な準備を行います。
・PostProcessVolumeがレベル内に配置されているかを確認、されていなければ配置する。
・ProjectSetting→PostProcessing→CustomDepthStencilPassを”Enable with Stencil”に設定
※設定しないと次の設定が反映されないので注意
・Outlineを付けたいオブジェクトを配置し以下のように設定する。（下図赤線部分2箇所）
![00.jpg](https://qiita-image-store.s3.amazonaws.com/0/245572/ce5db29d-d8ff-7f7e-6899-07d3eb4fd6f2.jpeg)

#反映確認
　・画面左上のライティング→バッファを可視化→カスタム深度・カスタムステンシルを選択し反映されているか確認（下図参照）
![01.jpg](https://qiita-image-store.s3.amazonaws.com/0/245572/672baa1e-b2e4-7b62-ced2-17989a770ecf.jpeg)

カスタム深度
![02.jpg](https://qiita-image-store.s3.amazonaws.com/0/245572/e5af19cc-3838-ca13-96da-8da59efbb9b8.jpeg)

カスタムステンシル
![03.jpg](https://qiita-image-store.s3.amazonaws.com/0/245572/1089c3dc-1681-8f8d-bc9b-3095b3c402ce.jpeg)
上図では、CustomDepthStencilValueの値が表示されます。（1~255の中の値を指定）

・PostProcessVolumeの動作確認
　・PostProcessVolume→RenderingFeatures→PostProcessMaterial→ArrayをAdd
　・新規マテリアル”M_Outline”を作成、マテリアル属性をPostProcessにして上記の箇所に設定し、画面に変化が生じればok!（後でこのマテリアルに追加実装を行います）

#Outline描画用のMaterialを作成
ここからが本題です。PostProcessを画面全体に適用することができたので、次はオブジェクトの輪郭にのみ適用（=Outlineを描画）されるようにします。
結論だけ述べると、SobelFilterを用いてエッジ（境界）検出を行います。画像処理の知識はあまり無いので説明は省きまが、今回の場合だと、周囲との深度値の差が大きい部分を見つけて、その部分に特定の処理を施します。興味のある人は調べてください．．．
では、必要なアセットを作成していきます。必要なアセットはPostProcessVolumeに設定するOutline描画用のMaterial, MaterialFunctionです。
　・口述する”MF_GetSobelValue”を用いて、最終的なエミッシブカラーを決定するマテリアル ”M_Outline”
![06.jpg](https://qiita-image-store.s3.amazonaws.com/0/245572/2a97c79e-8720-79eb-2e27-c8625e4b2002.jpeg)

　・Offset付きで深度値を得る関数　”MF_GetDepth”
![04.jpg](https://qiita-image-store.s3.amazonaws.com/0/245572/ba187371-a28c-148d-4cbd-a368c4ecfd27.jpeg)

　・SobelFilterの結果を得る関数 ”MF_GetSobelValue”
![05.jpg](https://qiita-image-store.s3.amazonaws.com/0/245572/19104b22-8b7e-f087-544a-a8cc504efda8.jpeg)

これらのマテリアル、関数に関する説明は他のサイトでも多々見受けられるので、そちらに丸投げします。以下は、参考にしたサイトです。
・http://monsho.blog63.fc2.com/blog-entry-127.html
・http://www.michalorzelek.com/blog/tutorial-creating-outline-effect-around-objects/

#Materialを適用
早速、このM_OutlineをPostProcessVolumeに適用してみます。エッジ部分に黒い線（Outline）が描画されていることが分かりますね。深度値の差が微妙（小さい）な部分は描画されていなかったり、薄い黒線になっていることも分かります。
![07.jpg](https://qiita-image-store.s3.amazonaws.com/0/245572/c1f2ad20-3419-a449-1977-9259ce3f6b04.jpeg)

このことは、実際にシーンの深度値を可視化すると分かりやすいです。人間の目で見ても、エッジ部分が判別しづらい箇所が多く見受けられます。逆に、エッジ部分がはっきりとしている部分に関しては、Outlineが描画されていることが分かります。（下図は、同画面のシーン深度を可視化したもの）
![08.jpg](https://qiita-image-store.s3.amazonaws.com/0/245572/3c2f7b03-87d8-e0f7-6af7-ca6028a0239c.jpeg)


しかし、これでは使い物にならないので、もう少し手を加えます。簡単に言えば、区別したいオブジェクト同士の深度値の差を、もっともっともっと明確にしてやれば良い訳です。
そこで、記事の初めにカスタム深度orカスタムステンシルを描画した図をもう一度見てください。良い感じに明確にオブジェクトが区別しやすそうな状態ですね。次はこれらの値（カスタム深度・カスタムステンシル）を用いてエッジ検出を行います。
以下が、修正を加えたMF_GetDepthです。SceneDepth（シーン深度）の代わりにカスタム深度orカスタムステンシルの値を用いることで特定のオブジェクトのみに対してOutlineを描画できていることが分かります。
![09.jpg](https://qiita-image-store.s3.amazonaws.com/0/245572/2c0fd4ee-c57c-e3ce-d3c5-c7d714e74a18.jpeg)

![10.jpg](https://qiita-image-store.s3.amazonaws.com/0/245572/3da99871-e90b-dda3-b9d1-7b4bad4f1fcc.jpeg)

今回はここで終わります。しかし、このままでは少し味気ないのですね．．．
次回はこれらを基に、もう少し手を加えていきたいと思います。
次回 -> https://qiita.com/kanurapoison/items/930e1400f3fb8a527cb8