椿の日記

たぶんプログラムの話をします

Frequency Domain Normal Map Filtering続きの続き

論文のセクション8にも意味が分からなかった部分があったのですが、解決したので覚書しておきます。

問題を要約すると、入射方向ωi、出射方向ωo、そのハーフ角ωhについて、

\displaystyle \int_{S^2} L(\omega_i) f(\omega_h(\omega_i,\omega_o)) d\omega_i = \int_{S^2} L(\omega_i(\omega_h,\omega_o)) f(\omega_h) 4(\omega_h \cdot \omega_i) d\omega_h

が成り立つ、というものです。通常の反射の積分は入射方向で球面上を積分しますが、Blinn-PhongとかTorrance-Sparrowなどではハーフ角が主役になり、その積分変数に変換したのが上記式です。

このように変換しておくと、予めLと4(ωi・ωh)の積についてωhで球面調和展開した形式を用意しておけば、照明計算を畳み込みによってただの線形結合で表せるようになります(但し、Lはωiとωoにも依存しているため、ωiとωoに関して離散化したテーブルを用意し、それを補間する必要があります)。

で、このとき置換積分に伴って現れる 4(ωi・ωh) は一体どこからくるねん!という話なのですが、Physically Based Rendering From Theory to Implementationに解法が載っていました。以下は、ほぼそのまんま本の内容です。

まず、ωoを基準とする座標系に移し変えて考えます。例えばωiとωoを含む平面を考えると次のような図を考えられます。

f:id:tbk:20121208030556p:plain

ここでθiはωiとωoの間の角度、θhはωhとωoの間の角度です。ここで立体角ωiとωhは単位球上の面積を表し、その微小な変動量は次のように求まります。

\displaystyle d\omega_i=\sin \theta_i d\theta_i \cdot d\phi_i
\displaystyle d\omega_h=\sin \theta_h d\theta_h \cdot d\phi_h
従って、

\displaystyle \frac{d\omega_i}{d\omega_h} = \frac{\sin\theta_i \cdot d\theta_i d\phi_i}{\sin\theta_h \cdot d\theta_h d\phi_h}
ωhはωiとωoのハーフ角なのでθi=2θhです。また、ωoを基準とする座標系においてはφi=φhが成立しています。従って、

\displaystyle \frac{d\omega_i}{d\omega_h} = \frac{\sin2\theta_h \cdot 2d\theta_h \phi_h}{\sin\theta_h \cdot d\theta_h d\phi_h}

sin2θを倍角の公式で展開し、微少量dθh dφhを消去すると、

\displaystyle \frac{d\omega_i}{d\omega_h} = \frac{4\sin\theta_h\cos\theta_h}{\sin\theta_h} = 4\cos \theta_h = 4(\omega_i \cdot \omega_h)

これがωiからωhへ積分変数変換したときに発生します。