はじめに
今回はShaderGraphでフレネル効果をしてみる記事になります!
フレネル効果とは、視点のベクトルと物体の法線のベクトルの内積によって出力値(色)を変化させるものです。
実際にやってみるとこんな感じ。
早速見ていきましょう。
Fresnel Effectノード
名前 | 入出力 | タイプ | 意味 |
---|---|---|---|
Normal | Input | Vector 3 | 法線ベクトル |
View Dir | Input | Vector 3 | 視点のベクトル |
Power | Input | Vector 1 | フレネル効果の強さ |
Out | Output | Vector 1 | 出力値 |
内積は高校生?あたりで習うと思いますが、2つのベクトルが垂直なほど0に近づき、平行のときは正規化(大きさが1)されている場合には1(もしくは−1)に近づきます。
実際のフレネル効果のノードのコードはこのように実装されています。
void Unity_FresnelEffect_float(float3 Normal, float3 ViewDir, float Power, out float Out) { Out = pow((1.0 - saturate(dot(normalize(Normal), normalize(ViewDir)))), Power); }
少し分解してみてみましょう。
まず法線ベクトルと視点のベクトルを正規化した後に内積をとり、0以下を0,1以上を1にします。
saturate(dot(normalize(Normal), normalize(ViewDir)))
その後1から引くので、0~1
のいずれかの値になります。(垂直なら1,平行なら0)
1.0 - saturate(dot(normalize(Normal), normalize(ViewDir))
ただし、内積が−1の場合はここの値が1になってしまう(理想は平行なので0)のでそれは変ですよね。実はここが原因でこのノードは両面描画のときにはうまく動作しません。
これは公式のサイトで自前実装する方法が紹介されているので、是非調べてみてください。
https://www.youtube.com/watch?v=7ToExWKVZW0&t=644s
あとはべき乗をしたものが出力値になります。
Out = pow((1.0 - saturate(dot(normalize(Normal), normalize(ViewDir)))), Power);
実装例
一番最初に貼った画像のノードはこんな感じ。