Strumpy Shader Editor サンプルからノードベースのプログラミングを学ぶ

1.はじめに
前回はStrumpy Shader Editor導入,プレビューといったことを紹介しましたが,今回から本格的にノードベースのプログラミングを見ていきます.今回はデフォルトのリムライト付きのピクセルシェーダのサンプルからノードベースのプログラミングの方法の基礎を学びます.
2.今回取り上げるシェーダ
今回は,まずはStrumpy Shader Editorのデフォルトのシェーダを見てみます.下記のような感じですね.


このシェーダグラフを細かく分解しながらStrumpy Shader Editorを学んでいきます.
3.Strumpy Shader Editorの基本ルール
Strumpy Shader Editorのプログラミングは右から左に処理をつなぎます.
たとえば,下記の例の場合[Color: _DiffuseColor]というノードはRGBA(Red, Green Blue, Alphaのカラー)を出力するのですが,それを[Master]のDiffuseに接続しています.この流れは,[Color: _DiffuseColor]の色をDiffuseカラーに使用するという意味になります.

それから別な例では,下記の処理を見てみましょう.ここでは,[Pow]と[Multiply]を見てみます.[Pow]と[Multiply]にはそれぞれノード右側にArg1とArg2というのあがります.Argはそれぞれノードを関数に見立てた際の引数になります.ここでは2つの引数を接続できます.「関数の引数」という言い方はプログラミングっぽい説明なので,プログラマ以外の人は単純に[Pow]と[Multiply]にはArg1とArg2という2つのパラメータに対して何らかの計算をしてResultに出すと理解していただければ大丈夫です.
それではそれぞれのノードの処理が何を意味するか解説していきます.[Pow]は累乗を計算するノードで「Arg1のArg2乗」してResultに出します.たとえば,Arg1が数字の2だとしてArg2が数字の3なら[Pow]は「2の3乗」を計算してResultに8を出力します.
[Multiply]はArg1とArg2の乗算です.ここでは,[Color: _RimColor]のRGBAの各チャンネルと[Pow]の乗算をします.[Color: _RimColor]はRGBAの4つのカラーチャンネルを持つパラメータですが,乗算はそれぞれのチャンネルに対して行われます.

次に,特殊なノード[Master]の解説をします. Strumpy Shader Editorでは頂点シェーダ(描画する3Dモデルのジオメトリに対する処理を行う)を編集するVertex Graphとピクセルシェーダ(3Dモデルのサーフェイスのピクセル処理を担当するシェーダ)編集するPixel Graphとライティングの編集をするLighting Graphがあります(Pixel Graph以外の2つのグラフについては今後の記事で扱います).これらのグラフの計算のゴールが[○○ Master]になります.Pixel Graphでは[Master]になります.
[Master]では,Diffuse(拡散反射), Normal(法線), Emission(自己発光),Gloss(光沢),Specular(鏡面反射), Alpha(透明度), Custom(ちょっとドキュメントで何に使うかの説明が見つけられなかったので不明), Clip(クリップ.これも現時点で使い方や入力パラメータ不明)といったライティング処理についてノードベースのプログラミングでカスタマイズができます. カスタマイズは項目ごとにできますので,必要のない処理は使わないようにすればデフォルトの振る舞い(デフォルトの振る舞いは使われない,頂点処理から来た値を使うなど様々)をします.

4.もう一度サンプルの処理を見直す
それでは,もう一度サンプルのPixel Graphを見てます.これを[Master]の入力単位ごとに分解して処理を見ていきましょう.

4.1 DiffuseとProperties型の解説
まずは,Diffuseです.これは大変わかりやすいです.先に書きましたが,[Color: _DiffuseColor]というノードはRGBA(Red, Green Blue, Alphaのカラー)を接続するだけです.

