1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

3. 双方向パストレーシング

1
Last updated at Posted at 2026-09-14

本記事では双方向パストレーシングについて説明します.なお,前の記事を理解している前提で説明します.

双方向パストレーシングはパストレーシングの発展形で,カメラ側から経路をサンプリングするだけでなく,ライト側からも経路をサンプリングし,それぞれの経路頂点を接続することでライトからカメラに至る経路を生成します(カメラ側からの経路が直接ライトにヒット,ライト側からの経路が直接カメラにヒットすることもあります).

このように経路を生成する場合,同じ経路が複数のサンプリング方法で生成される可能性があります.例えば下図のように経路の長さが3の場合は以下の5通りがあります.

サンプリングパターン.png

全ての経路頂点をカメラ側からサンプリングするのは入射方向サンプリングだけを使ってピクセル値を推定する場合のパストレーシングで,ライトから1つ経路頂点を生成しカメラからの経路と接続するのはNEEを使ったパストレーシングですね.

双方向パストレーシングでは,それら以外のサンプリング戦略も使用したうえで,MISを用いてピクセル値の推定を行います.これにより推定の安定性は大きく向上するのですが,重み関数の計算も非常に複雑になっていきます.また,カメラ側とライト側からの経路を接続するという,通常のパストレーシングにはない処理をするため,そもそもピクセル値をどのように計算するのか?という問題もあります.以降ではこれらについて説明していきます.

ピクセル値

パストレーシングではカメラからレイを飛ばし,ヒット位置でレンダリング方程式を解くためにさらにレイを飛ばして...という形でピクセル値を計算しました.双方向パストレーシングではライト側からもレイを追跡していくので,ピクセル値の計算式を考え直す必要があります.

ピクセル値の計算式を考える前にまずカメラモデルを考え直します.今まではピンホールカメラを考えていましたが,ピンホールカメラではライト側からの経路生成でカメラにヒットすることがないため,レンズがあるカメラモデルを考えます.このモデルでは,まずレンズ上の位置をサンプリングし,次に計算したいピクセルに対応する仮想スクリーン上の位置をサンプリングします.そしてその位置の方向にレイを飛ばすことでカメラから見える位置を決定します.

このカメラモデルを用いることで,ライト側からの経路のサンプリングでレイがレンズにヒットできるようになり,ヒットしたレイが通過したピクセルに光の影響を与えるようになります.

ちなみにこのモデルでは被写界深度を表現でき,仮想スクリーンのある面上でピントが合うようになります.

それではピクセル値の計算式を考えていきます.パストレーシングではカメラから見える位置を起点に出射輝度を考えていましたが,双方向パストレーシングではレンズ上の位置を起点に入射輝度を考えます.$j$番目のピクセル値$I_j$は以下の式で計算されます.

\begin{aligned}
I_j &= \int_{\mathcal{M_l}} \int_\Omega W_j(x,\omega_i)L_i(x,\omega_i)\cos\theta d\omega_i dA
\end{aligned}

ここで,$\mathcal{M_l}$はレンズ上の面,$\Omega$は上半球,$Li$は入射輝度,$\theta$はカメラの向きと入射方向のなす角です.$W_j(x,\omega_i)$は位置$x$に方向$\omega_i$から入射する輝度がピクセル$j$にどの程度影響するかを表す感度のようなものです.仮想スクリーンのピクセル$j$に対応する領域を通る方向に対して値を持ちます(別ピクセルを通る方向でも値を少し持つようにする場合もあります).具体的な式の例は後で説明します.

下の図のように,レンズ上に渡っての積分で,レンズ上の位置では上半球で積分をします.実際に値を持つのは$W_j\ne0$の狭い範囲です.

以降では表記簡略化のためピクセル$j$の依存は省略して,$I$や$W$と表記します.

以前の記事で説明したように,立体角についての積分はシーン上の面についての積分に変換できます.その方が双方向パストレーシングには都合がいいので変換します.

