Theory of Physically Based Rendering 1
レイトレの数理モデル, 放射輝度, BRDF, レンダリング方程式などについて

この資料では 物理ベースレンダリング(Physically Based Rendering) を実現するために必要な数学・理論・実装について説明しています。

次のような事柄をこの資料では説明しています。

  • レイトレの数学的モデル
  • 光の物理量
  • BSDF(BRDF, BTDF)
  • レンダリング方程式
  • レンダリング方程式の作用素表現
  • カメラのモデル化
  • 経路積分形式のレンダリング方程式
  • レンダリング方程式の計算について

レイトレの数学的モデル

まずレイトレーシングで行っていることを数学的に表現することを考えます。

方向

方向ベクトルω\vec{\omega}は3次元の単位球面S2={v=1vR3}\mathcal{S}^2 = \{ ||\vec{v}|| = 1 | \vec{v} \in \mathbb{R}^3 \}上の点として表現します。こうすることで方向ベクトルは大きさが1に正規化されたもののみになります。

物体表面

シーンにある物体表面上の点全体を表す集合をM\mathcal{M}とします。物体表面上で微積分が行えないと理論が展開できないので、M\mathcal{M}区分的に微分可能な2次元多様体(2-dimensional Piecewise Differencial Manifold) として定義しておきます。

一般の空間上での積分

レイトレでは方向ベクトルによる積分や、物体表面上での積分などが頻繁に出てきます。これらの厳密な定義を知らなくても議論を進めることはできるのですが、ある程度知らないと何故?ってなると思うので、簡単に紹介します。

一般の空間XX上での積分を定義するためには、測度(Measure)μ\mu というものを導入し、測度空間(Measure Space)(X,F,μ)(X, \mathcal{F}, \mu)を構成する必要があります。

σ\sigma加法族

F\mathcal{F}σ\sigma加法族 といい、XXの部分集合を持つ集合(集合族)です。σ\sigma加法族は次のような定義になっています。

  1. ϕF\phi \in \mathcal{F}
  2. DFDcFD \in \mathcal{F} \Longrightarrow D^c \in \mathcal{F}
  3. D1,D2,...Fi=1DiFD_1, D_2, ... \in \mathcal{F} \Longrightarrow \cup_{i=1}^{\infty} D_i \in \mathcal{F}

この定義から F\mathcal{F}に属する集合の和・差・積を高々加算無限回行って得られる集合はまたF\mathcal{F}に属している ことが分かります。

このF\mathcal{F}に属している集合を 可測集合(Measurable Set) といいます。後で見るように測度はF\mathcal{F}に含まれる集合に対して定義されているので、可測集合でない集合では測度が計算できません。

測度

F\mathcal{F}に含まれる集合D1,D2,...FD_1, D_2, ... \in \mathcal{F}に対して次のような集合関数μ\muを定義します。

  1. 0μ(Di)0 \le \mu(D_i) \le {\infty} (非負性)
  2. μ(ϕ)=0\mu(\phi) = 0
  3. DiDj=ϕ(ij)D_i \cap D_j = \phi (i \neq j)のとき、μ(i=1Di)=i=1μ(Di)\mu(\cup_{i=1}^{\infty}D_i) = \sum_{i=1}^{\infty}\mu(D_i) (可算加法性)

この集合関数を 測度(Measure) といいます。測度は与えられた集合の大きさを測ってくれる関数です。例えばR\mathbb{R}上なら長さ、R2\mathbb{R}^2なら面積が測度の1つになります。

測度による積分

単関数の積分

F\mathcal{F}に属し、互いに交わらない集合D1,D2,...,DnD_1, D_2, ..., D_nが与えられているとします。D=i=1nDiD = \cup_{i=1}^{n} D_iとします。DiD_i上で一定値aiRa_i \in \mathbb{R}を取る、DD上で定義された関数ffを考えます。この関数は集合の定義関数1Di(x)\boldsymbol{1}_{D_i}(x)を用いて

f(x)=i=1nai1Di(x)  xDf(x) = \sum_{i=1}^{n} a_i\boldsymbol{1}_{D_i}(x) ~~ x \in D

として表現できます。このような関数ff単関数(Simple Function) といいます。

ai0a_i \ge 0となる単関数をf0f \ge 0で表すことにします。

単関数の積分を考えましょう。リーマン積分では、一変数関数の積分はxx軸を一定間隔で分割し、その区間幅と関数の値をかけ合わせたものを足すことで積分を定義していました。

これと同様に、正の単関数f0f \ge 0の測度μ\muによる積分を

