物理ベースレンダリング入門1(第5回)
物理ベースレンダリングの理論的な部分について

このページでは物理ベースレンダリングの理論的な部分について解説を行う。

光の性質を記述する方法

光の性質を記述する方法は大きく分けて2つある。

  • 幾何光学(Geometry Optics)

幾何光学
幾何光学
光が直線であると仮定して光の性質を記述する。

  • 波動光学(Wave Optics)

波動光学
波動光学
光が波であると仮定して光の性質を記述する。干渉と回折を表現することができる。

物理ベースレンダリングにおいては幾何光学による光の表現を主に利用する。

光の物理量

光子のエネルギー

振動数ν\nuの光子一つが持つエネルギーeνe_{\nu}は以下の式で表される。

eν=hνe_{\nu} = h\nu

hhはプランク定数である。 ν=cλ\nu = \frac{c}{\lambda}の関係から、波長λ\lambdaの光子一つが持つエネルギーeλe_{\lambda}は以下の式で表される。

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

光のエネルギー

波長λ\lambdaの光子がnn個あるとき、スペクトル放射エネルギーQλQ_{\lambda}は以下の式で表される。

Qλ=neλ=nhcλQ_{\lambda} = n e_{\lambda} = n \frac{hc}{\lambda}

放射エネルギーQ[J]Q[J]は全波長にわたってスペクトル放射エネルギーを積分することで得られる。

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

放射束(Radiant Flux)

放射束Φ[W]\Phi[W]は単位時間あたりの放射エネルギーである。

Φ=dQdt\Phi = \frac{dQ}{dt}
放射束
放射束

イメージ的にはある領域を単位時間あたりに通過する光子の量と考えられる。物理ベースレンダリングでは放射束が光の基本的な物理量となる。 波長について考慮する場合はスペクトル放射束Φλ\Phi_{\lambda}を使用する。

Φλ=dQλdt\Phi_{\lambda} = \frac{dQ_{\lambda}}{dt}

放射束面密度

放射束面密度[W⋅m−2][W\cdot m^{-2}]は単位面積dAdAあたりの放射束である。

dΦdA\frac{d\Phi}{dA}
放射束面密度
放射束面密度

単位面積を単位時間に通過する光子の数と考えることができる。つまり、ある点を単位時間に通過する光子の数である。 入射してくる光に対する放射束面密度は放射照度(Irradiance)EEといい、出射する光に対する放射束面密度は放射発散度(Radient Exitance)MMという。ただ入射と出射で名前が変わっただけで中身は同じ。

例

半径rrの球が放射束aaで光っているとする。すると球面上の放射束面密度は次の式で表される。

a4πr2\frac{a}{4\pi r^2}

立体角(Solid Angle)

立体角は光線の方向と角度的な大きさを表現する概念であり、以下のように定義される。

点OOを中心とした半径1の単位球面に面SSを投影したときの面積がΩ\Omegaならば、点OOに対する面SSの立体角をΩ\Omegaとする

立体角
立体角

単位球面上で面積が1になるような角度が単位立体角である。立体角の単位はステラジアン[sr][sr]。

放射強度(Radient Intensity)

放射強度I[W⋅sr−1]I[W\cdot sr^{-1}]は単位立体角dω⃗d\vec{\omega}あたりの放射束である。

I=dΦdω⃗I = \frac{d\Phi}{d\vec{\omega}}
放射強度
放射強度

放射強度はある領域において、ある方向から単位時間あたりに来る光子の数を表している。

放射輝度(Radiance)

放射輝度L[W⋅m−2⋅sr−1]L[W\cdot m^{-2}\cdot sr^{-1}]は単位立体角あたりの単位面積あたりの放射束である。物理ベースレンダリングにおいて最も重要な物理量。

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

放射輝度
放射輝度
θ\thetaは微小領域dAdAの法線とω⃗\vec{\omega}のなす角度である。cos⁡θdA\cos{\theta}dAはdAdAをω⃗\vec{\omega}の方向に投影した面積である。