\begin{aligned}
I &= \int_{\mathcal{M_l}} \int_{\mathcal{M}} W(x_0\leftarrow x_1)L(x_0\leftarrow x_1)G_V(x_0,x_1) dA_1 dA_0 \\
\end{aligned}

ここで,$G_V$は幾何項と可視関数を合わせたものです.単に式が長くなるので合わせただけです.$L_i(x_0\leftarrow x_1)$と$W_j(x_0\leftarrow x_1)$はそれぞれ位置$x_0$に位置$x_1$の方向から入射する輝度とそれに対する感度です.数学的にはこういう矢印を使った書き方はよくないらしいですが,CGでは慣習的にこう書かれることが多いので慣習に従います.

数式のイメージ図は以下のような感じです.

輝度$L(x_0\leftarrow x_1)$は,位置$x_1$から位置$x_0$の方向に出射する輝度でもあります.これはレンダリング方程式で表すことができます.シーン上の面についての積分の形式のレンダリング方程式は以下の通りでした.

\begin{aligned}
L(x_0\leftarrow x_1) &= L_e(x_0\leftarrow x_1)+\int_{\mathcal{M}} L(x_1\leftarrow x_2)F(x_0\leftarrow x_1 \leftarrow x_2)G_V(x_1,x_2) dA
\end{aligned}

ここで,$L_e$は発光輝度,$F$はBRDFです.この式をピクセル値の計算式に代入すると以下の式が得られます.

\begin{aligned}
I &= \int_{\mathcal{M_l}} \int_{\mathcal{M}} W(x_0\leftarrow x_1)G_V(x_0,x_1)L_e(x_0\leftarrow x_1) dA_1 dA_0 \\
&+ \int_{\mathcal{M_l}} \int_{\mathcal{M}} \int_{\mathcal{M}} W(x_0\leftarrow x_1)G_V(x_0,x_1) F(x_0\leftarrow x_1 \leftarrow x_2)G_V(x_1,x_2)L(x_1\leftarrow x_2) dA_2dA_1 dA_0
\end{aligned}

ここで,最初の積分式は長さ1の経路(ライトの光がカメラから直接見える経路)のピクセル値への寄与を表しています.2つ目の積分式の$L$に再度レンダリング方程式を代入すると以下の式が得られます.

\begin{aligned}
I &= \int_{\mathcal{M_l}} \int_{\mathcal{M}} W(x_0\leftarrow x_1)G_V(x_0,x_1)L_e(x_0\leftarrow x_1) dA_1 dA_0 \\
&+ \int_{\mathcal{M_l}} \int_{\mathcal{M}} \int_{\mathcal{M}} W(x_0\leftarrow x_1)G_V(x_0,x_1) F(x_0\leftarrow x_1 \leftarrow x_2)G_V(x_1,x_2)L_e(x_1\leftarrow x_2) dA_2dA_1 dA_0 \\
&+ ...
\end{aligned}

2つ目の積分式は長さが2の経路のピクセル値への寄与を表しています.式を見ると反射回数ごとの寄与の式には法則性がありそうです.長さ$k$の経路のピクセル値への寄与$I_{k}$は以下の式で表されます.

\begin{aligned}
I_{k} &= \int_{\mathcal{M_l}}...\int_{\mathcal{M}} W(x_0\leftarrow x_1) G_V(x_0,x_1) \left\{ \prod_{i=1}^{k-1}F(x_{i-1}\leftarrow x_i\leftarrow x_{i+1})G_V(x_i,x_{i+1}) \right\} L_e(x_{k-1}\leftarrow x_k) dA_{k}...dA_0 \\
\end{aligned}

上式を用いてピクセル値は,各経路長の寄与の和で表されます.

\begin{aligned}
I = \sum_{k=1}^{\infty} I_{k}
\end{aligned}

なお,$I_{k}$の計算式があまりにも長いので,簡略化のために以下のように書くことがよくあります.

\begin{aligned}
I_{k} &= \int_{\mathcal{P_k}} f(\bar{x}) d\mu(\bar{x})
\end{aligned}