Dfdμ=i=1naiμ(Di)\int_D fd\mu = \sum_{i=1}^{n} a_i\mu(D_i)

として定義します。(これはDDの表し方によらない)

可測関数

DD上の一般の関数で上のような積分を定義しようとすると、μ(Di)\mu(D_i)が計算できる必要があることが分かります。つまり、f(x)=aif(x) = a_iであるようなxxの集合をf=aif = a_iと表すとすると、(f=ai)F(f = a_i) \in \mathcal{F}である必要があります。

σ\sigma加法族の定義から、これは(f<ai)F(f < a_i) \in \mathcal{F}と同値であることが分かります。これを満たす関数を 可測関数(Measurable Function) といいます。

一般の可測関数の積分

DD上の任意の可測関数ffの積分を考えます。ff

f+(x)=max{f(x),0}     f(x)=max{f(x),0}f^+(x) = \max\{f(x), 0\} ~~~~~ f^-(x) = \max\{-f(x), 0\}

のように、値が正の部分と負の部分に分割します。このときf+,f0f^+, f^- \ge 0です。

f(x)f(x)はこの2つの関数を用いてf(x)=f+(x)f(x)f(x) = f^+(x) - f^-(x)と表せます。

ffが可測であることは、f+f^+ff^-が両方とも可測であることと同値です。

まずf+f^+の積分を考えます。f+f^+に対しては、DD上の単関数fi(x)0f_i(x) \ge 0の単調増加列で、ffに各点収束するものが存在します。この単調増加列を{fi}\{f_i\}としたとき、f+f^+の測度μ\muによる積分を

Df+dμ=limiDfidμ\int_D f^+d\mu = \lim_{i \to \infty} \int_D f_id\mu

として定義します(これは{fi}\{f_i\}の表し方によらない)。ff^-の積分も同様に定義されます。

次にffの積分を考えます。f=f+ff = f^+ - f^-と表されているので、Ef+dμ\int_E f^+d\muEfdμ\int_E f^-d\muのどちらか一方が有限の値を取るとき、ffの測度μ\muによる積分を

Dfdμ=Df+dμDfdμ\int_D fd\mu = \int_D f^+d\mu - \int_D f^-d\mu

と定義します。この値が有限のとき、ffDD上可積分であるといいます。

S2\mathcal{S}^2上での積分

S2\mathcal{S}^2上の表面積を表す測度を 立体角測度(Solid Angle Measure) といい、σ\sigmaで表します。

これは平面の角度の概念を3次元空間に一般化したようなものです。ΩS2\Omega \in \mathcal{S}^2上の可測関数ffの立体角測度による積分を

Ωf(ω)dσ(ω)\int_{\Omega} f(\vec{\omega})d\sigma(\vec{\omega})

と表します。(多様体論の微分形式からこのような測度が導かれるようです)

具体的な計算方法

この積分は半径1の球面座標系(θ,ϕ)(\theta, \phi)を用いて表すことができます。立体角と球面座標系には

dσ=sinθdθdϕd\sigma = \sin{\theta}d\theta d\phi

という関係があります。((x,y,z)(r,θ,ϕ)(x, y, z) \rightarrow (r, \theta, \phi)のヤコビアンを求めてr=1r=1と置くとsinθ\sin{\theta}が得られる)

これを用いて立体角による積分はΩ\Omegaを区間[θ1,θ2]×[ϕ1,ϕ2][\theta_1, \theta_2] \times [\phi_1, \phi_2]として表現することで

Ωf(ω)dσ(ω)=ϕ1ϕ2θ1θ2f(θ,ϕ)sinθdθdϕ\int_{\Omega} f(\vec{\omega})d\sigma(\vec{\omega}) = \int_{\phi_1}^{\phi_2}\int_{\theta_1}^{\theta_2}f(\theta, \phi)\sin{\theta}d\theta d\phi

と計算することができます。これは後で頻繁に使います。

M\mathcal{M}上での積分

M\mathcal{M}上の表面積を表す測度を 面積測度(Area Measure) といい、AAで表します。

DMD \in \mathcal{M}上の可測関数ffの面積測度による積分を

Df(x)dA(x)\int_{D} f(x)dA(x)

と表します。(これも立体角測度と同様に、多様体論からこのような測度が存在することが言えます)

レイ

レイは始点oR3\vec{o} \in \mathbb{R}^3と、方向ベクトルdS2\vec{d} \in \mathcal{S}^2を定義することで表現できます。レイ上にある全ての点集合RR

