Light and Shading

Chapter 6

前章まででとりあえず描画までは行くことができたものの、得られた画像は立体感がまったくなく平面的なものだった。
この章では Light を導入し、Shading 処理を加えることで影による立体感を出す。

この本で用いる Shading のモデルは非常にシンプルなもので、object(今のところ球のみ) 上の点(実際には微小平面)における shading の計算に要する情報は以下の通り。

  • 光源位置
  • normal vector (法線ベクトル)
  • 視点位置

Surface Normals

object(球)の normal vector は簡単に求められるが、それはあくまで球のローカル座標におけるものであり、他の座標系(ここではワールド)における normal vector を求めなくてはならない。その際、変換行列に non-uniform な scaling が含まれていたりすると変換行列をそのままかけただけでは変換後 object 上の normal vector にならない。
代わりに  (\mathbf{M}^{-1}) ^T を使う。

この本、test first で ray tracer を作っていくというもので、これだけだとボトムアップに ray tracer のことが理解できるように思えるのだけれど、実際には結構違う。複雑な部分のアルゴリズム天下り式に与えられ、なぜそれでうまくいくのかの解説が全くないことがままある。
原理に興味がなくて、モノが作れればそれで ok という考え方なら問題ないけれど、プログラミングを通して理解を深めることを目的とするなら、ちょっと物足りない。

normal vector への Transform の適用もそれで、通常の変換行列  \mathbf{M}の inverse transpose ( (\mathbf{M}^{-1}) ^T) を用いれば良いとだけ書かれている。

object 上の任意の点における normal vector \mathbf{n}、tangent vector(接ベクトル)を  \mathbf{t} とする。両者は直交するため、


\mathbf{n}\cdot\mathbf{t} = \mathbf{n}^T\mathbf{t} = 0

が成り立つ( T は transpose)。一方で Transform 適用後の  \mathbf{n}' \mathbf{t}' に対しても同様の関係が成り立つはずなので、


\mathbf{n}'\cdot\mathbf{t}' = \mathbf{n}'^T\mathbf{t}' = 0

となる。

ここで、Transform を  \mathbf{M}、normal vector に適用する Transform を  \mathbf{S} とする。tangent vector \mathbf{M} をかけるだけで変換後の点で objct に接する性質は変わらないため


\eqalign{
    \mathbf{t}' &= \mathbf{M}\mathbf{t}\cr
    \mathbf{n}' &= \mathbf{S}\mathbf{n}
}

であり、両者が直交することから、


\eqalign{
    \mathbf{n}'\cdot\mathbf{t}' &= \mathbf{S}\mathbf{n}\cdot\mathbf{M}\mathbf{t} \cr
    &= (\mathbf{S}\mathbf{n})^T\mathbf{M}\mathbf{t}\cr
    &= \mathbf{n}^T\mathbf{S}^T\mathbf{M}\mathbf{t} = 0
}

となる。 \mathbf{n}^T\mathbf{t} = 0 より  \mathbf{S}^T\mathbf{M} = \mathbf{I} ( \mathbf{I}単位行列)が成り立つことから、


\eqalign{
\mathbf{S}^T &= \mathbf{M}^{-1}\cr
\mathbf{S} &= (\mathbf{M}^{-1})^T
}

というわけで、 (\mathbf{M}^{-1}) ^T を変換前の normal vector にかければ、変換後の objcet に対する normal vector が得られる。

The Phong Reflection Model

このモデルでは、Ambient、Diffuse、Specular の 3 要素に分け、それぞれを別々に計算してから合計する。合計する際の各要素の割合は Material に記述する。
それぞれの意味や計算手法は本に書かれているので、ここでは簡単に触れるにとどめる。

Ambient

環境光。定数値。

Diffuse

拡散反射光。object 上の微小平面と光源から発する光のなす角で決まる。微小平面の向きは normal vector で表されるため、normal vector と光源ベクトルから計算する。
使用する情報は

  • 光源位置
  • normal vector (法線ベクトル)

Specular

鏡面反射光。Diffuse までは視点位置に無関係で、object 上の一点の色はどこから見ても同じになるが、これは視線も考慮に入れるためどこから見るかで変化する。
使用する情報は

  • 光源位置
  • normal vector (法線ベクトル)
  • 視点位置

Rendering

他は大体本に書かれている通りなので、この章の範囲まで実装した状態での rendering 結果を載せておく。

f:id:mtXTJocj:20201216164426p:plain

少しそれらしくなってきた。

f:id:mtXTJocj:20201220000441p:plain