ここで,$\mathcal{P}_k$は長さ$k$の経路の空間で,$f(\bar{x})$は経路$\bar{x}$がピクセルに与える寄与です.

これでピクセル値の計算式が分かりました.単純に1つのサンプリング戦略でピクセル値$I_{k}$を推定する場合は以下の式となります.

\begin{aligned}
I_{k}\approx\hat{I}_{k}=\frac{f(\bar{X})}{p(\bar{X})}
\end{aligned}

ここで重要なのは,どのようなサンプリング戦略を用いても,その経路自体がピクセルに与える寄与$f$は同じで,異なるのは確率密度関数だけということです.

例えば,経路$\bar{x}=(x_0,x_1,x_2,x_3)$を考えます.$x_0$はレンズ上の位置,$x_3$はライト上の位置です.

すべての経路頂点をカメラ側からサンプリングしていく場合の確率密度関数は以下の通りです.

\begin{aligned}
p(\bar{x})=p_E(x_0)p_E(x_1|x_0)p_E(x_2|x_1,x_0)p_E(x_3|x_2,x_1)
\end{aligned}

ここで,$p_E$はカメラ側からの経路サンプリングにおける確率密度関数です.ピクセル値を位置に関する形で記述したため,確率密度関数も方向ではなく位置に関するものであることに注意してください.

$x_0$はレンズ上の位置で,経路の始点であるため別の位置に依存せずサンプリングされると仮定しています.$x_1$はカメラから見える位置で,レンズ上の位置$x_0$に依存します.位置$x_2$以降は入射方向サンプリングを介して決まるもので直前の2つの位置に依存します.$p_E(x_0)$と$p_E(x_1|x_0)$の具体的な式は後で説明します.

一方,すべての経路頂点をライト側からサンプリングしていく場合の確率密度関数は以下の通りです.

\begin{aligned}
p(\bar{x})=p_L(x_3)p_L(x_2|x_3)p_L(x_1|x_2,x_3)p_L(x_0|x_1,x_2)
\end{aligned}

ここで,$p_L$はライト側からの経路サンプリングにおける確率密度関数です.サンプリングにおける依存性の話は順序が変わっただけで先ほどと同様です.

そして,カメラ側から2個,ライト側から2個の経路頂点を生成し接続する場合の確率密度関数は以下の通りです.

\begin{aligned}
p(\bar{x})=p_E(x_0)p_E(x_1|x_0)p_L(x_2|x_3)p_L(x_3)
\end{aligned}

他にも,(カメラ側から1個,ライト側から3個),(カメラ側から3個,ライト側から1個)の経路頂点を生成し接続するサンプリング方法も考えられ,同じような感じの確率密度関数の式になります.双方向パストレーシングでは,これらすべてのサンプリング戦略をMISで組み合わせてピクセル値を推定します.

ピクセル値の推定

ピクセル値$I$は経路長毎の寄与$I_{k}$の総和で表されていました.そのため,すべての寄与$\hat{I}_{k}$を推定し,加算していけばピクセル値の推定値$\hat{I}$が得られます.最初に説明した通り,双方向パストレーシングではあらゆる経路頂点の生成パターンのサンプリング戦略を使用しMISで組み合わせます.この場合のピクセル値の推定値$\hat{I} _{k}$は以下の式で表されます.

\begin{aligned}
\hat{I}_{k}=\sum_{s=0}^{k+1} \frac{1}{n_{s,t}} \sum_{i=1}^{n_{s,t}}  w_{s,t}(\bar{X}_{s,t}^{(i)}) \frac{f(\bar{X}_{s,t}^{(i)})}{p_{s,t}(\bar{X}_{s,t}^{(i)})}
\end{aligned}

ここで,$s$番目の戦術はカメラ側とライト側からそれぞれ$s$個と$t(=k+1-s)$個の経路頂点をサンプリングするものとします.$n_{s,t}$と$p_{s,t}$はそれぞれ各戦術のサンプル数と確率密度関数,$\bar{X}_{s,t}^{(i)}$は各戦略の$i$番目の経路のサンプルです.