R={o+tdtR+}R = \{ \vec{o} + t\vec{d} | t \in \mathbb{R}^{+} \}

と表現できます。ここでR+\mathbb{R}^+は正の実数全体を表す集合です。

レイキャスト関数

シーンM\mathcal{M}が与えられたとき、レイを飛ばしてM\mathcal{M}との衝突点xx'を求める関数を レイキャスト関数(Raycasting Function) r(x,d)r(x, \vec{d})として定義します。

tclose=inf{tRt>0,o+tdM}r(x,d)=o+tclosed\begin{aligned} t_{close} &= \inf\{ t \in \mathbb{R} | t > 0, \vec{o} + t\vec{d} \in \mathcal{M} \} \\ r(x, \vec{d}) &= \vec{o} + t_{close}\vec{d} \end{aligned}

tcloset_{close}o\vec{o}からd\vec{d}にレイを飛ばしたときの衝突距離を表します。

光の物理量

物理ベースレンダリングを行うためには、まず光のどういった物理量を計算すれば良いのかを知らなくてはなりません。物理ベースレンダリングでは 放射測定学(Radiometry) と呼ばれる物理の分野で定義される物理量が計算の基礎になります。

光のエネルギー

波長λ\lambda光子(Photon) 1つのエネルギーeλe_{\lambda}

eλ=hcλe_{\lambda} = \frac{hc}{\lambda}

として定義されます。ここでhhはプランク定数、ccは光速です。

放射エネルギー

波長λ\lambdaの光子がnn個あるとき、スペクトル放射エネルギーQλQ_{\lambda}

Qλ=neλQ_{\lambda} = ne_{\lambda}

として定義されます。これを全波長に渡って積分することで、光の放射エネルギーQQ

Q=0QλdλQ = \int_0^{\infty} Q_{\lambda} d\lambda

として定義されます。これはそれぞれの波長で存在する光子の数を合計したものと見ることができます。

放射束

放射束(Radiant Flux) Φ\Phiは単位時間あたりの放射エネルギーで、以下のように定義されます。

Φ=dQdt\Phi = \frac{dQ}{dt}

これは単位時間あたりの光子の数を表していると見ることができます。

放射照度

放射照度(Irradiance)EEM\mathcal{M}上の単位面積あたりの放射束を表し、

E(x)=dΦdAE(x) = \frac{d\Phi}{dA}

と定義されます。これはM\mathcal{M}上のある点xxを単位時間あたりに通過する光子の数と見ることができます。

放射輝度

放射輝度(Radiance)LLM\mathcal{M}上の単位面積あたり、単位立体角あたりの放射束として定義され

L(x,ω)=d2ΦcosθdAdσL(x, \vec{\omega}) = \frac{d^2\Phi}{|\cos{\theta}|dAd\sigma}

と表されます。θ\thetaは点xxにおける法線N(x)\vec{N(x)}と方向ベクトルω\vec{\omega}のなす角度です。cosθ|\cos{\theta}|

cosθ=N(x)ω|\cos{\theta}| = |\vec{N(x)}\cdot\vec{\omega}|

として、2つのベクトルの内積をとることで計算できます。cosθdA|\cos{\theta}|dAは物体表面上の単位面積dAdAを方向ベクトルω\vec{\omega}の方向に投影した単位面積を表しています。

放射輝度はM\mathcal{M}上のある点xxにある方向ω\vec{\omega}からやってくる、単位時間あたりに通過する光子の数を表していると考えることができます。

物理ベースレンダリングでは放射輝度が最も重要な物理量です。レイトレではカメラセンサー上の点に、ある方向からやってくる光の強さを計算することになりますが、この光の強さというのがまさに放射輝度になっています。

放射輝度の重要な性質として、真空中では光が進行しても放射輝度の値が変化しない ことが挙げられます。真空のシーンでは物体表面上でしか放射輝度の変化が発生しないので、レイが空気中を進行している最中の光の作用を全て無視することができます。

放射輝度から放射照度を求める

放射輝度L(x,ω)L(x, \vec{\omega})cosθ|\cos{\theta}|をかけたものを立体角測度で積分することで放射照度が求まります。

E(x)=ΩL(x,ω)cosθdσ(ω)E(x) = \int_{\Omega} L(x, \vec{\omega})|\cos{\theta}|d\sigma(\vec{\omega})

放射輝度から放射束を求める

上で求めたEEをさらに面積測度で積分することで放射束が求まります。

