Substance Designerでシェーダを書いてみた話

ちょっと遅くなりましたが、先々週にあったSubstance Designerゆるゆる会で作成したマテリアルについてです。

ゆるゆる会のテーマはスタイライズドでした。
私が選んだのは『あつまれ どうぶつの森』に出てくる床の1つである”みなものゆか”でした。

f:id:monsho:20201101141808p:plain

この床はゲーム中で動きます。また、カメラを動かすと白っぽい部分(コースティクス的な?)と青い部分に視差があることがわかります。
いわゆるParallax Mappingを施されているテクスチャです。
で、まずは普通にそれっぽく再現するところから始めてみました。出来たのがこれ。

f:id:monsho:20201101143104p:plain

色味とかに差はありますが、まあ似た感じになったかなと。
しかし物足りない。
原因は2つ。動かない。視差がない。
え?再現性が低い?ごめんなさい…

とにかくこの2つをなんとかしたい。
動かない点についてはSubstance Designerの性質上仕方ない部分もありますが、timeパラメータを使って対応すると確認が難しい上に、パラメータが変更されるとテクスチャが生成し直しになるので時間がかかります。
これくらいのマテリアルならそこまで遅くはないものの、なめらかに動いているようには見えません。

もう1つの視差がない点については、Substance DesignerにはParallax Occlusion Mappingが存在しています。
これを使えば再現できるかというと、これは無理です。
POMは高さ方向でOcclusion、つまり遮蔽されてしまうので、例えば白い部分を高くするようにしてしまうとその部分が山になっているように見えてしまいます。

通常、この手の表現はシェーダ側で行います。UE4のマテリアルなんかが最終出力はシェーダですね。
しかしSubstance Designerの最終出力はテクスチャです。シェーダではありません。
テクスチャというのはシェーダで利用するリソースの1つでしかありません。実際、Substance Designerでもシェーダは使われていて、3DビューメニューのMaterialからプリセットのシェーダを選択することが出来ます。
しかしこの中にはみなものゆかを表現できるシェーダが存在しません。

ないなら作れ!

というわけで作ってみました。

f:id:monsho:20201101150925p:plain

似たような感じではありますが、カメラを動かすと水面と水底に視差があるように見えます。
そして水底の影が水面のコースティクスを参照するようになっています。
このように、Substance Designerは(Painterもですが)自作のシェーダを使用することが出来ます。

シェーダの解説は行いませんが、作成されているシェーダとこのマテリアルはゆるゆる会のTrelloにアップロードされていますので、興味ある人は試してみてください。

trello.com

Substance DesignerのシェーダはGLSLで書く必要があります。書けるのはオブジェクト表面用のシェーダだけで、ポストプロセス的なものは出来ません。マルチパスレンダリングも無理。
しかし環境マップやライト情報も取得できるのでライティングも出来ます。カメラ情報も取得できるのでカメラ角度に応じた変化も対応できます。

とはいえ、書き方やパラメータ設定の仕方はGLSLを知ってるだけでは難しいでしょう。
そんなあなたに朗報です。なんと、ビルトインシェーダのコードが読めます!
以下のフォルダを開いてみてください。

$(SubstanceDesignerインストールフォルダ)\resources\view3d\shaders

ここにビルトインされたシェーダが入っています。
このフォルダ直下にある.glslfxファイルはどのシェーダステージにどのシェーダコードを利用するか、パラメータはどんな名前で設定するか、テクスチャはどんなIDで設定するかといった内容を記述します。
実際のシェーダコードはこのフォルダ内の各マテリアル名のフォルダにあります。
頂点シェーダやテッセレーションはあまりいじることはないかもしれませんが、その場合はcommonフォルダ内にデフォルトのシェーダがあるのでそれを使うことが出来ます。
もちろん、頂点シェーダも作成することも可能ですが、多くの場合はそこまでする必要はないでしょう。

シェーダが書けるという点ではSubstance Painterでも書くことが出来ますが、SDとの互換性がなさそうな感じです。
なぜそこに互換性がないのか…謎。

もしシェーダの内容に質問などがあるようでしたらコメントなりいただければ追記しますが、特に難しいことはしてないです。多分。

でまあ、こんな感じでシェーダを書くことに意味があるのかという話をしてしまうと、多分ほとんどの場合では必要ないです。
しかしゲームエンジンを使うにしろインハウスエンジンを使うにしろSubstance DesignerやSubstance Painterと同じ結果にするというのはなかなか難しいです。
ポストプロセスの問題もありますが、ライティングモデルが別だったり、それこそトゥーンシェーダのようなPBRではないライティングを行っているものもあるでしょう。
そういった違いが制作効率を下げるような状況であれば十分使えるはずです。
とはいえ、SPならともかく、SDで使うことはほとんどないと思います。
こんな事もできるよ~という程度のものとして覚えておくくらいで良いでしょう。