【Unity】初めて『シェーダーグラフ』でシェーダーを学んでみる 応用編.①
こんにちは。
シェーダーを一度も触った事のないデザイナーが、Unityの「シェーダーグラフ」を使ってシェーダーを学んでみるシリーズ。
このシリーズでは、公式のサンプルシーンを元に僕がシェーダーグラフで学んだ事を解説していきます。
シェーダー学習初という事もあり、たくさんの方のブログを拝見し、勉強させていただきました。
このシリーズには僕が参考にさせていただいたブログのリンクを貼らせていただいておりますので、そちらも併せて読んでいただくとより一層理解が深まるかと思います。
今回は「応用編.①」という事で、公式のサンプルシーンにある上の画像の女神像が溶けて消えていくシェーダーがどのように作られているかを解説します。
まずは、こちらのページから今回使用する「ShaderGraphExamples-master」プロジェクトをダウンロードして下さい。
ダウンロードが出来たらプロジェクトを開き、「Dissolve」のシーンを開いて下さい。
シーンは開けましたか?
それではシェーダーの解説に入ります。
シェーダーを開く
サンプルのシーンを開いたら、「Dissolve」というシェーダーファイルをダブルクリックして下さい。
するとシェーダーグラフのエディターが立ち上がります。
※Propertyにコンバートされていたノードは「Convert To Inline Node」で元に戻してあります。
全体の流れ
個々のノードを見ていく前に、このシェーダーが何をしているのか、全体の流れを軽く把握していきましょう。
このシェーダーは3Dモデルに適用するシェーダーですので、①PBR Musterノードが使用されています。PBR Musterノードについては後述します。
②で女神像に適用するノーマルマップとオクルージョンマップを設定しています。
③では、女神像のディゾルブ(溶けて消えるような表現)している個所のフチを強く発光させる設定をしています。
④では、ディゾルブの形状を設定しています。ここではSimple Noiseを使ってますね。
⑤ではノイズの明度を元に、ディゾルブするかしないかのしきい値をアニメーションで設定しています。
これにより女神像の消える範囲をコントロールしています。
Emissionの範囲のアニメーションにも使用していますね。
これらの組み合わせで、下図のような女神像が溶けて消えていくシェーダーが完成します。
実際に作ってみる
今回から基礎編と少し解説の流れを変えようと思います。
基礎編では重要なノード毎に解説をしていましたが、この応用編からはノードが何もない状態から完成まで、実際の作成手順に沿って解説していきたいと思います。
応用編はノードの組み合わせが複雑になりがちなため、この方法の方が解かりやすいかなと思ったためです。
では始めていきましょう。
① PBR Masterノードについて
PBR Masterノードは、ライティングが必要な3Dモデル用の物理ベースシェーダーです。
PBRとは「フィジカルベースドレンダリング」の略で、物理的に正しい質感や反射を表現します。
PBRってなに?って方はこちらの記事がすごく勉強になります。
僕も大変勉強させてもらいました。
さて、シェーダーグラフに戻ります。
PBR Masterノードは、前述したとおりライティングが必要な3Dモデルに使うもので、以下のような機能を内包しています。
- Albedo : アルベドマップの入力
- Normal : ノーマルマップの入力
- Emission : 自己発光量の指定
- Metallic : メタルネスマップを入力
- Specular : スペキュラーマップを入力
- Smoothness : スムースネス(ラフネス)マップを入力
- Occlusion : オクルージョンマップを入力
- Alpha : アルファチャンネルの入力
- AlphaClipThreshold : この値以下のアルファ値を持つフラグメントを破棄する。(※この項目を有効にするにはノードを繋ぐ必要があります)
---------------
- Workflow
Specular : スペキュラーを使用するモード
Metallic : メタルネスを使用するモード - Surface
Opaque : 不透明シェーダーになる
Transparent : 透明シェーダーになる - Blend(透明シェーダーの時のみ有効)
Alpha : アルファブレンド(Alphaチャンネルが使える)
Premultiply : 事前にアルファチャンネルをカラーチャンネルに乗算するブレンド方法(Alphaチャンネルを使える乗算)
Additive : 加算ブレンド(Alphaチャンネルは無視される)
Multiply : 乗算ブレンド(Alphaチャンネルは無視される) - Tow Sided : 両面描画になる
② ノーマルマップとオクルージョンマップを貼る
それでは、実際にノードを作成してシェーダーを組み立てていきましょう。
今回のシェーダーでは「ノーマルマップ」と「オクルージョンマップ」を使って女神像のディテールを表現しています。
テクスチャを使用するためには「Sample Texture 2D」ノードが必要です。
ただし、これだけだとマテリアルからテクスチャの変更ができないため、「Texture 2D Asset」ノードを追加してプロパティ化しています。
まず「Sample Texture 2D」「Texture 2D Asset」を2つずつ作り、下図のように繋げてください。
「Texture 2D Asset」ノードの赤丸の部分をクリックしてテクスチャをアサインしましょう。
アサインするテクスチャはこの2つです。
するとこのように、表面がつるつるだった女神像にディテールが追加されます。
③ ディゾルブで消えていくノードを組む
来ました!今回のキモ!
溶けて消えるようなディゾルブ表現を組んでいきます!
ディゾルブ表現をするには、PBR Masterノードの「Alpha」と「AlphaClipThreshold」を使います。
流れとしては、Alphaに0~1の値を持ったノイズを繋ぎ、AlphaClipThresholdでしきい値を設定して、そのしきい値以下の部分を消すという流れです。
実際に組んでみましょう。
まずAlphaに「Simple Noise」ノードを繋ぎます。
Scaleの値は「50」にしておきます。
次に、AlphaClipThresholdに「Slider」ノードを繋ぎます。
(※最終的にこのSliderノードは削除します。制作過程を分かりやすく説明するためだけに追加しています。)
すると、下図のようにスライドバーを左右に動かすと女神像の一部が消えていくようになります。
これは、Alphaに繋いでいるノイズの明暗(0~1)がしきい値よりも低い場合、その範囲が消えるからです。
さて、気づいた方もいるかもしれませんが、今はSliderノードをつないでいるため消える範囲は固定ですが、ここに0~1の周期でアニメーションするノードを繋げば、このシェーダーの最終結果のように消える範囲がアニメーションする表現ができますね。
アニメーションに関しては後述しますので、その前に、消える範囲のフチを発光させるノードを組んでみましょう。
Sliderの値は「0.5」にしておいて下さい。
④ 消える範囲のフチを発光させる
上図のような発光表現をするには、PBR MasterノードのEmissionに「Color」ノードを繋ぎます。
色はお好みで構いません。
「Color」ノードのModeはHDRに切り替えましょう。
HDRに切り替えると、Defaultでは出来なかった輝度調整ができるようになります。
カラーピッカーの下の方にIntensityという項目が追加され、ここで輝度を調整できます。
基本的には、輝度を1以上にすることで今回のシェーダーのように発光させる事ができます。
この時点でシェーダーをセーブして、Gameモードで確認してみてください。
下図のように一部が消えつつ、全体が発光している状態になっていると思います。
Emissionに一律にカラーが入っているため、全体が発光してしまっています。
今回はフチ部分だけ光らせたいので、うまくフチ部分だけ光るようなマスクを作成していきましょう。
どういうマスクを作ればいいのか、簡略化した図形で発想の流れを見ていきます。
まず、今の女神像は下図のようなマスクをAlphaに使用することで、表示されている部分と消えている部分の2つに分かれています。
今回は下図のように消えている部分のフチを光らせたいです。
ということは、下図のようにフチ部分だけ残したマスクを用意してEmissionに繋げればいいはずです。
ではマスクを実際に作っていきましょう。
初めに、女神像の表示されている部分と消えている部分を反転します。
反転した白い部分の範囲を少し広げます。
この範囲を広げた白い部分から、広げる前の部分を減算すれば目的のマスクは作れそうです。
ですが、今回のシェーダーではそこまで必要ありません。
なぜなら、広げる前の部分というのは女神像のすでに消えている部分ですので、Emissonにつなぐマスクがどうであれ、結果的には消えて見えなくなるからです。
ですので、現時点のままの画像に発光させたいカラーを乗算して、それをEmissionに繋げれば、フチだけ発光する絵が完成します。
という事で、Emissionに必要な最終画像はこちらです。
発想の流れはこれで終わりです。
実際にノードを組む前にどういう処理が必要かを考えないと、ノードをどう組めば良いかが分からないのでちょっと丁寧に説明さてもらいました。
では実際に、シェーダーグラフでフチを発光させるノードを組んでいきましょう。
まずはAlphaに使用しているSimple Noiseを反転させる必要がありますので、「Subtract」ノードを新たに作成し、ノイズをB入力につなぎます。
A入力の値は、AlphaClipThresholdの値と同じ「0.5」にしてください。
これで女神像の消えている部分とEmissionの光らせる範囲が同じになります。
これで下図と同じ事ができました。
このままだとノイズのグレーの部分が女神像の消える範囲と同じなので発光部分は表示されません。
色もグレーですのでキンと光る表現にも適さないですね。
このグレー部分を広げて真っ白にするために、「Step」ノードを使います。
新たに「Step」ノードを作成し、下図のように繋いでください。
「Step」ノードのEdgeの値は「-0.04」にして下さい。
しきい値をマイナスにする事で白い部分が広がります。
プレビュー画面を見ると、消えている部分のフチが白くなっていますね。
これで下図と同じ事ができました。
~ちょっと補足~
なぜ「Step」のEdgeをマイナスにすると白い部分が広がるのか?を少し解説します。
「Step」ノードは、Inの入力値がEdgeの入力値以上の場合は1を、未満の場合は0を出力するノードです。
つまり、Edgeの入力値がマイナスの場合、ノイズの黒い部分にも白い部分が侵食していくことになります。
どうやらノードのプレビュー画面に映っている黒い部分は一律0の値ではなく、0以下の値が続いているようですね。
図で解説してみます。
まず、「Subtract」ノード時点でのノイズの値(明暗)は下図のようになっています。
「Step」ノードのEdgeでしきい値を「0.0」にした場合は、「0.0」地点を境に下図のように二値化されます。
白い部分が「1」、黒い部分が「0」です。
Edgeの値を「-0.04」にした場合、下図のようにノイズの黒く見えている部分にも白い部分が侵食します。
「Step」ノードのしきい値をマイナスにすると、このような計算が行われる事になります。
最後に、「Step」ノードと「Color」ノードを乗算する事で、フチの発光が完成です。
Gameモードで確認してみましょう。
下図のように消えている部分のフチが発光していると思います。
これでフチの発光は完成です!
いやー、難しかったですねー。
僕はここかなり苦労しました・・・・。
~ちょっと補足~
ちなみに、今回のシェーダーでは「Subtract」ノードを使用していますが、色の反転なら「Invert Colors」というノードを使う方法もあります。
「Subtract」の代わりにこちらを使っても同じ表現はできるのですが、「Invert Colors」ノードは入力ポートが1つしかないので「Time」ノードが繋げられません。
ですので、今回のようにアニメーションが必要な場合は「Subtract」ノードを使いましょう。
⑤ ディゾルブで消える動きにアニメーションを追加する
ここまで出来たら後はアニメーションを付けるだけですね。
アニメーションには「Time」ノードと「Fraction」ノードを使います。
「Fraction」ノードは、Inの値の小数部分を返すノードです。
例えば、1.1を入力したら「0.1」が、3.6を入力したら「0.6」の値が返されます。
ですので、どんな値が入力さても、必ず0以上1未満の数値が返されるノードとなります。
この「Fraction」ノードに「Time」ノードを繋ぐ事で、1秒間の間に0~1の値を出力するアニメーションが完成します。
この「Fraction」ノードを「PBR Master」ノードのAlphaClipThresholdに繋ぐと女神像の消える範囲がアニメーションします。
さらに「Subtract」ノードのA入力に繋ぐと、発光する範囲もアニメーションします。
同じアニメーションノードで範囲をコントロールしているため、消える範囲とフチの発光を同じように動かす事ができます。
実際にノードを組んだ状態がこちらです。
完成!
これで今回のシェーダーは完成です!
最後に「ノーマルマップ」「オクルージョンマップ」「エミッションカラー」をプロパティ化してマテリアルから調整できるようにしておきましょう。
まとめ
今回は基礎編とは違いとても実用性の高そうなシェーダーでした。
実際にいろんなゲームでこういう表現って目にしますよね。
このような表現は、トゥーン調の炎や煙のエフェクトでも千切れて消える表現によく使われますね。
僕もそういうシェーダーを作ってみたかったので、まず最初にこのシェーダーを覚えようと思って選びました。
さて、最後に今回新しく登場したノードを紹介してこの記事は終わりです。
- Fractionで小数点以下の値を出力!
それでは、次回のシェーダーグラフ解説をお待ちください。