Φ=DE(x)dA(x)=DΩL(x,ω)cosθdσ(ω)dA\begin{aligned} \Phi &= \int_D E(x)dA(x) \\ &= \int_D \int_{\Omega} L(x, \vec{\omega})|\cos{\theta}|d\sigma(\vec{\omega})dA \end{aligned}

BRDF

光が物体に当たると反射・屈折が発生します。

xxから方向ω\vec{\omega}に出射していく放射輝度をLo(x,ω)L_o(x, \vec{\omega})、点xxに方向ω\vec{\omega}から入射してくる放射輝度をLi(x,ω)L_i(x, \vec{\omega})と表すことにします。

BRDF(Bidirectional Reflectance Distribution Function - 双方向反射率分布関数) は物体表面上のある点xxにおける、光の入射方向ωi\vec{\omega_i}と反射方向ωo\vec{\omega_o}が与えられたときの反射率を表す関数ffで、次のように定義されます。

f(x,ωi,ωo)=dLo(x,ωo)dEi(x)=dLo(x,ωi)Li(x,ωi)cosθdσ(ωi)f(x, \vec{\omega_i}, \vec{\omega_o}) = \frac{dL_o(x, \vec{\omega_o})}{dE_i(x)} = \frac{dL_o(x, \vec{\omega_i})}{L_i(x, \vec{\omega_i})|\cos{\theta}|d\sigma(\vec{\omega_i})}

BRDFは入射してくる単位放射照度あたりの、反射される放射輝度の値を表しています。

このような定義になっているのは、実験結果からEi(x)Lo(x,ωo)E_i(x) \propto L_o(x, \vec{\omega_o})という関係が知られているためです。

光の入射と反射方向は通常物体表面より上側に限られるため、ωi,ωo\vec{\omega_i}, \vec{\omega_o}は半球面Ω={ωN(x)ω0,ωS2}\Omega = \{ \vec{\omega} | \vec{N(x)}\cdot \vec{\omega} \ge 0, \vec{\omega} \in \mathcal{S}^2\}に属しています。

BRDFがエネルギー保存の法則を満たすために

Ωf(x,ωi,ωo)cosθdσ(ωi)1\int_{\Omega} f(x, \vec{\omega_i}, \vec{\omega_o})|\cos{\theta}|d\sigma(\vec{\omega_i}) \le 1

となります。また、入射と反射の方向を入れ替えても同じなので

f(x,ωi,ωo)=f(x,ωo,ωi)f(x, \vec{\omega_i}, \vec{\omega_o}) = f(x, \vec{\omega_o}, \vec{\omega_i})

という関係があります。

ffを指定することで、様々な反射特性を表現することができます。

拡散反射のBRDF

拡散反射(Diffuse Reflection) では光がすべての方向に一様に反射します。

これはBRDFの値が一定であることを意味しており、拡散反射のBRDFは一定の反射率をρ\rhoとして

f(x,ωi,ωo)=ρπf(x, \vec{\omega_i}, \vec{\omega_o}) = \frac{\rho}{\pi}

と表されます。(π\piが出てくるのはエネルギー保存則を満たすため)

完全鏡面のBRDF

完全鏡面の場合、入射した光は必ず一意の反射方向に反射するので、デルタ関数δ(ωi,ωo)\delta(\vec{\omega_i}, \vec{\omega_o})を用いて

f(x,ωi,ωo)=ρδ(ωi,ωo)cosθf(x, \vec{\omega_i}, \vec{\omega_o}) = \rho\frac{\delta(\vec{\omega_i}, \vec{\omega_o})}{|\cos{\theta}|}

と表されます。

反射方程式

入射してくる放射輝度Li(x,ωi)L_i(x, \vec{\omega_i})とBRDFが与えられている時、反射する放射輝度Lo(x,ωo)L_o(x, \vec{\omega_o})の値を計算してみましょう。

BRDFの定義から

dLo(x,ωo)=f(x,ωi,ωo)Li(x,ωi)cosθdσ(ωi)dL_o(x, \vec{\omega_o}) = f(x, \vec{\omega_i}, \vec{\omega_o})L_i(x, \vec{\omega_i})|\cos{\theta}|d\sigma(\vec{\omega_i})

両辺を立体角測度に関して全領域(半球面Ω\Omega)で積分することで

Lo(x,ωo)=Ωf(x,ωi,ωo)Li(x,ωi)cosθdσ(ωi)L_o(x, \vec{\omega_o}) = \int_{\Omega} f(x, \vec{\omega_i}, \vec{\omega_o})L_i(x, \vec{\omega_i})|\cos{\theta}|d\sigma(\vec{\omega_i})

この方程式を 反射方程式(Reflection Equation) といいます。

