【Unity】【シェーダー】ランバート反射モデル (グローシェーディング)
ランバート反射モデルとは
[1]サーフェスの法線ベクトルと、光源方向のベクトルがなす角度から 0.0 ~ 1.0 の値を算出し、それをサーフェスの「明るさ」とします。
原理
光とは粒子の集合(フォトン)でフォトンが物体に当たることにより、光ります。
とある光源からX個の粒子が放出した場合に光源方向ベクトルとサーフェイスの法線の角度によって当たるであろう面積(=S)が変化します。
懐柔電灯の光を紙の上に当てたことを想像してください。
垂直に当てた時より斜めに当てた時の方が光っている紙の面積が大きくなることが分かると思います。
仮に垂直に当てた時の面積をS=1、斜めに当てた時の面積をS=2とし、
S=1あたりに当たるフォトンの数を比較するとX/1>X/2になり、垂直に当てた方が一部に多くのフォトンが集まっていることになります。
つまり、光が垂直に当たるほど明るくなる!
[1]サーフェス:プリミティブによって表されるモデルの表面。フラグメントシェーダー内では、特に現在 処理の対象としている1点(あるいは微少面)のことを指している事が多い。法線ベクトルなど各種の情報を持っている。
ソース
解説
//法線-ライトのcosθ float NdotL = dot(normal, lightDir);
//拡散反射量の決定 o.diffuse = max(0, NdotL);
拡散反射量 = (N ・ L)
N 法線
L 光源方向ベクトル
内積の公式は
a・b = || a || * || b || * cosθ
法線と光源方向ベクトルは単位ベクトルを使用します。
= 1 * 1 * cosθ
= cosθ
cosθが残り、計算結果の値が-1〜1を取ります。
θ(二つのベクトルのす角度)が0のき = 1
θが90のとき = 0
θが180のとき = -1
(ただし、90度を超えた場合は、サーフェスが光源の方を向いておらず、光が届いていないので、結果が0未満になる場合はすべて0に丸めます)
法線と光源方向ベクトルが平行の時は先程の例でいうと懐柔電灯の光を垂直に当てた状態です。
つまり、値が1に近づくほど明るくすれば原理通りになります。
//サンプリングしたカラー値に拡散反射量を乗算する return i.diffuse * texCol;
バーテックスシェーダーで計算したディフューズ色をテクスチャーカラーに掛けています。