今回はちょっとした補足説明です。
まあ、単純に自分がはまった部分と、ちょっとした便利機能紹介です。
前回、VertexNormalWSとPixelNormalWSは基本的に同じである、と解説しました。
…あれは嘘だ。
いやまあ、嘘というとちょっと語弊があるんですが、以下の画像をご覧ください。
このマテリアルはフレネル反射をEmissive Colorとして出力するだけのマテリアルです。
フレネル反射というのは視線と法線が直角に近いほど1.0に、水平に近いほど0.0になるような値を求める計算式です。
まあ、実際にはそういう意味ではないのですが、とりあえずそんな感じのものとここでは認識しておいていただければOKかなと。
上の画像では計算する際の法線をPixelNormalWSで行っています。
では、以下の画像はどうでしょう?
この画像ではVertexNormalWSを使っていますが、プレビューではポリゴンの境目が見えてしまってガタガタしているようになってしまっています。
なぜこのようになるのかというと、VertexNormalWSは空間中の頂点法線ではあるのですが、ピクセルシェーダで取得する際に正規化が行われていないのです。
頂点シェーダで変換された頂点法線はピクセルシェーダに入ってきた際に補間されることになるのですが、ピクセルシェーダに入る際の3次元ベクトルの補間は単純な数値の補間になってしまいます。
例えば、ある頂点の法線が(1.0, 0.0, 0.0)で、もう1つの頂点の法線が(0.0, 1.0, 0.0)だとします。
この2つの中間の法線ベクトルは(0.7071, 0.7071, 0.0)が正しいのですが、単純な数値の補間では(0.5, 0.5, 0.0)になってしまうのです。
これでは長さ1.0のベクトルにはならないので、計算結果が変わってしまうのは仕方ないんですね。
ではどうすればいいか、というと、答えは簡単で頂点法線を正規化すればいいのです。
これで結果がPixelNormalWSの時と同じになりましたね。
続きにはちょっとした便利機能の紹介ですが、割とマジで便利なので覚えておいて損はありません。
最初に紹介するのが各ノードのプレビューです。
マテリアルを調整するとその結果が左のプレビューウィンドウに表示されます。
しかし、その結果が予想したものと違っていたらどうでしょう?
計算は間違っていないはずなのになぜか予想通りにならない。
まあ、たいていそういう場合はどこかの計算式が間違っています(笑
ただ、どこまで計算が正しいのか、複雑な計算式になるとノードも複雑になってよくわからなくなります。
そこで登場するのが各ノードのプレビューです。
あるノードまでの計算が正しく処理されているかをプレビューする機能が存在するのです。
使い方は簡単で、プレビューしたいノードを右クリックし、コンテキストメニューから[Start Previewing Node]を選択するだけです。
これを選択すると、選択したノードの色が変わり、プレビュー中の表示がされるようになります。
そしてプレビューウィンドウにノードの計算結果が表示されているのがわかるでしょう。
シェーダプログラマなら、途中計算の結果をとりあえず出力してみてどこまでの処理が正しいかを確認する、なんてことはよくやってることなんじゃないかと思います。
それと同じことがこんなに簡単にできるってのはうれしい限りですね。
なお、やめる場合はやはりコンテキストメニューから[Stop Previewing Node]を選択すればOKです。
もう1つの便利機能として、Customノードを紹介します。
このマテリアルノードはシェーダプログラムを直接入力することができるというものです。
Customノードを設定し、Detailsタブの[Code]にプログラムを書くことが可能です。
入力は複数指定することが可能ですが、出力は残念ながら1つしか指定できません。
入力を指定する際に引数名を設定することができ、Code内ではその引数名をそのまま利用することができます。
Descriptionを変更すればエディタのノード名も変更可能です。
Codeの書き方は基本的にHLSLの書き方で問題ないようですが、GLSLでも使えるかどうかは不明です。
まあ、たいていのHLSL命令はGLSLで使用できるのでほぼ問題ないと思いますが。
Codeの最後はreturn命令で値を返してやる必要があり、この値が出力となります。
残念なのはCodeが1行しか書けないので、複雑な式だとわかりにくくなることだと思いますが…
でまあ、Customノード自体はノードだけで表現すると複雑になりがちな計算式をまとめるのに役立ったりと便利な機能なんですが、今回はそれ自体の紹介ではなく、あるシェーダ命令を紹介しようと思います。
それが "smoothstep" 命令です。
正直なところ、なぜ標準的なマテリアルノードに存在しないのかわからないレベルで便利な命令です。
smoothstep命令のリファレンスはHLSLのリファレンスを見るのが一番わかりやすいでしょう。
http://msdn.microsoft.com/ja-jp/library/bb509658(v=vs.85).aspx
簡単に説明すると、xの値がmin以下なら0.0, max以上なら1.0, minとmaxの間なら0.0~1.0の割合を計算してくれるという代物です。
Customノードで実装する場合はDetailsタブを以下のように設定します。
この命令は結構使い勝手がいいので、知ってるとちょっとしたところで使うようになります。
例えば、ある2つのマテリアルを深度によって切り替えたい、しかしいきなり切り替わるのではなく、徐々に補間して切り替えたい、というような場合があるとしましょう。
それをsmoothstepで実現すると以下のようになります。
結構簡単ですし、わかりやすくまとまります。
とまあ、こんな感じの便利機能紹介でした。
解説その3は夏休み後にでも更新しようと思います。