この式を評価するには,各戦略で対応する数だけカメラ側とライト側から経路頂点のサンプリングを行う必要があります.しかしながら,経路のサンプリングは計算負荷が高く,また,他の経路長の寄与の推定も必要であるため,1つ1つの戦略毎に真面目に経路をサンプリングをしていては負荷が高すぎるという問題があります.

そこで双方向パストレーシングでは,カメラ側とライト側それぞれから一度だけ経路をサンプリングし,その経路をすべての$\hat{I}_k$の計算で共有します.なお,このときの経路のサンプリングは事前に決めた最大経路頂点数に達するか,ロシアンルーレットで打ち切られるまで経路頂点を作り続けます.

例えば下の左図では,カメラから2個,ライトから2個の経路頂点を生成する戦略のサンプルとして,経路長3の積分値の推定に使用します.右図では,カメラから2個,ライトから3個の経路頂点を生成する戦略のサンプルとして,経路長4の積分値の推定に使用します.

サンプル数

双方向パストレーシングでは,各ピクセルでカメラとライトそれぞれから1本の経路をサンプリングします.カメラから2個以上の経路頂点をサンプリングする戦略では,そのピクセルにだけ寄与する経路しかサンプリングされませんが,2個未満の場合は,他のピクセルにも寄与する経路がサンプリングされる場合があります.

つまり,カメラから2個以上の経路頂点をサンプリングする戦略のサンプル数を1とするならば,2個未満の場合の戦略のサンプルはピクセルの数だけあるということになります.

注意として,ピクセルに寄与した経路だけをカウントしてサンプル数とするべき?と悩んでしまうことがあるのですが,寄与する可能性がある経路のサンプリングを行っている時点でサンプル数に含まれるのです.被積分関数が0の領域をサンプリングしただけということです.

重み関数の計算

双方向パストレーシングでは,使用する戦略数が多いため重み関数にも工夫が必要になります.ここではカメラ側から3個,ライト側から3個の経路頂点を生成する戦略の重み関数$w_{3,3}(\bar{x})$で説明します.なお,カメラ側とライト側から生成する経路をそれぞれ$\bar{y}=(y_0,y_1,y_2)$と$\bar{z}=(z_0,z_1,z_2)$とし,それぞれを接続したカメラからライトに至る経路を$\bar{x}=(y_0,y_1,y_2,z_2,z_1,z_0)$で表します.

重み関数の定義通りの式は以下の通りになります.

\begin{aligned}
w_{3,3}(\bar{x})&=\frac{p_{3,3}(\bar{x})}{ 
n_{0,6}p_{0,6}(\bar{x})+ 
n_{1,5}p_{1,5}(\bar{x})+ 
p_{2,4}(\bar{x})+ 
p_{3,3}(\bar{x})+ 
p_{4,2}(\bar{x})+ 
p_{5,1}(\bar{x})+ 
p_{6,0}(\bar{x})
} \\
\end{aligned}

なお表記簡略化のため,カメラから2個以上の経路頂点をサンプリング戦略のサンプル数を1としています.このとき2個未満のもののサンプル数$n_{0,6}$,$n_{1,5}$はピクセルの数です.

双方向パストレーシングでは使用する戦略数が多いため,定義式通りに計算するのはコストが高いです.双方向パストレーシングでは各積分の推定のためのサンプルを共有するため,それを利用した効率的な計算方法を探していきます.

まず,分子が1になるように,分母分子を$p_{3,3}(\bar{x})$で除算します.

