古典的レイトレーサーの実装(第3回) 練習問題解答例
第3回の練習問題の解答例

問1

まず入射レイd⃗\vec{d}を水平成分dh⃗\vec{d_h}と垂直成分dp⃗\vec{d_p}に分解してみよう。

dp⃗=−(d⃗⋅n⃗)n⃗dh⃗=d⃗−dp⃗=d⃗+(d⃗⋅n⃗)n⃗\begin{aligned} \vec{d_p} &= -(\vec{d}\cdot\vec{n})\vec{n} \\ \vec{d_h} &= \vec{d} - \vec{d_p} = \vec{d} + (\vec{d}\cdot\vec{n})\vec{n} \end{aligned}

この水平成分と垂直成分の長さに注目すると∥d⃗∥=1\| \vec{d} \| = 1より

∥dp⃗∥=cos⁡θi∥dh⃗∥=sin⁡θi\begin{aligned} \| \vec{d_p} \| = \cos{\theta_i}\\ \| \vec{d_h} \| = \sin{\theta_i} \end{aligned}

という関係がある。

同様に屈折レイも水平成分rh⃗\vec{r_h}と垂直成分rp⃗\vec{r_p}に分解する。

スネルの法則より

sin⁡θt=n1n2sin⁡θi\sin{\theta_t} = \frac{n_1}{n_2}\sin{\theta_i}

であるから、

∥rh∥=n1n2∥dh⃗∥\| r_h \| = \frac{n_1}{n_2}\| \vec{d_h} \|

が成り立つ。水平成分の方向は変化しないから

rh⃗=n1n2dh⃗=n1n2(d⃗+(d⃗⋅n⃗)n⃗)\vec{r_h} = \frac{n_1}{n_2}\vec{d_h} = \frac{n_1}{n_2}(\vec{d} + (\vec{d}\cdot\vec{n})\vec{n})

となる。 ∥r⃗∥=1\| \vec{r} \| = 1より

∥rp⃗∥=1−∥rh⃗∥2\|\vec{r_p}\| = \sqrt{1 - \|\vec{r_h}\|^2}

となり、垂直成分の方向は−n⃗-\vec{n}であるから

rp⃗=−1−∥rh⃗∥2n⃗\vec{r_p} = -\sqrt{1 - \|\vec{r_h}\|^2}\vec{n}

である。 よって

r⃗=rh⃗+rp⃗=n1n2(d⃗+(d⃗⋅n⃗)n⃗)−1−∥rh⃗∥2n⃗\vec{r} = \vec{r_h} + \vec{r_p} = \frac{n_1}{n_2}(\vec{d} + (\vec{d}\cdot\vec{n})\vec{n}) -\sqrt{1 - \|\vec{r_h}\|^2}\vec{n}

となる。

問2

まず球のyy軸方向で[−1,1][-1, 1]から一様サンプリングする。サンプリングした結果をuuとすると、y=uy = uのところで球をスライスする。あとはスライスされた円の縁上で点を一様にサンプリングすれば良い。

y=uy = uでスライスされた円の半径は1−u2\sqrt{1 - u^2}である。したがって、あとは円での角度θ\thetaを[0,2π][0, 2\pi]から一様にサンプリングすれば

y=ux=1−u2cos⁡θz=1−u2sin⁡θ\begin{aligned} y &= u\\ x &= \sqrt{1 - u^2}\cos{\theta}\\ z &= \sqrt{1 - u^2}\sin{\theta} \end{aligned}

で球上の点を一様にサンプリングすることができる。これをそのまま方向ベクトルとして使えば良い。