【Unity】初めて『シェーダーグラフ』でシェーダーを学んでみる 基礎編.㉕
こんにちは。
シェーダーを一度も触った事のないデザイナーが、Unityの「シェーダーグラフ」を使ってシェーダーを学んでみるシリーズ。
このシリーズでは、公式のサンプルシーンを元に僕がシェーダーグラフで学んだ事を解説していきます。
シェーダー学習初という事もあり、たくさんの方のブログを拝見し、勉強させていただきました。
このシリーズには僕が参考にさせていただいたブログのリンクを貼らせていただいておりますので、そちらも併せて読んでいただくとより一層理解が深まるかと思います。
今回は「基礎編.㉕」という事で、公式のサンプルシーンにある上の画像のグラーデションしているシェーダーがどのように作られているかを解説します。
まずはこちらの記事で紹介したサンプルシーン「Shader Graph Example Library」を開いてください。
シーンは開けましたか?
それではシェーダーの解説に入ります。
シェーダーを開く
サンプルのシーンを開いたら、「Procedural-Color-SoftSplit」というファイルをダブルクリックして下さい。
するとシェーダーグラフのエディターが立ち上がります。
※Propertyにコンバートされていたノードは「Convert To Inline Node」で元に戻してあります。
全体の流れ
個々のノードを見ていく前に、このシェーダーが何をしているのか、全体の流れを軽く把握していきましょう。
このシェーダーは、見た目的には基礎編.㉓の色の境界をボカしたようなシェーダーです。
ノードの流れも似てますが、少しだけ組み方が複雑に見えるので解説していきます。
まず①では、UVのUを+0.5オフセットかけた値を作り、最後のSplitノードでR(U)チャンネルのみ出力しています。
次に②では、Smmothstepというノードで、入力された値を基に左右に対してグラデーション掛かったような数値を出力しています。
最後に③で、おなじみのLerpノードでカラーを設定し、次のような左右にグラデーションしているシェーダーが完成します。
重要ノード群の解説
さて、全体の流れを把握した所で、今回のシェーダーで重要な役割を持つノードを詳しく見ていきましょう。
① オフセットされたUVのUのみ出力
このノード群では、簡潔に言うとUVのUを+0.5オフセットかけた値を出力しています。
最後のSplitでR(U)チャンネルのみ出力されるようにしてますね。
この+0.5オフセットかけるのはTiling And Offsetとそこに入力されているノード群で設定しているのですが、Tiling And Offsetノードの時点でどのような数値が導き出されているか確認しておきたいと思います。
UVのUを+0.5オフセットかけた時のプレビュー画面上での数値は下図のように変化します。
(※左が元のUV、右がUを+0.5オフセットかけた状態)
このノード群最後のSplitノードでR(U)のみ抽出しているので、最終的に使われる値は下図の点線で囲った値のみとなります。
ちなみに、Combineノードを使用している理由は、Tiling And OffsetノードでUのみにオフセットをかけるために、(0.5, 0)というRGチャンネルを作りたいためです。
Vector1ノードを使っているのは外部(マテリアル)からオフセットの数値を調整するためです。
② Smoothstepでグラデーション
このノードは、Inの値がそれぞれEdge1とEdge2の値の間にある場合、0と1の間でエルミート補間された値を返します。 もしInの値がEdge1の値より小さい場合は0を、入力Edge2の値より大きい場合は1を返します。
長いですね(笑)、複雑!エルミートって何!?
調べたので解説していきます。
エルミート補間とは、始点から徐々にスピードアップし、終点に向かって減速していく補間方法です。
Lerpの線形補完とは違う補間方法ですね。
この補間方法で求めた曲線をエルミート曲線と言うらしいのですが、これが「エルミート曲線だ!」と自信を持って言える知識がないので、参考にさせていただいたブログのリンクを貼らせていただきます。
興味のある方は読んでみて下さい。
エルミート補間の説明はここまでにして、実際にこのノードでどのような値が求められているかを解説したいと思います。
まず、①のノード群で最終的に求めた値は下図の値でした。
これをSmoothstepノードに入力すると、計算前の値は下図のようになります。
このノードの計算は
「Inの値がそれぞれEdge1とEdge2の値の間にある場合0と1の間でエルミート補間された値を返します」
という事でしたね。
とすると、このシェーダーでは「Edge1が0、Edge2が1」となっていますので、プレビュー画面の左端(In値0.5)から中間(In値1.0)の部分がエルミネート曲線の中間から終点になり、計算後は下図のような値が求められます。
Smoothstepノードにはもう一つの機能がありましたね。
もしInの値がEdge1の値より小さい場合は0を、入力Edge2の値より大きい場合は1を返します。
という事は、このシェーダーではEdge2が1ですので、In値が1.0以上のプレビュー画面の中間から右端までは、全て1.0の値が求められるという計算結果になります。
最後に、試しにEdge2の値を1.5にするとプレビュー画面の右端がエルミート曲線の終点となり、左端から右端までグラデーションがかかった見た目になります。
③ Lerpでカラー設定
もうお馴染みのLerpノードです。
このシェーダーではTに入力されている値が下図になってます。
Lerpはノードは、「A入力値を最小値、B入力値を最大値として、T入力値0~1の範囲で値を線形補完するノード」ですので、Lerpのプレビュー画面の左端(T入力値0.75)は、カラーAからカラーBへ3/4ほど遷移した状態の色が表示されるという事になります。
完成!
これで今回のシェーダーは完成です!
まとめ
今回はSmoothstepという新しいノードが出てきました。
このノードで使われているエルミート補間というのを正確に説明できなくて申し訳ないです。
ただ、正確には理解できなくても、自然なグラーデションを使えるノードはエフェクトにはとても重要になりそうですので覚えておくべきノードかなと思います。
それと今回はUVを基に計算をしていました。
どうもUV絡むとノードから求められる計算結果がすんなり理解できないので、ちょっとくどいかなと思いつつもどのように値が求められていくかを解説してみました。
もし疑問点などあればお気軽にコメント下さいね。
さて、今回新しく覚えるべきノードは1つです。
- Smoothstepでグラデーションをかける!
この1つを覚えたら次へ進みましょう!
(※この記事で、エルミート曲線で求められたプレビュー画面左端の値を0.75と記載していますが、正確な曲線が分からないため、Photoshopで色をスポイトして結果の値を求めました。結果の値は正しいと思いますが、万が一間違いがあるかもしれませんのでお伝えしておきます。1.0の値はノードの説明を読むかぎり正しいはずです。)