\begin{aligned}
w_{3,3}(\bar{x})=1/ \left\{
n_{0,6}\frac{p_{0,6}(\bar{x})}{p_{3,3}(\bar{x})}+
n_{1,5}\frac{p_{1,5}(\bar{x})}{p_{3,3}(\bar{x})}+
\frac{p_{2,4}(\bar{x})}{p_{3,3}(\bar{x})}+
1+
\frac{p_{4,2}(\bar{x})}{p_{3,3}(\bar{x})}+
\frac{p_{5,1}(\bar{x})}{p_{3,3}(\bar{x})}+
\frac{p_{6,0}(\bar{x})}{p_{3,3}(\bar{x})}
\right\} \\
\end{aligned}

式が長くなりすぎるので記号を使います.

\begin{aligned}
w_{3,3}(\bar{x})&=\frac{1}{w_E+1+w_L} \\
w_E&=n_{0,6}\frac{p_{0,6}(\bar{x})}{p_{3,3}(\bar{x})}+
n_{1,5}\frac{p_{1,5}(\bar{x})}{p_{3,3}(\bar{x})}+
\frac{p_{2,4}(\bar{x})}{p_{3,3}(\bar{x})} \\
w_L&=\frac{p_{4,2}(\bar{x})}{p_{3,3}(\bar{x})}+
\frac{p_{5,1}(\bar{x})}{p_{3,3}(\bar{x})}+
\frac{p_{6,0}(\bar{x})}{p_{3,3}(\bar{x})}
\end{aligned}

$w_E,w_L$をさらに変形していきます.変形過程は同じなので$w_E$の変形で説明します.まず$p_{0,6}(\bar{x})/p_{3,3}(\bar{x})$を以下のように整理していきます.

\begin{aligned}
\frac{p_{0,6}(\bar{x})}{p_{3,3}(\bar{x})}&=\frac{p_L(y_0y_1y_2z_2z_1z_0)}{p_E(y_0y_1y_2)p_L(z_2z_1z_0)}\\
&=\frac{p_L(y_0y_1y_2|z_2,z_1)}{p_E(y_0y_1y_2)}\\
&=\frac{p_L(y_0|y_1,y_2)}{p_E(y_0)}\frac{p_L(y_1|y_2,z_2)}{p_E(y_1|y_0)}\frac{p_L(y_2|z_2,z_1)}{p_E(y_2|y_1,y_0)}\\
\end{aligned}

$p_{1,5}(\bar{x})/p_{3,3}(\bar{x})$と$p_{2,4}(\bar{x})/p_{3,3}(\bar{x})$も同様にして以下を得ます.

\begin{aligned}
\frac{p_{1,5}(\bar{x})}{p_{3,3}(\bar{x})}&=\frac{p_L(y_1|y_2,z_2)}{p_E(y_1|y_0)}\frac{p_L(y_2|z_2,z_1)}{p_E(y_2|y_1,y_0)}\\
\frac{p_{2,4}(\bar{x})}{p_{3,3}(\bar{x})}&=\frac{p_L(y_2|z_2,z_1)}{p_E(y_2|y_1,y_0)}\\
\end{aligned}

各式に共通の項が含まれているので,それらをまとめて$w_E$を書き直します.

\begin{aligned}
w_E&=\left( \left( n_{0,6} \frac{\color{red}{p_L(y_0|y_1,y_2)}}{\color{red}{p_E(y_0)}} +n_{1,5} \right) \frac{p_L(y_1|y_2,z_2)}{\color{red}{p_E(y_1|y_0)}} +1 \right) \frac{p_L(y_2|z_2,z_1)}{\color{red}{p_E(y_2|y_1,y_0)}} 
\end{aligned}

ここで,赤字のものはカメラから経路頂点の生成を行った時点で計算できます.その他のものは,接続対象が決まってからしか計算できないものです.

$w_L$も同様にして以下のように求められます.

\begin{aligned}
w_L&= \frac{p_E(z_2|y_2,y_1)}{\color{red}{p_L(z_2|z_1,z_0)}} \left( 1+\frac{p_E(z_1|z_2,y_2)}{\color{red}{p_L(z_1|z_0)}} \left( 1+\frac{\color{red}{p_E(z_0|z_1,z_2)}}{\color{red}{p_L(z_0)}} \right)  \right) \\
\end{aligned}

