Normal Matrix
#Transform #行列 #CG #数学
正規行列……なんだけど
ここではモデル行列に応じて法線を求めるほうの行列を扱います
gl_NormalMatrix のほう
Normal Matrixは、モデル行列の左上3x3の逆行列の転置行列となる
$ {\bf N} = ({\bf M}^{-1})^T
モデル行列が直交行列のとき(= スケールがuniformの場合)、
$ {\bf M} = ({\bf M}^{-1})^Tとなるため、
左上3x3を取り出した結果をそのままNormal Matrixとして使って良い
$ {\bf N} NのL2ノルムは1とは限らないため、正規化して使ってあげたほうが良い
$ N' = {\rm normalize}({\bf N} N)
GLSL
原則は、CPU側で計算してやりuniform変数として渡してやるのがおすすめだが、GLSL内でも計算可能
mat4 で定義された modelMatrix を mat3 にキャストすることで、左上3x3を取り出せる
Object Space Raymarchingに使える
code:glsl
mat3 normalMatrix = transpose(inverse(mat3(modelMatrix)));
証明
Ref: https://stackoverflow.com/questions/13654401/why-transform-normals-with-the-transpose-of-the-inverse-of-the-modelview-matrix
法線を$ N・接線を$ V・モデル行列の左上3x3を$ {\bf M}とおく
求めたいのは、Normal Matrix$ {\bf N}
$ V' = {\bf M}V
$ N' = {\bf N}N
$ N \cdot V = 0
$ N' \cdot V' = 0
これらが前提
$ N' \cdot V' = ({\bf N}N) \cdot ({\bf M}V) = 0
$ ({\bf N}N)^T ({\bf M}V) = 0
$ N^T {\bf N}^T {\bf M} V = 0
これより、
$ {\bf N}^T {\bf M} = {\bf I}
$ {\bf N}^T = {\bf M}^{-1}
$ {\bf N} = ({\bf M}^{-1})^T
zeuxの手法
→ zeux's Normal Transformation