放射輝度は方向ω⃗\vec{\omega}から微小領域dAdAに単位時間あたりに来る光子の数と考えることができる。

放射輝度は空間中のある一点において、ある方向から来る光の強さを表している。物理ベースレンダリングにおいて最も重要な物理量である。

真空中においては光が進行しても放射輝度の値は変化しない。

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

ある物体表面の位置をxxとし、方向dω⃗d\vec{\omega}から来る放射輝度をL(x,ω⃗)L(x, \vec{\omega})で表す。あらゆる方向から来る放射輝度の値が事前に分かっている場合、xxにおける放射束面密度は

dΦdA=∫ΩL(x,ω⃗)(ω⃗⋅n⃗)dω⃗\frac{d\Phi}{dA} = \int_{\Omega}L(x, \vec{\omega})(\vec{\omega}\cdot\vec{n})d\vec{\omega}

と計算できる。

放射輝度から放射束面密度を計算
放射輝度から放射束面密度を計算
ここでn⃗\vec{n}はxxにおける物体表面の法線方向、Ω\Omegaはすべての方向(つまり全球)を表す。

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

ある領域AAの放射束は以下の式で計算できる。

Φ=∫A∫ΩL(x,ω⃗)(ω⃗⋅n⃗)dω⃗dA\Phi = \int_{A}\int_{\Omega}L(x, \vec{\omega})(\vec{\omega}\cdot\vec{n})d\vec{\omega}dA

立体角と球面座標

球面座標(θ,ϕ)(\theta, \phi)を用いて単位立体角を表すことができる。(ヤコビアンを計算すると求まる)

dω⃗=sin⁡θdθdϕd\vec{\omega} = \sin{\theta}d\theta d\phi

これを用いると、半球方向全体Ω\Omegaにおける、ある関数ffの立体角による積分は、球面座標を用いて次のように書き直せる。

∫Ωf(ω⃗)dω⃗=∫02π∫0π2f(θ,ϕ)sin⁡θdθdϕ\int_{\Omega} f(\vec{\omega})d\vec{\omega} = \int_0^{2\pi}\int_0^{\frac{\pi}{2}}f(\theta, \phi)\sin{\theta}d\theta d\phi

半球全体での立体角による積分は物理ベースレンダリングにおいて頻出であり、この変換は特に重要。

双方向反射率分布関数(BRDF)

光は物体表面に到達すると一部が吸収され、残りは反射される。点xxに方向ωi⃗\vec{\omega_i}から入射した光が、方向ωr⃗\vec{\omega_r}にどれだけ反射されるかを表す関数として双方向反射率分布関数(BRDF)f(x,ωi⃗,ωr⃗)f(x, \vec{\omega_i}, \vec{\omega_r})がある。

f(x,ωi⃗,ωr⃗)=dLr(x,ωr⃗)dEi(x,ωi)=dLr(x,ωr⃗)Li(x,ωi⃗)(ωi⃗⋅n⃗)dωi⃗f(x, \vec{\omega_i}, \vec{\omega_r}) = \frac{dL_r(x, \vec{\omega_r})}{dE_i(x, \omega_i)} = \frac{dL_r(x, \vec{\omega_r})}{L_i(x, \vec{\omega_i})(\vec{\omega_i}\cdot \vec{n})d\vec{\omega_i}}
BRDF
BRDF

BRDFには次の重要な性質がある。

f(x,ωi⃗,ωr⃗)=f(x,ωr⃗,ωi⃗)f(x, \vec{\omega_i}, \vec{\omega_r}) = f(x, \vec{\omega_r}, \vec{\omega_i})

入射方向と反射方向を入れ替えてもBRDFの値は変化しない。これは ヘルツホルムの相反性の法則 と呼ばれる。

また、受け取った以上の光を返すことはありえないので

∫Ωf(x,ωi⃗,ωr⃗)(ωi⃗⋅n⃗)dωi⃗≤1\int_{\Omega} f(x, \vec{\omega_i}, \vec{\omega_r})(\vec{\omega_i}\cdot\vec{n})d\vec{\omega_i} \le 1

が成り立つ。

