第07回 ベクトル演算とライティング
3 / 4 内積によるLambert照明
このステップの目的
長さ1の二つの向きを比較し、面の明るさを計算します。
同じ空間へそろえた接続
Vector3プロパティのDirection To Lightを作り、値を(0,1,0)にしてください。この値は、World空間で表面から光へ向かう方向を表します。
Normal VectorをWorldに設定し、光方向とそれぞれNormalizeへつなぎます。二つのNormalizeの出力を、Dot ProductのAとBへつないでください。
Dot Productの出力をSaturateへつなぎ、Saturateの出力をBase Colorへつなぎます。これで、法線を色として表示していた接続を置き換えられます。
2つの向きの近さを求める内積
面の向きと光の向きがどれくらい一致するかを求めると、面の明るさを計算できます。この計算に使うのが内積です。英語ではDot Productと呼びます。
内積は、二つのベクトルで対応する成分を掛け、その結果を足して求めます。
csharp
// C# での内積の例
Vector3 A = new Vector3(aX, aY, aZ);
Vector3 B = new Vector3(bX, bY, bZ);
// 内積を計算
float dot = A.x * B.x +
A.y * B.y +
A.z * B.z;
// Unity には内積のメソッドもあります
dot = Vector3.Dot(A, B);Lambertライティング
Lambertライティングは、拡散反射の基本的なモデルです。光の方向と面の向きの関係だけで明るさを計算します。法線と光方向の内積を明るさとして使うと、最小限のライティングを実現できます。
単純なモデルですが、月の表面のようなマットな質感には十分効果的です。
条件を変えた確認
上向きの法線(0,1,0)に対し、光方向を(0,1,0)、(1,0,0)、(0,-1,0)へ変えたときの内積と表示する明るさを求めてください。
予測と結果の照合
内積は順に1、0、−1です。Saturateを通すと1、0、0になります。光と逆向きの面では、負になった明るさを0に制限します。
確認後は光方向を(0,1,0)へ戻してください。今回の計算には、Materialに設定した光方向を使っています。SceneのLightを動かす操作とは別であることを確認します。
チェックリスト
- 法線と光方向をWorld空間で比較している。
- 正規化・内積・Saturateの役割を説明できる。