レンダリング方程式

物体が点xxで発光し、方向ωo\vec{\omega_o}に放射している放射輝度の値をLe(x,ωo)L_e(x, \vec{\omega_o})で表すことにします。すると反射方程式と組み合わせることで、xxからωo\vec{\omega_o}に反射する放射輝度の値は

Lo(x,ωo)=Le(x,ωo)+Ωf(x,ωi,ωo)Li(x,ωi)cosθdσ(ωi)L_o(x, \vec{\omega_o}) = L_e(x, \vec{\omega_o}) + \int_{\Omega} f(x, \vec{\omega_i}, \vec{\omega_o})L_i(x, \vec{\omega_i})|\cos{\theta}|d\sigma(\vec{\omega_i})

として表されます。この方程式を レンダリング方程式(The Rendering Equation) といいます。(他にも光輸送方程式(LTE - Light Transport Equation)などの名前があります)

右辺第一項は発光を表しているので発光項、右辺第二項は反射を表しているので反射項と呼ばれます。

レンダリング方程式の重要性

レンダリング方程式は物理ベースレンダリングで最も重要な基礎方程式になっています。画像を生成するためにはカメラセンサー上の点xxに、ある方向ωi\vec{\omega_i}からやってくる放射輝度の値Li(x,ωi)L_i(x, \vec{\omega_i})を知る必要があるのですが、この値をレンダリング方程式を用いて計算することができます。

つまり、物理ベースレンダリングとはレンダリング方程式を計算することに帰着されます。世の中には物理ベースレンダリングを達成するための様々なアルゴリズムが存在しますが、それらは全てこのレンダリング方程式をいかにして計算するかということを工夫したものです。

レンダリング方程式の計算

この方程式を計算するためにはLeL_eの値、BRDFの値、そしてLiL_iを知っている必要があります。LeL_eとBRDFはシーンを作った時点で既知ですが、LiL_iは未知なので計算する必要があります。

Li(x,ωi)L_i(x, \vec{\omega_i})を計算するには再びレンダリング方程式を適用することができます。x=r(x,ωi)x' = r(x, \vec{\omega_i})とすると、Li(x,ωi)=Lo(x,ωi)L_i(x, \vec{\omega_i}) = L_o(x', -\vec{\omega_i})なので

