はなちるのマイノート

Unityをメインとした技術ブログ。自分らしくまったりやっていきたいと思いますー!

【Unity】ShaderGraphでフレネル効果をお手軽に

はじめに

今回はShaderGraphでフレネル効果をしてみる記事になります!

フレネル効果とは、視点のベクトルと物体の法線のベクトルの内積によって出力値(色)を変化させるものです。

実際にやってみるとこんな感じ。

f:id:hanaaaaaachiru:20200103184929p:plain

早速見ていきましょう。

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);

実装例

一番最初に貼った画像のノードはこんな感じ。

f:id:hanaaaaaachiru:20200103192923p:plain

さいごに

再度繰り返しになりますが、両面描画のときにだけは注意をしたほうが良いと思います。

またこちらの公式の動画はめちゃくちゃためになるので是非。

www.youtube.com