以上より,重み関数の計算が,事前計算分を除けば最大4頂点の確率密度関数を計算するだけですむようになりました.


他の例も式だけ見ておきます.$w_{3,2}(\bar{x})$は以下の通りです.

\begin{aligned}
w_{3,2}(\bar{x})&=\frac{1}{w_E+1+w_L} \\
w_E&=\left( \left( n_{0,5}\frac{\color{red}{p_L(y_0|y_1,y_2)}}{\color{red}{p_E(y_0)}} +n_{1,4} \right) \frac{p_L(y_1|y_2,z_1)}{\color{red}{p_E(y_1|y_0)}} +1 \right) \frac{p_L(y_2|z_1,z_0)}{\color{red}{p_E(y_2|y_1,y_0)}}  \\
w_L&= \frac{p_E(z_1|y_1,y_2)}{\color{red}{p_L(z_1|z_0)}} \left( 1+\frac{p_E(z_0|z_1,y_2)}{\color{red}{p_L(z_0)}} \right) \\
\end{aligned}

$w_{3,1}(\bar{x})$は以下の通りです.

\begin{aligned}
w_{3,1}(\bar{x})&=\frac{1}{w_E+1+w_L} \\
w_E&=\left( \left( n_{0,4}\frac{\color{red}{p_L(y_0|y_1,y_2)}}{\color{red}{p_E(y_0)}} +n_{1,3} \right) \frac{p_L(y_1|y_2,z_0)}{\color{red}{p_E(y_1|y_0)}} +1 \right) \frac{p_L(y_2|z_0)}{\color{red}{p_E(y_2|y_1,y_0)}}  \\
w_L&= \frac{p_E(z_0|y_1,y_2)}{\color{red}{p_L(z_0)}} \\
\end{aligned}

$w_{3,0}(\bar{x})$は以下の通りです.

\begin{aligned}
w_{3,0}(\bar{x})&=\frac{1}{w_E+1+w_L} \\
w_E&=\left( \left( n_{0,3}\frac{\color{red}{p_L(y_0|y_1,y_2)}}{\color{red}{p_E(y_0)}} +n_{1,2} \right) \frac{p_L(y_1|y_2)}{\color{red}{p_E(y_1|y_0)}} +1 \right) \frac{p_L(y_2)}{\color{red}{p_E(y_2|y_1,y_0)}}  \\
w_L&=0
\end{aligned}

最大経路頂点数に関する注意

重み関数を計算する上で,最大経路頂点数を決めて経路頂点をサンプリングしていく場合は注意が必要です.例えば,最大経路頂点数を4としていても,カメラ側とライト側の経路を接続したときの経路頂点数は4個を超えます.

カメラ側とライト側の経路頂点数の和が最大経路頂点数を超えた場合の重み関数の場合,例えば重み関数$w_{2,3}$の場合,計算式には$p_{0,5}$や$p_{5,0}$が含まれます.しかしながら,最大経路頂点数が4なので,片側から5個の経路頂点をサンプリングすることはできません.そのためこれらの確率密度関数値は0として扱う必要があります.

さいごに

双方向パストレーシングは通常のパストレーシングと比べてはるかに実装が複雑になります.この記事では最小限のことだけを説明しましたが,鏡のような完全に1方向にしか反射しない材質では特別扱いが必要であったり,幾何法線ではなく見た目を滑らかにするためのシェーディング法線を使用するとライト側からの追跡で特別扱いが必要になるなど,考慮すべきことがいろいろあります.

なので,もし実装しようとする人がいたなら,そもそもの双方向パストレーシングの実装が大変なので,まずはこれらの考慮が不要なシンプルなシーンで実装するのがいいでしょう.

また,いきなり双方向パストレーシングを実装しようとせず,まずはライトから経路をサンプリングしカメラと接続する戦略だけを使って,パストレーシングの結果と一致するか確認するのも大事です.先に説明したように,どのようなサンプリング戦略を使ってもサンプル数を増やせば同じ結果画像になります.