Li(x,ωi)=Lo(x,ωi)=Le(x,ωi)+Ωf(x,ωi,ωi)Li(x,ωi)cosθdσ(ωi)L_i(x, \vec{\omega_i}) = L_o(x', -\vec{\omega_i}) = L_e(x', \vec{\omega_i'}) + \int_{\Omega} f(x', \vec{\omega_i'}, -\vec{\omega_i})L_i(x', \vec{\omega_i'})|\cos{\theta}|d\sigma(\vec{\omega_i'})

として、Li(x,ωi)L_i(x, \vec{\omega_i})が計算できます。

ここでLi(x,ωi)L_i(x', \vec{\omega_i'})の計算に再びレンダリング方程式を適用します。このように再帰的にレンダリング方程式を使うことで、Lo(x,ωo)L_o(x, \vec{\omega_o})を計算することができます。これを理論的にきれいな形としてまとめたのが次の内容です。

レンダリング方程式の作用素表現

レンダリング方程式は再帰的な方程式になっていますが、これを関数解析で出てくる線形作用素を使用することで、簡単な代数方程式として表現することができます。

ここでは放射輝度の関数空間L\mathcal{L}を考えます。この空間上で定義される線形写像F:LLF:\mathcal{L} \rightarrow \mathcal{L}線形作用素(Linear Operator) といいます。線形作用素は関数を別の関数に移す線形写像です。身近な例としては微分・積分が線形作用素の1つになっています。

局所散乱作用素

レンダリング方程式の再帰をきれいな形として書くために、次のような局所散乱作用素(Local Scattering Operator)SSを定義します。

Sh(x,ωo)=Ωf(x,ωi,ωo)h(x,ωi)cosθdσ(ωi)Sh(x, \vec{\omega_o}) = \int_{\Omega} f(x, \vec{\omega_i}, \vec{\omega_o})h(x, \vec{\omega_i})|\cos{\theta}|d\sigma(\vec{\omega_i})

局所散乱作用素SSを使用することで、ある点の入射放射輝度LiL_iが与えられているときに、その点で反射される放射輝度LoL_o

Lo=SLiL_o = SL_i

として表現できます。

進行作用素

さらに放射輝度の真空中の伝播を表すために、進行作用素GGを定義します。

Gh(x,ωi)=h(r(x,ωi),ωi)Gh(x, \vec{\omega_i}) = h(r(x, \vec{\omega_i}), -\vec{\omega_i})

進行作用素GGを利用することで、ある点から出射した放射輝度LoL_oが別の点に入射するとき、その点における入射放射輝度LiL_i

Li=GLoL_i = GL_o

として表現できます。

レンダリング方程式の作用素表現

局所散乱作用素SSと進行作用素GGを組み合わせることで、レンダリング方程式を

Lo=Le+SGLoL_o = L_e + SGL_o

として表現することができます。ここでさらにT=SGT = SGを光輸送作用素として定義すれば

Lo=Le+TLoL_o = L_e + TL_o

となります。これを レンダリング方程式の作用素表現 といいます。これは放射輝度の関数空間上で成り立つ代数的関係を表しています。

レンダリング方程式のノイマン級数展開

作用素表現のレンダリング方程式

Lo=Le+TLoL_o = L_e + TL_o

は単純な代数方程式になっています。この方程式は関数方程式ですが、関数のあらゆる引数に対してこの関係が成り立っているので、シーン中の放射輝度の均衡関係を表していると見ることができます。(光子が光源から発射されて反射を繰り返していくと、シーン中のあらゆる地点で光子の単位時間あたりの通過量が一定になる)

これを変形することでレンダリング方程式の解を明示的に表現することが可能です。

右辺のTLoTL_oを左辺に移行することで

LoTLo=Le(IT)Lo=Le\begin{aligned} L_o - TL_o &= L_e \\ (I - T)L_o &= L_e \end{aligned}

ここでIIは恒等作用素であり、Ih=hIh = hです。 (IT)(I - T)の逆作用素(IT)1(I - T)^{-1}を用いることで

Lo=(IT)1LeL_o = (I - T)^{-1} L_e

と書くことができます(逆作用素はBRDFがエネルギー保存の法則を満たすなら存在することが示されます)。右辺にはLeL_eしかないので、これがレンダリング方程式の明示的な解になっています。

(IT)1(I - T)^{-1}はノイマン級数展開することが可能で

(IT)1=I+T+T2+T3+(I - T)^{-1} = I + T + T^2 + T^3 + \cdots

と表されます。したがってレンダリング方程式は

Lo=Le+TLe+T2Le+T3Le+L_o = L_e + TL_e + T^2L_e + T^3L_e + \cdots

と表現されます。これは レンダリング方程式のノイマン級数展開 と呼ばれます。この形では、出射放射輝度を求めるためには、シーン中の発光放射輝度を0回、1回、2回、\cdots, \infty回反射させたものを足し合わせれば良いということを言っています。

カメラのモデル化

光の伝達はレンダリング方程式としてモデル化することができました。次にカメラをモデル化することを考えてみます。

カメラはセンサー上に大量の画素を持ち、画素1つ1つが入射してくる光子の数を記録することによって光の強さを記録しています。これはつまり、非常に短い時間では放射束を記録しているということです。

カメラは入射してくる光をセンサー上に結像させるためにレンズを前面に持っています。レンズは一般的に複数枚の凹凸レンズを組み合わせて構成されます。

カメラからレイを出射することを考えます。物理的にはセンサーからレイが出発して、多くのレンズで屈折を繰り返してからシーンに出ていくようにモデル化した方が良いですが、ここでは話をシンプルにするために、途中の屈折過程はブラックボックス化し、レンズ最前面からいきなりレイが出射すると考えます。(画素の範囲外に出るレイを除けば画素上から出るレイと1対1対応する)

jj番目の画素が記録する光の強さIjI_jを考えます。レンズ最前面上の点をxDx \in D、ここから出るレイの方向をω\vec{\omega}とします。このレイに対応する画素のセンサー感度をWe(j)(x,ω)W_e^{(j)}(x, \vec{\omega})(これはMeasure Contribution Functionと呼ばれる)、レンズ最前面にレイの方向から入射してくる放射輝度をLi(x,ω)L_i(x, \vec{\omega})とします。するとθ\thetaxxにおける法線ベクトルとω\vec{\omega}のなす角として

Ij=DS2We(x,ω)Li(x,ω)cosθdσ(ω)dA(x)I_j = \int_D \int_{\mathcal{S^2}} W_e(x, \vec{\omega})L_i(x, \vec{\omega})|\cos{\theta}|d\sigma(\vec{\omega})dA(x)

となります。

WeW_eの関数形を変えることで、様々なカメラを表現することが可能です。

ピンホールカメラ

ピンホールカメラの場合、ピンホールの位置をxpx_pとして、D={xp}D = \{x_p\}です。また画素jjに対応してレイの出射方向が一意に定まるため、WeW_eはデルタ関数で表現されることになります。したがってIjI_jを計算する式は積分をはずせて

Ij=We(x,ω)Li(x,ω)cosθI_j = W_e(x, \vec{\omega})L_i(x, \vec{\omega})|\cos{\theta}|

のように簡略化されます。

経路積分形式のレンダリング方程式

レンダリング方程式は方向に関する積分方程式として表されていましたが、これを光の経路(x0,x1,,xk)(x_0, x_1, \cdots, x_k)に関する積分として表現することも可能です。ここではそのような表現について見ていきます。

ある点xxから別の点xx'に向かう方向ベクトルをxxx \rightarrow x'として表すことにします。

立体角測度と面積測度の関係

物体表面上の点xx'における微小単位面積dAdAを点xxに置かれた単位球面上に投影することを考えます。すると

dσ(ω)=V(x,x)cosθxx2dA(x)d\sigma(\vec{\omega}) = V(x, x')\frac{|\cos{\theta'}|}{||x' - x||^2}dA(x')

