目まぐるしく変わる Unity の Universal RP の実装
その実装に合わせてカスタム MasterNode を作り替え続ける備忘録である
手順
Unity 2019.3.0b6 を落して、テンプレートに Universal RP を選ぼう

起動すると次の画面になりますね

Create Shader をチェック

Toon Graph 項目を増やす
Library/PackageCache フォルダを見ます

この三つのフォルダを Packages フォルダへ移動しておきます。

で PBR Graph で文字列検索して次の通り Toon Graph を作る項目を追加します。

いえー、増えた

ToonMasterNode クラス作ろう
次のファイルを作成して
"Packages\com.unity.shadergraph@7.1.2\Editor\Data\MasterNodes\IToonSubShader.cs"
このように実装します。
同じフォルダにある PBRMasterNode.cs ファイルを複製して ToonMasterNode.cs とし…
ファイル内の PBR を Toon に全部置換します
次のファイルを同じフォルダにある PBRSettingsView.cs を複製して作ります
Packages\com.unity.shadergraph@7.1.2\Editor\Drawing\Views\ToonSettingsView.cs
ファイル内の PBR を Toon に全部置換します
次のファイルも同様に、同じ階層の PBRMasterGUI.cs を複製して作ります。
Packages\com.unity.shadergraph@7.1.2\Editor\ShaderGUI\ToonMasterGUI.cs
ファイル内の PBR を Toon に全部置換します
これで、最初の UI メニュー項目の変更箇所を次のように ToonMasterNode に置き換え
[MenuItem("Assets/Create/Shader/Toon Graph", false, 208)] public static void CreateToonMasterMaterialGraph() { GraphUtil.CreateNewGraph(new ToonMasterNode()); }
これで壊れた Toon Master Node を Shader Graph で作れるようになりました

UniversalPBRSubShader を複製する
次のファイルを複製
Packages\com.unity.render-pipelines.universal@7.1.2\Editor\ShaderGraph\SubShaders\UniversalPBRSubShader.cs
UniversalToonSubShader.csファイルにリネームして
ファイル内の PBR を Toon に全部置換します(小文字の pbr は残す)
次のパスのファイルを同じフォルダのPBRForwardPass.hlslを複製して作ります
Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/ToonForwardPass.hlsl
ファイル内の PBR を Toon に全部置換します(一か所だけ)
次のパスのファイルを同じフォルダのPBR2DPass.hlslを複製して作ります
Packages\com.unity.render-pipelines.universal@7.1.2\Editor\ShaderGraph\Includes\Toon2DPass.hlsl
ファイル内に PBR はないので置換は不要
次のファイル内を見ましょう
Packages\com.unity.render-pipelines.universal@7.1.2\ShaderLibrary\Lighting.hlsl
UniversalFragmentPBR 関数をコピーして UniversalFragmentToon 関数を次の通り追加します
half4 UniversalFragmentToon(InputData inputData, half3 albedo, half metallic, half3 specular,
half smoothness, half occlusion, half3 emission, half alpha)
{
BRDFData brdfData;
InitializeBRDFData(albedo, metallic, specular, smoothness, alpha, brdfData);
Light mainLight = GetMainLight(inputData.shadowCoord);
MixRealtimeAndBakedGI(mainLight, inputData.normalWS, inputData.bakedGI, half4(0, 0, 0, 0));
half3 color = GlobalIllumination(brdfData, inputData.bakedGI, occlusion, inputData.normalWS, inputData.viewDirectionWS);
color += LightingPhysicallyBased(brdfData, mainLight, inputData.normalWS, inputData.viewDirectionWS);
#ifdef _ADDITIONAL_LIGHTS
uint pixelLightCount = GetAdditionalLightsCount();
for (uint lightIndex = 0u; lightIndex < pixelLightCount; ++lightIndex)
{
Light light = GetAdditionalLight(lightIndex, inputData.positionWS);
color += LightingPhysicallyBased(brdfData, light, inputData.normalWS, inputData.viewDirectionWS);
}
#endif
#ifdef _ADDITIONAL_LIGHTS_VERTEX
color += inputData.vertexLighting * brdfData.diffuse;
#endif
color += emission;
return half4(color, alpha);
}
Unity にフォーカスを与えると Shader ビルドが走るので、先ほどの壊れた Shader Graph が正常な Shader として扱われるようになります

おまけ
Lighting.hlsl の UniversalFragmentToon を次の通り emissionを消してみました
half4 UniversalFragmentToon(InputData inputData, half3 albedo, half metallic, half3 specular,
half smoothness, half occlusion, half3 emission, half alpha)
{
BRDFData brdfData;
InitializeBRDFData(albedo, metallic, specular, smoothness, alpha, brdfData);
Light mainLight = GetMainLight(inputData.shadowCoord);
MixRealtimeAndBakedGI(mainLight, inputData.normalWS, inputData.bakedGI, half4(0, 0, 0, 0));
half3 color = GlobalIllumination(brdfData, inputData.bakedGI, occlusion, inputData.normalWS, inputData.viewDirectionWS);
color += LightingPhysicallyBased(brdfData, mainLight, inputData.normalWS, inputData.viewDirectionWS);
uint pixelLightCount = GetAdditionalLightsCount();
for (uint lightIndex = 0u; lightIndex < pixelLightCount; ++lightIndex)
{
Light light = GetAdditionalLight(lightIndex, inputData.positionWS);
color += LightingPhysicallyBased(brdfData, light, inputData.normalWS, inputData.viewDirectionWS);
}
color += inputData.vertexLighting * brdfData.diffuse;
return half4(color, alpha);
}

まとめ
PBR シェーダを複製していき Toon MasterNode を作って Shader Graph 経由で作成、編集できることを示しました。
頑張って Shader の実装を書き換えていけば Toon の Master Node が作れるってわけです。
ここまでの知識を次の知見につなげれば、なんとかなりそう…
simplestar-tech.hatenablog.com
v7.1.2 でも動く Toon Shader Graph の完成に期待(未来の自分頑張れ)