UE4でMToonを再現したい(1/2)


MToonを再現したい

MToonはVRMファイルで使われている、標準シェーダの1種です。アニメ的表現に特化したものです。

詳細はこちら → https://dwango.github.io/vrm/univrm/shaders/mtoon/

Unity向けに作られているものを、今回はUnrealEngine4で再現していきます。

利用環境はUE4.20.3です。

内容にパラメータの解釈や実装の間違いありましたらすみません。ご指摘いただけると有り難いです。


UE4におけるトゥーンレンダリング

com04さんのまとめページがとても参考になりました。勝手ながら感謝をお伝えします。

https://qiita.com/com04/items/a7895160df8d854fe924

記事のままですが、手法は大別して3種「マテリアル」「ポストプロセスフィルタ」「エンジン改造」があります。


先に結果

今回は「マテリアル」の手法で実装し、陰影には自前のシャドウマップを利用することにしました。

整理して VRM4U のアセットに追加予定です。

描画コストは少々高いかも… とはいえVR機材を扱っているような環境であれば 余裕で動作すると思います。

test6.gif

モデルはこちらからお借りしました → http://3d.nicovideo.jp/works/td32797

要素は押さえられていると思いますが、機能不足はありそう…

以下、つらつらと。


再現にあたって考えていたこと


「主色/陰色」と「輪郭線の幅と色」を反映したい

これができれば8割方完成な気持ち。


  • 主色/陰色について


    • 描画時に明確に陰・影領域を判別できている必要がある

    • ShadingShift(主色の面積を増減させる)に対応するため、中間値も欲しい



  • 輪郭線の幅と色について


    • なんとなく背面法で良さそう

    • パラメータ参照が多いので、ポストプロセスだとどこかで手詰まりしそうな予感がする…




陰と影 を判別したい

※ここ言う「陰」「影」を図解しておきます。

1が陰で、2が影です。わかりにくくてすみません…

image.png


  • 陰と影


    • 検索すると こんな素敵な技が紹介されている。これで解決かと思いきや…



    • 陰は自前で計算できる。影を解決するにはShadowmap(厳密にはLightAttenuationTexture)を参照する必要がある


      • プラグインで配布したいので できればエンジン改造は避けたい

      • そういえばUnityでShadowmapを自前実装してる方がいたのを思い出した http://www.shibuya24.info/entry/shadowmap

      • 自分も作ってみよう






他のMToonパラメータとの相性は…

以下に表でまとめました。Unityでパラメータを触りながらだと わかりやすいかも。

この赤枠で囲った部分のパラメータです。

この画面はUnityです

image.png

実装の手法として以下の3つを比較検討しました。厳密にはそれぞれforward/deferredで動作が分かれます。


  • material+自前shadowmap(今回使った手法)


    • 自前のshadowmapを作成し、マテリアルで参照しながらシェーディングを行う手法



  • material(+postprocess)


    • マテリアルでシェーディングしたりGBufferへ書き込みを行い、ポストプロセスで合成したり輪郭線描画を行う手法



  • postprocessのみ


    • マテリアルは基本的な物理シェーディングを行い、ポストプロセスで加工を行う手法




Color

主色・陰色。

手法
LitColor,Alpha
ShadeColor

material+自前shadowmap

material(+postprocess)


色指定の格納先に工夫が必要。Shadowmap参照可であれば○

postprocessのみ

BaseColorに格納

色指定の格納先に工夫が必要


Lit & ShadeMixing

主色領域の調整・陰のボケ足・影の影響度

手法
ShadingShift
ShadingToony
ShadowReceiveMultiplier
Lit&ShadeMixingMultiplier

material+自前shadowmap



?
未検証

material(+postprocess)



陰と影が判別できない。Shadowmap参照可であれば○
?

postprocessのみ
△※
GBufferのNormalとライト向きで計算すれば○

左と同じ
×
?

※厳密にはライト向きとノーマルの内積を-1~+1の値で取得する必要がある。


LightColor

主光源の影響度・GIの影響度

どの手法でも、カスタムノードに記述すれば対応可能。詳しくは後半で。


Outline

輪郭線の出し方・線の太さ・ライト影響受けるか・線の色・ライト影響度

手法
Mode
Width
ColorMode
Color
LightMix

material+自前shadowmap
背面法




material(+postprocess
背面法




postprocessのみ

World方式はGbufferのNormalから算出

幅をGBuffer格納


色をGBuffer格納

左と同じ


 いざ実装

後半へ

https://qiita.com/ruyo/items/71a3f2f694d2853b3f1e