という関係があることが分かります。ここでcosθ=N(x)(xx)\cos{\theta'} = \vec{N(x')}\cdot (x' \rightarrow x)です。V(x,x)V(x, x')可視関数(Visible Function) と呼ばれ、xxxx'がお互いに見えるときに1、それ以外のときに0をとる関数です。

この関係式を用いて立体角測度と面積測度に関する積分を互いに積分変数変換することが可能になります。

3点形式のレンダリング方程式

ある点x1x_1からレンズ上の点x0x_0に出射する放射輝度Lo(x1x0)L_o(x_1 \rightarrow x_0)を考えます。レンダリング方程式を立体角測度に関する積分から面積測度に関する積分に積分変数変換することによって、

Lo(x1x0)=Le(x1x0)+Mf(x0x1x2)Li(x1x2)V(x1,x2)G(x1,x2)dA(x2)L_o(x_1 \rightarrow x_0) = L_e(x_1 \rightarrow x_0) + \int_{\mathcal{M}}f(x_0 \rightarrow x_1 \rightarrow x_2)L_i(x_1 \rightarrow x_2)V(x_1, x_2)G(x_1, x_2) dA(x_2)

と書くことができます。

G(x1,x2)G(x_1, x_2)幾何項(Geometry Term) と呼ばれ、積分変換変換による項とcosθ|\cos{\theta}|をかけたもので

