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

問1

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

dp=(dn)ndh=ddp=d+(dn)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θidh=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=n1n2dh\| r_h \| = \frac{n_1}{n_2}\| \vec{d_h} \|

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

rh=n1n2dh=n1n2(d+(dn)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=1rh2\|\vec{r_p}\| = \sqrt{1 - \|\vec{r_h}\|^2}

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

rp=1rh2n\vec{r_p} = -\sqrt{1 - \|\vec{r_h}\|^2}\vec{n}

である。 よって

r=rh+rp=n1n2(d+(dn)n)1rh2n\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でスライスされた円の半径は1u2\sqrt{1 - u^2}である。したがって、あとは円での角度θ\theta[0,2π][0, 2\pi]から一様にサンプリングすれば

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

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