Skip to content
第07回 ベクトル演算とライティング

4 / 4 光方向と面の向きの比較 ​

このステップの目的

光と物体の変更を分け、計算結果を予想します。

原因を一つに絞る課題 ​

光方向を(1,0,0)へ変更する前に、どの面が明るくなるか予想します。次に光方向を固定し、Cubeへ同じMaterialを割り当てて回転を変えます。明るさが変わる原因を法線と光方向に分けて記録してください。

予測と結果の照合

光方向を変えると比較する方向が変わります。物体を回転するとWorld空間の法線が変わります。両方を同時に変えず、それぞれが内積のどちらの入力へ影響するかを追います。

光方向=(0,1,0)、回転を基準へ戻して保存します。次回は光方向に代えて視線方向を比較します。

発展:外積・反射・屈折

外積で垂直な方向を求める ​

2つのベクトルに垂直なベクトル ​

外積と平行四辺形の関係
aとbの外積は、aとbを辺とする平行四辺形の面に垂直なベクトルになります。出典: Acdx, Wikimedia Commons, Public domain。

ライティングには面の法線が必要です。
ベクトルの 外積(Cross Product) は、 2つの方向ベクトルからその両方に垂直な新しい方向を作る演算です。

面の上にある2つの辺の方向が分かれば、 その面に垂直な法線を求められます。

外積の式 ​

3次元ベクトル a = (aX, aY, aZ) と b = (bX, bY, bZ) の外積は $$ \text{Cross}(a, b) = \begin{pmatrix} aY \cdot bZ - aZ \cdot bY \ aZ \cdot bX - aX \cdot bZ \ aX \cdot bY - aY \cdot bX \end{pmatrix} $$。

csharp
// C# での外積の例
Vector3 a = new Vector3(aX, aY, aZ);
Vector3 b = new Vector3(bX, bY, bZ);

// 外積を計算
Vector3 cross = new Vector3(
    a.y * b.z - a.z * b.y,
    a.z * b.x - a.x * b.z,
    a.x * b.y - a.y * b.x);

// Unity には外積のメソッドもあります
cross = Vector3.Cross(a, b);

面の向きや空間の基準へ利用する ​

  • 面の法線を求める 三角形や四角形の辺の方向から、面に垂直な法線ベクトルを計算できます
  • ビルボードの向きを作る カメラ方向と上方向から、スプライトの横方向を求めれば常にカメラを向くビルボードが作れます
  • エフェクトの広がる方向を決める 進行方向に対して直交する向きを作れば、 軌跡や衝撃波の幅の方向に使うことができます

外積を使うときの注意点 ​

外積ベクトルは、計算の順番が逆になると向きも逆になります a x b と b x a は逆向きのベクトルになります $$\text{Cross}(a, b) = -\text{Cross}(b, a)$$。

外積ベクトルは大きさも変わります a と b が平行に近いときは、外積の長さが小さくなります。
逆に、a と b が直交しているときは、外積の長さが最大になります $$|\text{Cross}(a, b)| = |a| \cdot |b| \cdot \sin(\theta)$$。

外積を法線として使う場合は正規化して長さを 1 にする必要がありますが a と b が平行に近いときは外積の長さが 0 に近くなり正規化できなくなります。

反射と屈折の方向 ​

面で跳ね返る反射ベクトル ​

面、法線、入射方向、反射方向の関係
反射方向は入射方向と法線から求められます(図はAI生成)。

反射のベクトルを求めることができれば、 金属、鏡、水面などの光や視線を強く反射する表現に近づけることができます。

反射方向は、入射方向と法線から求められます $$\text{Reflect}(I, N) = I - 2 \cdot \text{Dot}(I, N) \cdot N$$。

Shader Graph では Reflect ノードで反射ベクトルを作れます。

透明な物体で曲がる屈折ベクトル ​

簡易な屈折表現の例
簡易な屈折表現の例です。ゲームでは、背景を読む位置をずらすなどの近似も使われます。

屈折は、光が透明な物体を通るときに進む方向が変わる現象です。

光が空気中から水やガラスに入るとき、 その進む向きが少し曲がります。
屈折方向を計算で求めることができればガラスや水の表現に近づけることができます。

Shader Graph では Refract ノードで屈折方向のベクトルを作れます。

使用画像と出典 ​

チェックリスト
  • 表示結果から変更した入力を説明できる。
  • 基準の光方向と回転へ戻した。