G(x1,x2)=cosθcosθx2x12G(x_1, x_2) = \frac{|\cos{\theta}||\cos{\theta'}|}{||x_2 - x_1||^2}

と表されます。 このように視点x0x_0, 注目点x1x_1, 反射方向の点x2x_2を用いた形のレンダリング方程式を 3点形式のレンダリング方程式 といいます。

経路積分形式のレンダリング方程式

3点形式のレンダリング方程式をノイマン級数展開することで、次のような経路積分形式のレンダリング方程式が得られます。

Lo(x1x0)=Le(x1x0)+Mf(x0x1x2)V(x1,x2)G(x1,x2)Le(x2x1)dA(x2)+MMf(x0x1x2)f(x1x2x3)V(x1,x2)V(x2,x3)G(x1,x2)G(x2,x3)Le(x3x2)dA(x2)dA(x3)+\begin{aligned} L_o(x_1 \rightarrow x_0) &= L_e(x_1 \rightarrow x_0) \\ &+ \int_{\mathcal{M}}f(x_0 \rightarrow x_1 \rightarrow x_2)V(x_1, x_2)G(x_1, x_2)L_e(x_2 \rightarrow x_1) dA(x_2) \\ &+ \int_{\mathcal{M}}\int_{\mathcal{M}} f(x_0 \rightarrow x_1 \rightarrow x_2)f(x_1 \rightarrow x_2 \rightarrow x_3)V(x_1, x_2)V(x_2, x_3)G(x_1, x_2)G(x_2, x_3)L_e(x_3 \rightarrow x_2)dA(x_2)dA(x_3) \\ &+ \cdots \end{aligned}

カメラモデルの導入

カメラモデルの式

Ij=DS2We(x0,ω)Li(x0,ω)cosθdσ(ω)dA(x0)I_j = \int_D \int_{\mathcal{S^2}} W_e(x_0, \vec{\omega})L_i(x_0, \vec{\omega})|\cos{\theta}|d\sigma(\vec{\omega})dA(x_0)

を経路積分形式のレンダリング方程式に組み込むことを考えます。立体角測度による積分を面積測度による積分に変換することで

Ij=DS2We(x0,ω)Li(x0,ω)cosθdσ(ω)dA(x0)=MDWe(x0x1)V(x0,x1)G(x0,x1)Li(x0x1)dA(x0)dA(x1)=MMWe(x0x1)V(x0,x1)G(x0,x1)Li(x0x1)dA(x0)dA(x1)\begin{aligned} I_j &= \int_D \int_{\mathcal{S^2}} W_e(x_0, \vec{\omega})L_i(x_0, \vec{\omega})|\cos{\theta}|d\sigma(\vec{\omega})dA(x_0) \\ &= \int_{\mathcal{M}} \int_{D} W_e(x_0 \rightarrow x_1)V(x_0, x_1)G(x_0, x_1)L_i(x_0 \rightarrow x_1)dA(x_0)dA(x_1) \\ &= \int_{\mathcal{M}} \int_{M} W_e(x_0 \rightarrow x_1)V(x_0, x_1)G(x_0, x_1)L_i(x_0 \rightarrow x_1)dA(x_0)dA(x_1) \end{aligned}

となります。(DDM\mathcal{M}に変えていることに注意。このようにしてもWeW_eDD以外の点で0にすることで値は変化しない)

Li(x0x1)=Lo(x1x0)L_i(x_0 \rightarrow x_1) = L_o(x_1 \rightarrow x_0)なので、経路積分形式のレンダリング方程式を代入することで

Ij=k=1MMk+1We(x0x1)i=1k{f(xi2xi1xi)V(xi1,xi)G(xi1,xi)}Le(xkxk1)dA(x0)dA(x1)dA(xk)I_j = \sum_{k=1}^{\infty}\underbrace{\int_{\mathcal{M}} \cdots \int_{\mathcal{M}}}_{k+1} W_e(x_0 \rightarrow x_1)\prod_{i=1}^{k}\{ f(x_{i-2} \rightarrow x_{i-1} \rightarrow x_i)V(x_{i-1}, x_i)G(x_{i-1}, x_i) \}L_e(x_k \rightarrow x_{k-1})dA(x_0)dA(x_1)\cdots dA(x_k)

のように書けます。ここでf(x1x0x1)=1f(x_{-1} \rightarrow x_0 \rightarrow x_1) = 1としています。

xkˉ=(x0,x1,,xk)\bar{x_k} = (x_0, x_1, \cdots, x_k)とおきます。これを長さk+1k+1の光の 経路(Path) と呼びます。

Tk(xkˉ)=i=1k{f(xi2xi1xi)V(xi1,xi)G(xi1,xi)}T_k(\bar{x_k}) = \prod_{i=1}^{k}\{ f(x_{i-2} \rightarrow x_{i-1} \rightarrow x_i)V(x_{i-1}, x_i)G(x_{i-1}, x_i) \}スループット(Throughput) として定義すると

Ij=k=1MMk+1We(x0x1)Tk(xkˉ)Le(xkxk1)dA(x0)dA(x1)dA(xk)I_j = \sum_{k=1}^{\infty}\underbrace{\int_{\mathcal{M}} \cdots \int_{\mathcal{M}}}_{k+1} W_e(x_0 \rightarrow x_1)T_k(\bar{x_k})L_e(x_k \rightarrow x_{k-1})dA(x_0)dA(x_1)\cdots dA(x_k)

のようになります。これが 経路積分形式(Path Integral Form) と呼ばれるレンダリング方程式の形です。

レンダリング方程式の計算について

再帰的な形のレンダリング方程式を経路積分形式で表現することで、レンダリング方程式はnn次積分の無限級数になっていることが分かりました。数値積分を利用すればこれは数値計算が可能な形になっています。

しかし、10回の反射を経た光は10次元の積分、100回の反射を経た光は100次元の積分、\cdotsというように、高次元の積分を数値的に計算する必要があります。

高次元の積分は通常の数値積分の手法だと計算量が爆発的に多くなります。例えばそれぞれの軸を10個のサンプル点に分割する場合、100次元積分を計算しようとすると1010010^{100}のサンプル点を生成することになります。これは現代のコンピューターを持ってしても計算が不可能な値です。

これを解決するための手法として、確率論的に積分の値を求める モンテカルロ積分(Montecarlo Integration) というものがあります。レイトレではモンテカルロ積分を用いてレンダリング方程式を解くことが一般的です。