この記事は前回の記事から続いた内容のものとなります。
セルシェーディング手法については前回の記事を参考にしてください。
さて、前回作成したものには大きな問題がひとつあります。
"シーン全体に対してセルシェーディングがかかってしまう"という点です。
これにより細かい問題が色々と発生します。まず背景のSkySphereがライティングの影響を受けて、真っ黒な状態となってしまっていました。まずはこの問題を対処してみます。
背景が真っ黒になってしまうのを修正する
前回作成したセルシェーディングでは背景が真っ黒になっており、SkySphereがライティングにより描画されない状態になっています。
これをなんとかするには、遠景のSkySphereをマスクして、ライティング対象外にしてしまう必要があります。
前回作成したマテリアルの先で"if"ノードを使って分岐をします。
"Constant"ノードに"100000.0"という大きめの値を設定し、"SceneTexture"の"SceneDepth"情報を取り出してRチャンネルの2つの情報を比較します。
その結果、Aの方が大きい場合には通常のセルシェーディングを行い、Bの方が大きい場合にはセルシェーディングのかからない生のRGB情報を渡します。
これにより、距離的にとても奥にあるオブジェクトに対してはセルシェーディングをしないので、遠景のSkySphereは通常のシェーディングを行います。
遠景のSkySphereが描画されました。これでもう通常用途では困らないはずです。
カスタムデプスでセルシェーディング対象を分ける
今度はセルシェーディングをかけたいものとそうでないものを分けて描画してみます。
ここで、カスタムデプス(Custom Depth)と呼ばれるものを利用します。カスタムデプスは通常のデプス(深度)とは別に独自のデプス情報を作りだし、それを別用途で利用できるというものです。
これを利用するにはスタティックメッシュかスケルタルメッシュの"Rendering"カテゴリーにある、"Render CustomDepth Pass"というプロパティにチェックをつける必要があります。
これで独自のカスタムデプス情報をとることができるようになりました。
以下のようにノードマテリアルを作ります。
"Scene Depth"ノードから深度情報を取り、"Scene Texture"ノードの"CustomeDepth"からRチャンネルだけ取り出したものを"SphereMask"ノードで球状のマスク情報を作りだします。
これでレンダリングすると…
見事にカスタムデプスをもったオブジェクトだけをマスクすることができました。あとはこれを既存の情報と合成させることにより、別々のシェーディング情報を利用した画面を作ることができます。
先程の最終結果の後に"Lerp"ノードを入れています。これでふたつの絵を線形補間し、中間的な絵を作りだします。
カスタムデプスで取り出した情報を元々のセルシェーディングなしの情報の絵をかけ算し、セルシェーディングした情報の絵とLerpで補間をかけるとそれぞれの絵が合成されます。
少々わかりにくいかもしれませんが、手前のミクのみカスタムデプスにより通常のシェーディングをした状態になっています。
それぞれの比較画像です。
他のオブジェクトはセルシェーディングのままなので、特定のオブジェクトに対してのみ、カスタムデプスにより独自のシェーディングになっていることがわかります。
これを上手く使えば、違う絵作りをしたまま、同一世界の中に存在させるといったことが可能です。
また必要なものに対してのみのエフェクト効果をかけるということ等、その活用方法は無限大にあります。
ぜひ有効に活用してください!
最後に一連の記事とセルシェーディングする前とした後の画像を貼っておく。これだけでも面白いことができるのでぜひお試しを。#UE4Studyhttps://t.co/E6kP0cJSB0https://t.co/So5Bx1DvHu pic.twitter.com/0LhyUpct9F
— alwei (@aizen76) May 30, 2016
追記
最後がLerpだとどうしても元のシェーディングが再現できていなかったのが解決。これで完全に複数のシェーディングを一枚の絵に載せることができる。いわゆるレイヤーの上にもう一枚絵を重ねたような状態。#UE4Study pic.twitter.com/Je6BX1MlC9
— alwei (@aizen76) May 30, 2016
Lerpノードでは複数のシェーディングをブレンドしてしまいますが、上記ツイート画像のように組むと完全に複数の絵を一枚の絵に重ねることができます。