simplestarの技術ブログ

目的を書いて、思想と試行、結果と考察、そして具体的な手段を記録します。

Unity:VRMのMToonマテリアルをLWRPのShaderGraphで、その2

こちらの記事の続きです。
simplestar-tech.hatenablog.com

Unity Shader Graph で VRM の MToon 表現を LWRP で実現してみます。
カスタム Master Node の作り方まで確認できたので、具体的な Toon シェーディングコードを
GitHub - you-ri/LiliumToonGraph: ShaderGraph が使える ToonShader (LWRP)
こちらの実装から写経・理解してみます。

Lighting.hlsl に追加するべきは、まずは LightingToon 関数で、これが4つの引数をとります。
そこでさらに独自関数が呼ばれていました。DirectToonBDRF コレの定義を追います。
実装は Minimalist CookTorrance BRDF とのこと

一旦これで Toon の関数が揃いました。

変更前と後で見た目を比較してみます。

f:id:simplestar_tech:20190715132515p:plain
PRB そのままの絵
f:id:simplestar_tech:20190715132840p:plain
LightingToon に置き換えた Shader の絵(実際はクックトランスシェーダー)

次は GlobalIlluminationToon に GlobalIllumination を置き換えます

それは GlossyEnvironmentReflectionToon, EnvironmentToon で構成されていたので、それらも定義します。
適用した後の絵がこちら

f:id:simplestar_tech:20190715133718p:plain
GlobalIlluminationToon の適用結果

続いて LightingToonyBased を導入します。

f:id:simplestar_tech:20190715134936p:plain
ToonyBased を入れたのですが、変わりました?なんか暗いですね。

コレで最後かな? ToonyIntensity を導入します。

f:id:simplestar_tech:20190715140602p:plain
ToonyIntensity を導入した結果

暗に型変換するエラーがいくつかありましたので解決しました。
例えば戻り値が half3 の関数なのに、利用時に half として扱うとか

あれ、アウトラインはどうやっているんだろう?

lightweightToonExtraPasses.template ファイルの差異を見たが、得なし
lightweightToonForwardPass.template ファイルの差異を見た

以下の変数定義が追加されている

		float ToonyLighting = 1;

		float3 Shade = float3(0.25, 0.25, 0.25);
		float ShadeShift = 0.5;
		float ShadeToony = 1;

ほか LightweightFragmentToon に必要とされる引数の数が変わったので、hlsl の方を修正する

また Pass が一つ追加されていて、こちらはアウトラインの追加となっていた。

一通り見てからのコンパイル

うわ、エラー 2つ
一つ潰して 3つに

OutlineWidth というものを外部から利用している模様

ここで ToonMasterNode クラスの方を修正することにした
以下のパラメータを追加

        public const string ShadeSlotName = "Shade";
        public const string ShadeShiftSlotName = "ShadeShift";
        public const string ShadeToonySlotName = "ShadeToony";
        public const string OutlineWidthSlotName = "OutlineWidth";
        public const string ToonyLightingSlotName = "ToonyLighting";

他にもスロットを追加したところ、Master Node のスロットだけ増えました。

f:id:simplestar_tech:20190715151909p:plain
Master Node のスロットだけ増えた。依然としてエラー

最後に直すべきは…class LightWeightToonSubShader : IToonSubShaderですね。
記述の足りていない OutlineWidth などを追加していきます。

            PixelShaderSlots = new List<int>
            {
                ToonMasterNode.AlbedoSlotId,
                ToonMasterNode.NormalSlotId,
                ToonMasterNode.EmissionSlotId,
                ToonMasterNode.MetallicSlotId,
                ToonMasterNode.SmoothnessSlotId,
                ToonMasterNode.OcclusionSlotId,
                ToonMasterNode.AlphaSlotId,
                ToonMasterNode.AlphaThresholdSlotId,
                ToonMasterNode.ShadeSlotId,
                ToonMasterNode.ShadeShiftSlotId,
                ToonMasterNode.ShadeToonySlotId,
                ToonMasterNode.ToonyLightingSlotId
            },
            VertexShaderSlots = new List<int>()
            {
                ToonMasterNode.PositionSlotId,
                ToonMasterNode.OutlineWidthSlotId
            }

コレなんだろう
subShader.Append("CustomEditor \"UnityEditor.ShaderGraph.ToonMasterGUI\"");
後で足さないとな…

ひとまずシェーダーエラーを片付けたら絵が出ました。

f:id:simplestar_tech:20190715155040p:plain
outline 全部入りのディフォルト値の絵

試験的に UnityChan に当てるとこんな感じ

f:id:simplestar_tech:20190715161553p:plain
上記のディフォルト値のシェーダを適用

思った絵にならないな

f:id:simplestar_tech:20190715165850p:plain
ライティングの設定に問題?

あ、Normal Sampler を Type Default にしたままだった、そりゃ法線がおかしくなるかな
修正後がこちら

f:id:simplestar_tech:20190715173241p:plain
最後まで読むとできるようになる絵

f:id:simplestar_tech:20190715173407p:plain
カスタムノードから生やした Shader Graph はこちらです。

LWRP で MainColor, ShadeColor を指定できる Toon マテリアル表現ができるようになりました。
あとはこのシェーダを使って UniVRM で生成したキャラクターを確認できればよいのかな?

続く

ユニティちゃんライセンス

この作品はユニティちゃんライセンス条項の元に提供されています