ここで[Color:○○]というノードの解説をします. [○○:変数名]のように”:”(コロン)がついたノードはPropertiesノードです.PropertiesノードはEditorのプロパティでユーザーが指定した色や変数,テクスチャなどUnityのGUI上で指定できるパラメータのノードです.実際にEditor上ではInputsというタブを開くとプロパティが一覧で出てきます.上の[Color:_DiffuseColor]は赤がセットされています.
なお,ちょっと見ていただくとわかりますが,このInputsの項目は型によって様々なGUIが使えます.Color型であれば色を指定するパレットのようなものが使えますし, _RimColorのようにRange型というのを使うと最小値と最大値を指定したスライダーで値を編集したりすることができます.
Inputsの項目を増やすには,Add New Input…を押します.このときに使いたい型のリストが出てきます.

Add New Inputを押すと以下のような変数の候補が出てきます.ColorやFloat4,Rangなどの他にUnityのエンジン側から受け取るパラメータなどもあります.

Add New Inputではプロパティに項目を増やすことができますが,これだけではPixel Graph上にノードが追加されるわけではありません.せっかくなので,Properties型のノードの設置もやってみます.
ノードをGraph上に設置する方法はいくつかあります.1つは,Inputsボタンの右のNodesボタンを押すと一覧が出てきます.

もう1つは,Graph上で右クリックを押すと出てきます.今回は,新たにもう1個Properties型からColor型を追加しましょう.

追加するとGraph上にノードが増えます.Properties型は追加した瞬間はノードが赤くなってエラー表示になります.これはプロパティの項目との関連づけが行われていないために起きているエラーです.そこで関連付けを行います.

関連付けはエラーを出しているノードを選択して,プロパティのNodeを見ます.Input Propertyという項目がUnconfiguredになっています.これは関連付けの未設定を意味します.

そこでInput Propertyを見るとプロパティのInputsのColor型の項目が出てきます.とりあえず,特に意味はありませんが動作の確認のため_DiffuseColorを選択してみます.

そうするとエラー状態が解消します.

こんな感じで,プロパティに変数を追加してノードに割り当てができるのがわかります.
4.2 Emission
それでは再び[Master]の処理に戻ります.Emissionの処理です.ここが今回で一番処理的に大きな部分です.ここでは自己発光処理を行っているのですが,今回のシェーダは一般にリムライトと呼ばれる処理です.
リムライト参考(「TF2」における鏡面反射照明を参照のこと)
http://game.watch.impress.co.jp/docs/20080228/3de.htm 
今回は,Fresnel(フレネル)を利用して実装します.Fresnelの処理には,[Fresnel]ノードというのがあるのでそれを使っています.[Fresnel]ノードは計算にView(視線方向のベクトル)とNormal(法線)を使います.このうちNormalは特に何もしなければモデルの法線がそのまま使われます.Viewに関しては,ViewDirectionというノードを接続すればOKです.
続いて,この[Fresnel]のResultと_RimPowerの累乗計算をします._RimPowerは,リムライトの強度のパラメータでプロパティから取ってきます.これは,シェーダを編集する人がシーンに合わせて調整できるようにするためです.Range型のパラメータで0.1〜3.0の間で調整ができます.累乗は先ほど出てきた[Pow]ですね.
[Pow]のResultとリムライト色を示す_RimColor(今回は青)を乗算します.これは,[Multiply]でやります.
この結果をEmissionに入力すると最初の出力結果みたく青っぽく輪郭が光るようになります.

4.3 Gloss
GlossにはRange型の0.1〜1.0が指定できるパラメータが入ります.これはハイライトの大きさに関係します.

4.4 Specular
Specular(鏡面反射)の色はColorが入ります.今回は黄緑がプロパティに入っています.

5.まとめ
とりあえず,サンプルを元に色々と機能説明をちょっとしてみました.HLSLやCgでシェーダを書いてるような人ならおそらくここまで説明すれば自由にシェーダが作れるとは思いますが,ライティングやシェーディングの基礎部分は知らないという方にはまだまだ難しいと思います.ですので,次回は,[Master]の各項目を一個一個試しながらライティングの表現の基礎について学んでいけるようにしたいと思います.