最近Substance Painterを導入したので、UnityでPBRマテリアルを使いたくてURPのスタンダードシェーダーを使おうと思っていました。
ところが、調べてみたところスタンダードシェーダーそのものにディゾルブやリムライトのエフェクトをかけることは簡単には出来ないようです。
スタンダードシェーダーにエフェクトを足したシェーダーを作るのにはどうしたらいいのか?というのを調べたところShader Graphでほぼ互換のシェーダーを作ることができるようだったので、実際にやってみました。
この記事はこちらの動画を参考にしつつ自分が使いやすいようにアレンジしたものです。
(動画はSpecularでの作り方が紹介されています)
https://www.youtube.com/watch?v=ObpmdNTgVps
もくじ
基本の設定
まずはLitシェーダーでグラフを作って開きます。

右側にあるFragmentの各項目に必要なパラメーターを全て入力すればスタンダードシェーダー互換の見た目になるので、これを目指して作業していきます。
初期状態ではグレーのツルッとしたマテリアルになっています。

まずはGraph InspectorのGraph Settingsからマテリアルの透明度をどのように扱うのかを設定します。
透明度は以下の3つの中から決めておきます。
- 不透明(Opaque)
- 半透明(Transparent)
- カットアウト(Transparent + Alpha Clippingをオン)

透明な部分が全くない場合はSurface TypeをOpaqueに、一部でも透明・半透明な部分がある場合はTransparentにします。
透明でも、半透明部分がない切り抜き状態のマテリアルを作る場合は更にAlpha Clippingをオンにします。これはしきい値によって完全な透明と不透明を切り替えるものです。
カットアウトは半透明よりパフォーマンスが良いとのことなので、不透明・半透明・カットアウトの使い分けを考えながら決めます。
次に、プロパティのウィンドウの+を押して必要なプロパティを用意します。
これはインスペクターに表示される項目です。

テクスチャ画像はHDRPのMaskのようにRGBAに別データ(メタリック、AO、スムースネス等)を格納したものも使えますが、今回は分かりやすく全部別の画像にしました。
Floatはインスペクター上で調整可能なパラメーターです。
Unity6でのスタンダードシェーダーだとMetallic・Smoothnessを調整できるようになっていますが、今回の例ではNormalとHeightとAOを調整できるようにしてみました。
調整用のプロパティはスライダーにしておくと使いやすいかなと思います。
値が白~黒の範囲になるものであれば、0~1の値になるようにしておきます。

また個人的にTilingとOffsetは必要ないので作っていません。
ここらへんは好みで適宜調整すればいいかなと思います。
ノードを配置
まずは基本のUVです。
モデルの表面に沿ってテクスチャを貼るにはこのようにテクスチャとUVノードをSample Texture 2Dノードにつなぎます。

手始めにこんな感じでテクスチャ(Height以外)とUVを接続しました。
配置は見やすければOKです。

UVノードは全部のテクスチャについて同じように必要になるので、1つのノードを使い回すように作ります。UVの部分に後でHeightの仕組みを追加するので、バラバラに作らないようにしておきます。
一つ一つ、Fragmentへのつなぎ方を見ていきます。
Base Color

Base Colorはとてもシンプルで、テクスチャのRGBAをそのままFragmentのBase Colorに接続すればOKです。
Alpha

設定をTransparentにした場合、Fragmentの一番下にAlphaが出るのでBase ColorのAだけをAlphaに接続します。
カットアウトの場合、さらにAlpha Clip Threshold(しきい値)の項目が出るので値を手打ちで設定します。元のテクスチャの作り方にもよりますが、とりあえず0.5でいいんじゃないかと思います。
Normal Map

Sample Texture 2DのTypeをNormalにしてからRGBAをFragmentのNormalにつなぎます。
もしノーマルマップの強度をインスペクターから調整したい場合、Normal Strengthノードをつないで0~1のfloatの値を設定できるようにしておきます。
Metallic

テクスチャがグレースケールなので、RGBの出力のいずれかをそのままMetallicの出力につなげばOKです。
スタンダードシェーダーだとインスペクターで強度が設定できるようですが、Substance Painterから出力されるテクスチャだと値は金属or非金属の2択らしいのでとりあえず調整はできないようにしています。
もし調整できるようにするなら、Lerpノードを使ってテクスチャのRGBのいずれかと0の間で値を動かせるようにすればいいかなと思います。

Smoothness
これもRGBの出力のいずれかをそのままSmoothnessの出力につなげればOKです。
スタンダードシェーダー用のテクスチャだとMetallicのAにデータが入れられている場合があるようなので、テクスチャがその仕様だった場合はSample Texture 2DのAの出力だけを使います。
なおRoughnessでテクスチャが作られている場合、OneMinusノードを使って値を反転する必要があります。
強度の調整をしたい場合、ツルツルにしたいのかザラザラにしたいのかで変わってきてしまうのでちょっとややこしいかもしれません…。

AO
これも同様、RGBの出力のいずれかをそのままAOにつなげばOKです。
今回は強度をインスペクターから調整できるように作りました。テクスチャそのままと白(AOなし)の間で調整したいので、Lerpノードを使っています。

Emission
Base Colorと同様、テクスチャのRGBAをそのままFragmentのEmissionに接続すればOKです。
ここを加工することで光を点滅させる等色々な使い方ができますが、それはまた別の記事で紹介しようと思います。

Height
Heightは他とは違い、出力をFragmentにつなぐのではなく、UVを少し加工してフェイクの凹凸を作るような処理になります。
UVノードと全てのSample Texture 2Dとの間にParallax Mappingノードをつなぎます。
Heightmapの入力にHeight Mapのテクスチャをつなぎ、Amplitudeにfloatの強度をつなぎます。

この強度の値ですが、参考にした動画の中で最小値を0.5・最大値を8くらいにしておくと良いとのことだったので同じようにしています。
とはいえ最大値8までは必要ない気がしていて、画面を見て動かしながら感覚で決めても良いのかなと思います。

完成!

水面だけは別ですが、それ以外はすべてこのシェーダーで作ってみました!
スタンダードシェーダーとの比較はしていませんが、大体同じような感じで出来ているんじゃないかなと思います。
Shader Graphで作ったので、部分的に加工してディゾルブやリムライトのエフェクトを追加するのがとても簡単です。
そちらは別の記事にしているので個別に見てみてください!