BRDFを使うと半球全体Ω\Omegaからある点xxに来た光が、方向ωr⃗\vec{\omega_r}に反射される放射輝度の値Lr(x,ωr⃗)L_r(x, \vec{\omega_r})は以下の式で表せる。 Lr(x,ωr⃗)=∫Ωf(x,ωi⃗,ωr⃗)Li(x,ωi⃗)(ωi⃗⋅n⃗)dωi⃗L_r(x, \vec{\omega_r}) = \int_{\Omega}f(x, \vec{\omega_i}, \vec{\omega_r})L_i(x, \vec{\omega_i})(\vec{\omega_i}\cdot \vec{n})d\vec{\omega_i}

反射する放射輝度の計算
反射する放射輝度の計算

ここでLi(x,ωi⃗)L_i(x, \vec{\omega_i})は方向ωi⃗\vec{\omega_i}から入射する放射輝度、n⃗\vec{n}は点xxにおける物体表面の法線を表す。

レンダリング方程式

物体表面のある点xxから方向ωr⃗\vec{\omega_r}へ向かう放射輝度Lo(x,ωr⃗)L_o(x, \vec{\omega_r})は以下の式で表せる。

Lo(x,ωr⃗)=Le(x,ωr⃗)+Lr(x,ωr⃗)=Le(x,ωr⃗)+∫Ωf(x,ωi⃗,ωr⃗)Li(x,ωi⃗)(ωi⃗⋅n⃗)dωi⃗\begin{aligned}L_o(x, \vec{\omega_r}) &= L_e(x, \vec{\omega_r}) + L_r(x, \vec{\omega_r}) \\ &= L_e(x, \vec{\omega_r}) + \int_{\Omega}f(x, \vec{\omega_i}, \vec{\omega_r})L_i(x, \vec{\omega_i})(\vec{\omega_i}\cdot \vec{n})d\vec{\omega_i} \end{aligned}
レンダリング方程式
レンダリング方程式

Le(x,ωr⃗)L_e(x, \vec{\omega_r})は点xxにおいて物体が発光し、ωr⃗\vec{\omega_r}の方向へ出射される放射輝度の値を表している。Lr(x,ωr⃗)L_r(x, \vec{\omega_r})はxxからωr⃗\vec{\omega_r}に反射される放射輝度の量である。この式は物理ベースレンダリングにおいて最も重要な式であり、レンダリング方程式(Light Transport Equation) という。

画素に入る放射輝度
画素に入る放射輝度

たとえばカメラに方向ωr⃗\vec{\omega_r}から入射する放射輝度の値はLo(x,ωr⃗)L_o(x, \vec{\omega_r})である。したがって、物理ベースレンダリングにおいてはレンダリング方程式を解くことが主眼となる。

レンダリング方程式は再帰的に計算することができる。Li(x,ωi⃗)L_i(x, \vec{\omega_i})の部分は他のある点x′x'からωi⃗\vec{\omega_i}の方向に飛んできた光と考えることができる。したがって