以上おわり.

補足

カメラ周りの確率密度関数

まずレンズ上の位置$x_0$についてです.レンズは円盤で表現し,位置は円盤状を一様にサンプリングするとします.この場合の確率密度関数は以下の通りです.

\begin{aligned}
p_E(x_0)=\frac{1}{\pi r^2}
\end{aligned}

ここで,$r$はレンズの半径です.

次にカメラからのレイのヒット位置$x_1$についてです.レンズ上の位置をサンプリングした後は,レイの方向をサンプリングするのではなく,仮想スクリーン上のピクセルに対応する位置$x_1'$をサンプリングし,その位置の方向にレイを飛ばすことでヒット位置$x_1$がサンプリングされました.

この場合の$x_1$の確率密度関数はどうなるのでしょうか?これには以下の関係式を活用します.

\begin{aligned}
p(x)dA&=p(\omega)d\omega \\
p(x)&=p(\omega) \left| \frac{d\omega}{dA} \right| \\
&=p(\omega) \frac{\cos\theta}{||x-y||^2} \\
p(\omega)&=p(x) \frac{||x-y||^2}{\cos\theta} \\
\end{aligned}

仮想スクリーン上の位置$x_1'$は,ピクセルに対応する仮想スクリーン上の領域を一様サンプリングすることにより決まるため,確率密度関数は以下の通りです.

\begin{aligned}
p_E(x_1')=\frac{1}{A_p}
\end{aligned}

ここで,$A_p$はピクセルに対応する仮想スクリーン上の領域の面積です.位置$x_0$から位置$x_1'$の方向を$\omega_1$とすると

\begin{aligned}
p_E(\omega_1|x_0)=p_E(x_1')\frac{||x_0-x_1'||^2}{\cos\theta'}
\end{aligned}

そして,位置$x_0$方向$\omega_1$のレイがヒットする位置を$x_1$とすると,

\begin{aligned}
p_E(x_1|x_0)=p_E(\omega_1|x_0)\frac{\cos\theta}{||x_0-x_1||^2}
\end{aligned}

まとめると

\begin{aligned}
p_E(x_1|x_0)=\frac{1}{A_p}\frac{\cos\theta}{\cos\theta'}\frac{||x_0-x_1'||^2}{||x_0-x_1||^2}
\end{aligned}

です.

カメラ感度

カメラ感度$W$は自由に設定していいものなのですが,通常のパストレーシングと一致するものを使用するのが実装の正しさを検証するうえでおすすめです.

ここで言う通常のパストレーシングは,カメラからのレイがヒットした位置で,カメラ方向に出射する輝度をそのままピクセル値にしている場合です.

ピクセル値の式からもわかるように,レンズ上の位置$x_0$とカメラからのレイがヒットした位置$x_1$の間にも幾何項が存在し,カメラ感度$W$を定数とした場合は,スクリーンの外側のピクセルほど暗くなるはずです.

図で書くと左図のように画面端のピクセルほど立体角が狭く,確かに入射する光が少なくなっています.右図は写真の例です(Microsoft Copilotで作りました).

しかしながら,パストレーシングで生成する画像は画面端でも暗くなることはなく,どこでもいい感じの明るさになります.これは,暗黙的に画面端が暗くなるのを打ち消すカメラ感度$W$を使用していたからです.

つまりは,ピクセル値の推定における位置$x_0$と位置$x_1$間の値が1となるカメラ感度$W$を使用していたのです.

\begin{aligned}
\frac{W(x_0\leftarrow x_1)G(x_0,x_1)}{p_E(x_0,x_1)}=1 \\
W(x_0\leftarrow x_1)=\frac{p_E(x_0,x_1)}{G(x_0,x_1)} \\
\end{aligned}

このカメラ感度$W$を使えば双方向パストレーシングでも,通常のパストレーシングと同じ結果を得ることができます.

1
1
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?