フォンの反射モデル解説 ~拡散反射~

こんにちは、Whileです。今回が初の技術記事です。
最近はシェーダーの勉強やレイトレーシングの実装を行っています。その際に出てきたPhong反射モデルを解説します。
全て解説すると長くなっちゃうので今回は拡散反射のみを扱います。

Phongの反射モデルとは

フォンの反射モデル
Phongの反射モデルはコンピュータグラフィックスにおけるシェーディングで扱われるモデルの一種で、以下の数式で表されます。

 \displaystyle
I = K_{d}I_{in}cosθ_{1} + K_{s}I_{in}(cosθ_{2})^n + K_{a}I_{a}

このモデルは拡散反射・鏡面反射・環境光の3つの要素から構成され、これらを足し合わせてオブジェクト表面の陰影を決定します。

拡散反射

拡散反射とは、物体の表面に入射した光が表面の細かい凹凸によってあらゆる方面に等しく拡散する反射のことを言います。

拡散反射のイメージ

数式でいうとこの部分にあたります。

 \displaystyle I_{d} = K_{d}I_{in}cosθ_{1}

この数式はランバートの法則と呼ばれます。
この式は、拡散反射光  {I}_d の強さは入射角の大きさに反比例する(余弦に正比例する)ということを意味しています。つまり、入射角が大きくなるにつれて拡散反射光が弱くなるということです。

拡散反射光と入射角の関係

  •  {K}_d 拡散反射係数

オブジェクトの表面がRGB各成分をどれだけ反射するかを表します。
例えば、 {K}_d = (0,1,0) だとオブジェクトは緑色の光のみを反射するという意味になります。オブジェクトの色を設定したというイメージに近いです。

  •  {I}_{in} 入射光の強さ

UnityのLightでいうIntensityに相当する部分です。この部分なんですが、光源の拡散反射係数  {I}_d になっている場合もあり混乱しました。UnityのLightでは光源の色も設定できるので、計算式が以下のようになっているんじゃないかと思います。

 \displaystyle I_{d} = I_{in}K_{d}I_{d}cosθ_{1}

これで光源の強さ・色の両方を反映させられるというわけですね。
色々書きましたが、この記事では 光源の強さとして扱います。

先ほどから出ていましたが、入射光とオブジェクト表面の法線とのなす角を入射光と言います。 なお計算時は入射光の逆ベクトル、すなわちオブジェクト表面から光源への方向ベクトルを使用します。

計算時の入射角のイメージ
cosの計算は遅いので、プログラムで使用する際はベクトルの内積に置き換えます。

 \displaystyle 
I_{d} = K_{d}I_{in}(\hat{L}\cdot\hat{N})
  • L オブジェクト表面から見た光源への方向ベクトル
  • N オブジェクト表面上の法線ベクトル
  •  \hat{}は正規化したことを意味します。

こうなる理由は次の通りです。

 \displaystyle 
L \cdot N = |L||N|cosθ_{1}\\

 |L| = |N| = 1になると  =cosθ になります。
よって、 
\hat{L}\cdot\hat{N} = cosθ_{1}
になります。

また、光源方向ベクトルとオブジェクト表面の法線ベクトルのなす角 θ_{1} \frac{π}{2} (= 90°)を超えた場合は、下図のようにオブジェクト表面の裏側から光が当たっていることになるので拡散反射は起きません。

入射角が \frac{π}{2} (= 90°)を超えると拡散反射は起こらない

最後に

フォンの反射モデルの拡散反射について解説してみました。
間違いがあったらご指摘いただけると嬉しいです。
次回記事はフォンの反射モデルにおける鏡面反射の予定です。