Lo(x,ωr⃗)=Le(x,ωr⃗)+∫Ωf(x,ωi⃗,ωr⃗){Le(x′,ωi⃗)+∫Ωf(x′,ωi′⃗,ωi⃗)Li(x′,ωi⃗)(ωi′⃗⋅n′⃗)dωi′⃗}(ωi⃗⋅n⃗)dωi⃗L_o(x, \vec{\omega_r}) = L_e(x, \vec{\omega_r}) + \int_{\Omega} f(x, \vec{\omega_i}, \vec{\omega_r})\{L_e(x', \vec{\omega_i}) + \int_{\Omega}f(x', \vec{\omega_i'}, \vec{\omega_i})L_i(x', \vec{\omega_i})(\vec{\omega_i'}\cdot\vec{n'})d\vec{\omega_i'}\}(\vec{\omega_i}\cdot\vec{n})d\vec{\omega_i}

となる。

レンダリング方程式の展開
レンダリング方程式の展開

さらにLi(x′,ωi′⃗)L_i(x', \vec{\omega_i'})の部分を無限に展開していくことができる。

上の式は非常に複雑である。式を簡単にするために積分オペレーターTTを導入する。

<Tg>(x,ωr⃗)=∫Ωf(x,ωi⃗,ωr⃗)g(x,ωi⃗)(ωi⃗⋅n⃗)dωi⃗<T g>(x, \vec{\omega_r}) = \int_{\Omega}f(x, \vec{\omega_i}, \vec{\omega_r})g(x, \vec{\omega_i})(\vec{\omega_i}\cdot \vec{n})d\vec{\omega_i}

これを使うとレンダリング方程式は以下のように書ける。

L=Le+TLL = L_e + TL

LLはLo(x,ωr⃗)L_o(x, \vec{\omega_r})を、LeL_eはLe(x,ωr⃗)L_e(x, \vec{\omega_r})を表している。これを再帰的に展開することにより、

L=Le+T(Le+T(Le+…L = L_e + T(L_e + T(L_e + \dots
L=Le+TLe+T2Le+T3Le+⋯=∑k=0∞TkLeL = L_e + TL_e + T^2L_e + T^3L_e + \dots = \sum_{k = 0}^{\infty}T^kL_e

このように表現することができる。この形をノイマン級数展開という。TLeTL_eは一回の反射を経た光、T2LeT^2L_eは二回の反射を経た光を表している。

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

上のレンダリング方程式では立体角に関する積分によって反射される放射輝度を表現していた。これを物体表面上の点x′x'に関する積分に置き換えることができる。 xxからωi⃗\vec{\omega_i}の方向にx′x'があるとする。すると単位立体角dωi⃗d\vec{\omega_i}の面積はx′x'において

∥x′−x∥2dωi⃗\|x' - x\|^2d\vec{\omega_i}

となっている。

x′x'における物体の法線をn′⃗\vec{n'}とすると、この面積を物体表面AAに投影することでdAdAとdωi⃗d\vec{\omega_i}の間には

dA=∥x′−x∥2(ωi⃗⋅n′⃗)dωi⃗dA = \frac{\|x' - x\|^2}{(\vec{\omega_i}\cdot\vec{n'})}d\vec{\omega_i}

の関係がある。

物体表面に関する積分
物体表面に関する積分

これより

dωi⃗=(ωi⃗⋅n′⃗)∥x′−x∥2dAd\vec{\omega_i} = \frac{(\vec{\omega_i}\cdot\vec{n'})}{\|x' - x\|^2}dA

を得る。この変換も頻出なのでよく覚えておいてほしい。これを立体角積分のレンダリング方程式に代入することで以下の式を得る。

Lo(x,ωr⃗)=Le(x,ωr⃗)+∫Af(x,x′→x,ωr⃗)Li(x′→x)V(x,x′)((x→x′)⋅n⃗)((x′→x)⋅n′⃗)∥x′−x∥2dAL_o(x, \vec{\omega_r}) = L_e(x, \vec{\omega_r}) + \int_Af(x, x'\rightarrow x, \vec{\omega_r})L_i(x'\rightarrow x)V(x, x')\frac{((x \rightarrow x')\cdot\vec{n})((x' \rightarrow x)\cdot\vec{n'})}{\|x' - x\|^2}dA

x→x′x\rightarrow x'はxxからx′x'に向かう方向を表す。AAは物体表面全体を表す。V(x,x′)V(x, x')は可視関数といい

V(x,x′)={1(x′がxから見える)0(otherwise)V(x, x') = \begin{cases} 1&(x'\text{が}x\text{から見える})\\0&(otherwise) \end{cases}

のように定義される。式が煩雑なので幾何項G(x,x′)G(x, x')を定義する。

G(x,x′)=((x→x′)⋅n⃗)((x′→x)⋅n′⃗)∥x′−x∥2G(x, x') = \frac{((x \rightarrow x')\cdot\vec{n})((x'\rightarrow x)\cdot\vec{n'})}{\|x' - x\|^2}

すると2点形式のレンダリング方程式は以下のように書ける。 Lo(x,ωr⃗)=Le(x,ωr⃗)+∫Af(x,x→x′,ωr⃗)Li(x′→x)V(x,x′)G(x,x′)dAL_o(x, \vec{\omega_r}) = L_e(x, \vec{\omega_r}) + \int_Af(x, x\rightarrow x', \vec{\omega_r})L_i(x'\rightarrow x)V(x, x')G(x, x')dA

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

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

3点x,x′,x′′x, x', x''を使用し、単純に2点形式のレンダリング方程式においてωr⃗\vec{\omega_r}を置き換えることで以下の3点形式のレンダリング方程式を得る。

Lo(x′→x)=Le(x′→x)+∫Af(x′′→x′→x)Li(x′′→x)V(x′,x′′)G(x′,x′′)dAL_o(x'\rightarrow x) = L_e(x'\rightarrow x)+\int_A f(x''\rightarrow x' \rightarrow x)L_i(x''\rightarrow x)V(x', x'')G(x', x'')dA
3点形式のレンダリング方程式
3点形式のレンダリング方程式

xxは視点、x′x'は注目している点、x′′x''は物体表面AA上の点である。

経路積分によるレンダリング方程式の表現

ノイマン級数展開されたレンダリング方程式から、kk回反射された光の経路を考え、すべてのkkに対する和としてレンダリング方程式を表現することができる。

Lo(x0→x−1)=∑k=0∞∫A∫A…⏞k+1∫AK(xk,xk−1,xk−2)…K(x1,x0,x−1)Le(xk→xk−1)dAkdAk−1…dA0L_o(x_0\rightarrow x_{-1}) = \sum_{k=0}^{\infty}\int_A\int_A\overbrace{\dots}^{k+1}\int_AK(x_k, x_{k-1}, x_{k-2})\dots K(x_1, x_0, x_{-1})L_e(x_k\rightarrow x_{k-1})dA_kdA_{k-1}\dots dA_0

ここで、K(x′′,x′,x)=f(x′′→x′→x)V(x′,x′′)G(x′,x′′)K(x'', x', x) = f(x''\rightarrow x' \rightarrow x)V(x', x'')G(x', x'')である。x−1x_{-1}は視点を表している。この表現ではレンダリング方程式は積分の無限級数となっている。

拡散反射のBRDF

拡散反射は全ての方向に一様に光を反射する。反射率をρ\rhoとすると拡散反射のBRDFは定数ccを用いて

f=cρf = c\rho

と表せる。半球で積分するとρ\rhoになるはずだから

cρ∫Ω(ωi⃗⋅n⃗)dωi⃗=ρc∫02π∫0π2cos⁡θsin⁡θdθdϕ=1cπ=1c=1πc\rho\int_{\Omega} (\vec{\omega_i}\cdot\vec{n}) d\vec{\omega_i} = \rho \\ c\int_0^{2\pi}\int_0^{\frac{\pi}{2}}\cos{\theta}\sin{\theta}d\theta d\phi = 1\\ c\pi = 1\\ c = \frac{1}{\pi}

したがって拡散反射のBRDFは

f=ρπf = \frac{\rho}{\pi}

となる。

練習問題

問1

点x⃗\vec{x}に法線n⃗\vec{n}で存在する半径rrの円を、原点にある単位球面上に投影した面積Ω\Omegaを求めよ。(つまり立体角を求める)

問2

∫Ωdω⃗=2π\int_{\Omega} d\vec{\omega} = 2\piを示せ。

問3

Li(x,ωi⃗)=1L_i(x, \vec{\omega_i}) = 1と与えられているとき(つまり空が真っ白)、xxにおける放射側面密度dΦdA\frac{d\Phi}{dA}を求めよ。

問4

問3の設定で、BRDFがf(x,ωi⃗,ωo⃗)=ρπf(x, \vec{\omega_i}, \vec{\omega_o}) = \frac{\rho}{\pi}と与えられているとき、点xxから方向ωo⃗\vec{\omega_o}に反射される放射輝度Lr(x,ωo⃗)L_r(x, \vec{\omega_o})を求めよ。

問5

鏡面反射のBRDFを求めよ。