物理ベースマテリアルについて
2022/12/25
#3dcg #raytracing #pbr
物理ベースレンダリングにおいて様々な質感の物体を表現する数学的モデルについて

この記事はレイトレアドベントカレンダー 2022 25日目の記事です. この記事では物理ベースレンダリングにおいて, マテリアルがどのような数学的モデルで表現されているのかについて解説しています. 代表的なBSDFについて説明した後, Arnold Standard Surfaceという物理ベースマテリアルモデルを例に, レンダラーでマテリアルがどのように表現されているのかについて見ていきます.

物理ベースレンダリングにおけるマテリアルの表現

物理ベースレンダリングにおいては, 以下の レンダリング方程式 を数値計算することで写実的なレンダリング結果を得ることが出来ます.

Lo(x,ωo)=Le(x,ωo)+Ωf(x,ωi,ωo)Li(x,ωi)cosθidσ(ωi)(1)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_i}|d\sigma(\vec{\omega_i}) \tag{1}
  • Lo(x,ωo)L_o(x, \vec{\omega_o}): 点xxから方向ωo\vec{\omega_o}に出ていく放射輝度
  • Le(x,ωo)L_e(x, \vec{\omega_o}): 点xxが発光して方向ωo\vec{\omega_o}に出ていく放射輝度
  • f(x,ωi,ωo)f(x, \vec{\omega_i}, \vec{\omega_o}): 点xxにおけるBSDF
  • Li(x,ωi)L_i(x, \vec{\omega_i}): 点xxに方向ωi\vec{\omega_i}から入射する放射輝度

この式において, 物体の質感は双方向散乱分布関数(BSDF) f(x,ωo,ωi)f(x, \vec{\omega_o}, \vec{\omega_i})で表現されます. BSDFとは大雑把に言うと, 点xxにおいて特定の入射, 出射方向のペア(ωi,ωo)(\vec{\omega_i}, \vec{\omega_o})について反射, 屈折(透過)がどれくらいの強度で起こるのかを記述している関数です. BSDFの形状を変化させることで様々な質感の物体を表現することが出来ます.

BSDFの具体例

式(1)を実際に計算する上では, BSDFを計算可能な数式で表現する必要があります. ここでは物理ベースレンダリングにおいて代表的な3つのBSDFについて見ていきます.

Lambert BRDF

Lambert BRDF は以下のような定数関数のBRDFです.

f(x,ωi,ωo)=ρπ(2)f(x, \vec{\omega_i}, \vec{\omega_o}) = \frac{\rho}{\pi} \tag{2}
  • ρ\rho: 反射率(アルベド)

定数関数なのでどの入射, 出射方向のペア(ωi,ωo)(\vec{\omega_i}, \vec{\omega_o})についても反射が同じ強さで起こるようなモデルになっています.

このような反射の仕方は 拡散反射(Diffuse reflection) と呼ばれます. マットな質感の物体は拡散反射に近い反射の仕方をしているため, そのような質感を表現するのにLambert BRDFがよく使われます.

Microfacet BRDF

Microfacet BRDF は以下の図のように, 物体表面がMicrofacetと呼ばれる微小な面の集まりで構成され, 各微小面で光が鏡面反射するというモデルです.

Microsurface上で鏡面反射する
Microsurface上で鏡面反射する
(図はUnderstanding the Masking-Shadowing Function in Microfacet-Based BRDFsより)

このモデルは様々な粗さの光沢反射, 金属反射などを表現するのに使われます.

Microfacet BRDFは具体的には以下のように記述されます.

f(x,ωi,ωo)=F(ωo,ωh)G2(ωi,ωo)D(ωh)4cosθicosθo(3)f(x, \vec{\omega_i}, \vec{\omega_o}) = \frac{F(\vec{\omega_o}, \vec{\omega_h})G_2(\vec{\omega_i}, \vec{\omega_o})D(\vec{\omega_h})}{4\cos{\theta_i}\cos{\theta_o}} \tag{3}
  • ωh=normalize(ωo+ωi)\vec{\omega_h} = \mathrm{normalize}(\vec{\omega_o} + \vec{\omega_i}): ハーフベクトル
  • F(ωo,ωh)F(\vec{\omega_o}, \vec{\omega_h}): フレネル反射率
  • G2(ωi,ωo)G_2(\vec{\omega_i}, \vec{\omega_o}): Shadowing-Masking function
  • D(ωh)D(\vec{\omega_h}): 法線分布関数

フレネル反射率(Fresnel reflectance)は物体表面で光がどれくらい反射されるかの割合を表しています. フレネル反射率は一般的に物体を真上から見ると低い値になり, 真横から見ると1に近づきます. 水面を真上から見ると水の中がよく見えるのに, 真横から見ると反射でよく見えないのはフレネル反射率が変化するためです.

フレネル反射率は物体が誘電体(Dielectric)導電体(Conductor)の場合で異なる式になります. 誘電体は大雑把に言うと電気を通しにくい物体(水, ガラス, プラスチック), 導電体は電気を通しやすい物体(金属)などです. フレネル反射率が誘電体と導電体で異なるのは, 物体中の自由電子の有無に起因しています.

誘電体フレネル

誘電体の場合のフレネル反射率は以下の式で与えられます.

rs=nicosθintcosθtnicosθi+ntcosθtrp=ntcosθinicosθtntcosθi+nicosθtF(ωo,ωh)=rs2+rp22(4)\begin{aligned} r_s &= \frac{n_i\cos{\theta_i} - n_t\cos{\theta_t}}{n_i\cos{\theta_i} + n_t\cos{\theta_t}} \\ r_p &= \frac{n_t\cos{\theta_i} - n_i\cos{\theta_t}}{n_t\cos{\theta_i} + n_i\cos{\theta_t}} \\ F(\vec{\omega_o}, \vec{\omega_h}) &= \frac{r_s^2 + r_p^2}{2} \tag{4} \end{aligned}
  • θi\theta_i: ωo\vec{\omega_o}とハーフベクトルωh\vec{\omega_h}のなす角(入射角)
  • θt\theta_t: 屈折方向ωt\vec{\omega_t}とハーフベクトルωh\vec{\omega_h}のなす角
  • nin_i: 入射側媒質の屈折率
  • ntn_t: 透過側媒質の屈折率

cosθt\cos{\theta_t}はスネルの法則から以下のように計算出来ます.

cosθt=1(nint)2(1cos2θi)\cos{\theta_t} = \sqrt{1 - \bigg(\frac{n_i}{n_t}\bigg)^2(1 - \cos^2{\theta_i})}

rs2r_s^2rp2r_p^2はそれぞれS, P偏光の反射率に対応します. ここでは偏光がないと仮定して, フレネル反射率をそれらの平均で計算しています.

この式は計算コストが高いので, 以下のような Schlickの近似式 で代わりに計算されることも多いです.

F(ωo,ωh)=F0+(1F0)(1cosθi)5F0=(nintni+nt)2\begin{aligned} F(\vec{\omega_o}, \vec{\omega_h}) &= F_0 + (1 - F_0)(1 - \cos{\theta_{i}})^5 \\ F_0 &= \bigg(\frac{n_i - n_t}{n_i + n_t}\bigg)^2 \end{aligned}

F0F_0は垂直反射率と呼ばれ, nin_i, ntn_tの代わりに直接指定されることもあります. 例えばDisney BRDFでは導電体フレネルを使う代わりに, F0F_0に金属の色を直接指定したりします.

透過側媒質の屈折率1.5で, 誘電体の場合のフレネル反射率をプロットすると以下のようになります.

誘電体フレネル
誘電体フレネル

入射角が90度に近づくにつれて, 反射率が1に近づくのが分かります. 黄色の線はSchlickの近似式で計算したフレネル反射率ですが, 厳密式(青線)をよく近似しているのが分かります.

導電体フレネル

導電体の場合のフレネル反射率は以下の式で与えられます.

rs=nicosθi(ntikt)cosθtnicosθi+(ntikt)cosθtrp=(ntikt)cosθinicosθt(ntikt)cosθi+nicosθtF(ωo,ωh)=rs2+rp22(5)\begin{aligned} r_s &= \frac{n_i\cos{\theta_i} - (n_t - ik_t)\cos{\theta_t}}{n_i\cos{\theta_i} + (n_t - ik_t)\cos{\theta_t}} \\ r_p &= \frac{(n_t - ik_t)\cos{\theta_i} - n_i\cos{\theta_t}}{(n_t - ik_t)\cos{\theta_i} + n_i\cos{\theta_t}} \\ F(\vec{\omega_o}, \vec{\omega_h}) &= \frac{r_s^2 + r_p^2}{2} \tag{5} \end{aligned}
  • ii: 虚数単位
  • ktk_t: 透過側媒質の消失係数

導電体の場合は光の一部が吸収されます. これを表現するため, 導電体の場合は屈折率が複素数(複素屈折率)で与えられます.

金の波長630nm(R), 532nm(G), 465nm(B)における複素屈折率を用いて, 導電体の場合のフレネル反射率をプロットすると以下のようになります.

導電体フレネル
導電体フレネル

波長によってフレネル反射率がかなり異なることが分かります. 特に, 赤色成分の反射率が高いことが分かります. このために金は色がついているように見えます.

法線分布関数

法線分布関数に関しては, 現在はGGXを使うのが標準になりつつあります. GGXは以下のような楕円形の法線分布です.

D(ωh)=1παxαy(hx2αx2+hz2αy2+hy2)2D(\vec{\omega_h}) = \frac{1}{\pi\alpha_x\alpha_y\bigg(\frac{h_x^2}{\alpha_x^2} + \frac{h_z^2}{\alpha_y^2} + h_y^2\bigg)^2}
  • hx,hy,hzh_x, h_y, h_z: 接空間に投影したハーフベクトルのxx, yy, zz成分
  • αx,αy\alpha_x, \alpha_y: 法線分布の広がり具合を表すパラメーター

αx,αy\alpha_x, \alpha_yに関してはユーザーが直接設定するのではなく, roughness(粗さ)とanisotropy(異方性)というパラメーターから次のように設定することが多いです.

αx=roughness2(1+anisotropy)αy=roughness2(1anisotropy)\begin{aligned} \alpha_x &= roughness^2(1 + anisotropy) \\ \alpha_y &= roughness^2(1 - anisotropy) \end{aligned}

(Revisiting Physically Based Shading at Imageworks p.24より)

Shadowing-Masking function

G2G_2Λ\Lambdaという別の関数から以下のように計算することが多いです(Height-Correlated Masking and Shadowing).

G2(ωi,ωo)=11+Λ(ωi,ωh)+Λ(ωo,ωh)G_2(\vec{\omega_i}, \vec{\omega_o}) = \frac{1}{1 + \Lambda(\vec{\omega_i}, \vec{\omega_h}) + \Lambda(\vec{\omega_o}, \vec{\omega_h})}

Λ\Lambdaは法線分布関数に付随して定義され, GGXの場合以下のようになります.

Λ(ω,ωh)=1+1+αx2ωx2+αy2ωz2ωy22\Lambda(\vec{\omega}, \vec{\omega_h}) = \frac{-1 + \sqrt{1 + \frac{\alpha_x^2\omega_x^2 + \alpha_y^2\omega_z^2}{\omega_y^2}}}{2}
  • ωx,ωy,ωz\omega_x, \omega_y, \omega_z: ハーフベクトルを法線とする接空間に投影したω\vec{\omega}xx, yy, zz成分

Microfacet BRDFの形状

ここでMicrofacet BRDFの具体的な形状について見てみます. 屈折率1.5の誘電体フレネル, anisotropy = 0という設定で, roughnessを様々な値に変えながらMicrofacet BRDFを計算すると以下のようになります. 入射方向ωo\vec{\omega_o}は左45度, Microfacetは真上を向いていると仮定しています.

(BRDFの値は最大で1になるように正規化)

roughnessが小さいとBRDFが反射方向に集中し, roughnessを大きくしていくとBRDFが反射方向から広がっていくことが分かります.

まとめると, Microfacet BRDFはフレネル反射率, roughness, anisotropyという3つのパラメーターを持っています. これらのパラメーターを変えることで様々な光沢反射, 金属反射などを再現することが出来ます.

Microfacet BTDF

Microfacet BTDFはMicrofacetによる屈折(透過)を表現するBTDFです. すりガラスのような材質を表現するために使われます.

式は以下のようになっています.

f(x,ωi,ωo)=cosθohcosθihcosθocosθint2(1F(ωo,ωh))G2(ωi,ωo)D(ωh)(nicosθoh+ntcosθih)2(6)f(x, \vec{\omega_i}, \vec{\omega_o}) = \frac{|\cos{\theta_{oh}}||\cos{\theta_{ih}}|}{|\cos{\theta_o}||\cos{\theta_i}|}\frac{n_t^2(1 - F(\vec{\omega_o}, \vec{\omega_h}))G_2(\vec{\omega_i}, \vec{\omega_o})D(\vec{\omega_h})}{(n_i\cos{\theta_{oh}} + n_t\cos{\theta_{ih}})^2} \tag{6}
  • ωh=normalize((niωo+ntωi))\vec{\omega_h} = \mathrm{normalize}(-(n_i\vec{\omega_o} + n_t\vec{\omega_i}))
  • θoh,θih\theta_{oh}, \theta_{ih}: ωo,ωi\vec{\omega_o}, \vec{\omega_i}とハーフベクトルωh\vec{\omega_h}のなす角
  • ni,ntn_i, n_t: 入射側, 透過側媒質の屈折率

Microfacet BTDFではフレネル項には誘電体フレネルが使われます. G2G_2, DDに関してはMicrofacet BRDF同様にGGXが使われることが多いです.

屈折率1.5の誘電体フレネル, anisotropy = 0という設定で, roughnessを様々な値に変えながらMicrofacet BTDFを計算すると以下のようになります. 入射方向ωo\vec{\omega_o}は左45度, Microfacetは真上を向いていると仮定しています.

(BTDFの値は最大で1になるように正規化)

Microfacet BRDF同様に, 屈折方向を中心にBTDFが広がっている様子が分かります.

以降ではこのような基本的なBSDFを使って, 現実にあるマテリアルがどのように再現されるのかについて見ていきます.

現実にあるマテリアルの再現

現実にある物体はマットな質感, プラスチックのような質感, 金属のような質感, 人の肌のような質感など多種多様な質感があります. これらの多種多様な質感を, 上で見たような1つのBSDFだけで表現するのには無理があります. そこで物理ベースレンダリングでは, 複数のBSDFを足し合わせた以下のような複合BSDFで多種多様な質感を再現する事が多いです.

f(x,ωi,ωo)=k=1Nakfk(x,ωi,ωo)(1)f(x, \vec{\omega_i}, \vec{\omega_o}) = \sum_{k=1}^N a_k f_k(x, \vec{\omega_i}, \vec{\omega_o}) \tag{1}
  • aka_k: kk番目のBSDFの係数
  • fkf_k: kk番目のBSDF

複合BSDFでは, マットな質感を表現するBRDF, 光沢反射を表現するBRDF, 金属反射を表現するBRDFなど, 質感の基本的な要素をそれぞれ別のBSDFで表現し, 最後にそれらをミックスするというアプローチで様々な質感を再現します.

以降ではこれらの基本的な要素を, 実際にどのようなBRDF, BTDFでモデル化することが出来るのかについて見ていきます.

マットな質感

マットな質感は物体内部で光が散乱を繰り返した結果, 物体表面から出てくる光がどの方向にも一様に反射されて出ていくように見えることが原因です.

式(2)のLambert BRDFはこのマットな質感の物体表面から出る光をうまくモデル化出来るため, よく使われます.

また, Microfacetベースのモデルである Oren-Nayar BRDF もよく使われます. Oren-Nayar BRDFは以下のような式で表されます.

f(x,ωi,ωo)=Rπ(A+Bmax(0,cos(ϕiϕo))sinαtanβ)A=1σ22(σ2+0.33)B=0.45σ2σ2+0.09α=max(θi,θo)β=min(θi,θo)\begin{aligned} f(x, \vec{\omega_i}, \vec{\omega_o}) &= \frac{R}{\pi}(A + B\max(0, \cos(\phi_i - \phi_o))\sin{\alpha}\tan{\beta}) \\ A &= 1 - \frac{\sigma^2}{2(\sigma^2 + 0.33)} \\ B &= \frac{0.45\sigma^2}{\sigma^2 + 0.09} \\ \alpha &= \max(\theta_i, \theta_o) \\ \beta &= \min(\theta_i, \theta_o) \end{aligned}

(式はPBRTより. この式は厳密解の近似式)

  • RR: 反射率(アルベド)

σ\sigmaはMicrofacetの面の粗さ(roughness)に対応しています.

Oren-Nayar BRDFをレンダリングすると以下のような画像が得られます. この画像ではσ\sigmaを右に行くほど大きくしています.

Oren-Nayar BRDF
Oren-Nayar BRDF

光沢反射

光沢反射は式(3)のMicrofacet BRDFでモデル化されます. フレネル反射率には式(4)の誘電体フレネルが使われます.

以下は, 屈折率1.5, anisotropy = 0でroughnessを0.05から0.8まで変えながらMicrofacet BRDFをレンダリングした結果です. 物体表面に光沢反射が出ている事が分かると思います.

Microfacet BRDF(誘電体フレネル)
Microfacet BRDF(誘電体フレネル)

これをマットな質感を表現するOren-Nayar BRDFと足し合わせて複合BSDFにしてあげると, 光沢反射の下の基底層の色が付き, 以下の画像のようになります.

Microfacet BRDF(誘電体フレネル) + Oren-Nayar BRDF
Microfacet BRDF(誘電体フレネル) + Oren-Nayar BRDF

プラスチックのような質感が再現出来ていることが分かります.

金属反射

金属反射は式(3)のMicrofacet BRDFで, 式(5)の導電体フレネルを用いてモデル化されます.

以下は, 金の複素屈折率, anisotropy = 0でroughnessを0.2から1.0まで変えながらMicrofacet BRDFをレンダリングした結果です.

Microfacet BRDF(導電体フレネル)
Microfacet BRDF(導電体フレネル)

金の色と質感が再現出来ていることが分かります.

透過

ガラスなどの材質による屈折は, 式(6)のMicrofacet BTDFでモデル化されます.

以下は, 屈折率1.5, anisotropy = 0でroughnessを0.1から0.5まで変えながらMicrofacet BTDFをレンダリングした結果です.

Microfacet BTDF
Microfacet BTDF

表面に粗さを持ったすりガラスのような材質による屈折が再現出来ていることが分かります.

これに光沢反射を表現するMicrofacet BRDFを加えてあげると, 以下のようになります.

Microfacet BTDF + Microfacet BRDF(誘電体フレネル)
Microfacet BTDF + Microfacet BRDF(誘電体フレネル)

物体表面での反射が加わり, ガラスのような質感が再現出来ています.

ボリュームによる影響

光は物体表面だけではなく, 物体内部でも吸収, 散乱を繰り返し, それが物体の質感に大きな影響を与えることがあります. 表面化散乱(Subsurface scattering) はそのような例の1つで, 人の肌を写実的にレンダリングする時には必要になります.

表面化散乱
表面化散乱

このようなボリュームによる影響に関しては, BSDFとしてモデル化するのではなく, BSSRDFによるアプローチ, またはボリュームレンダリングで数値計算することが多いです.

ボリュームレンダリングに関しては去年のレイトレアドベントカレンダーで記事を書いたので, 良かったらご覧ください.

https://blog.teastat.uk/post/2021/12/montecarlo-raytracing-of-homogeneous-medium/

Arnold Standard Surface

具体的な物理ベースマテリアルの例として, ここではArnold Standard Surfaceを見ていきます.

Arnold Standard Surfaceは以下のような7つのBRDF, BTDFで構成される複合BSDFになっています.

f=acoatfcoat+ametalfmetal+aspecularfspecular+atransmissionftransmission+asheenfsheen+adiffusetransmissionfdiffusetransmission+adiffusefdiffusef = a_{coat}f_{coat} + a_{metal}f_{metal} + a_{specular}f_{specular} + a_{transmission}f_{transmission} + a_{sheen}f_{sheen} + a_{diffuse transmission}f_{diffuse transmission} + a_{diffuse}f_{diffuse}

それぞれの項は次のようなBSDFで構成され, 異なる役割を持っています.

Layer BSDF Description
Coat Microfacet BRDF(誘電体フレネル) コーティング面による光沢反射を表現
Metal Microfacet BRDF(導電体フレネル) 金属反射を表現
Specular Microfacet BRDF(誘電体フレネル) 光沢反射を表現
Transmission Microfacet BTDF(誘電体フレネル) 屈折による透過を表現
Sheen Microfacet Sheen BRDF 布のような材質を表現
Diffuse Transmission Oren-Nayar BTDF 拡散透過を表現
Diffuse Oren-Nayar BRDF 拡散反射を表現

Oren-Nayar BSDF, Microfacet BSDFをベースにそれぞれの層(Layer)が表現されています. また, 特殊なBRDFとしてMicrofacet Sheen BRDFというものがSheenレイヤーの表現に使われています. このBRDFは布のような材質を表現するために使われています. レンダリングしてみると以下の画像のようになります.

Microfacet Sheen BRDF
Microfacet Sheen BRDF

Arnold Standard Surfaceには他にも表面化散乱を表現するSubsurface scatteringレイヤーがあります. これに関してはBSDFではなく, ボリュームレンダリングとして扱われています.

Arnold Standard Surfaceの仕様の詳細については以下で見ることが出来ます.

https://autodesk.github.io/standard-surface/

また, 実装例については以下で見ることが出来ます.

https://github.com/Autodesk/Aurora/blob/main/Libraries/Aurora/Source/Shaders/StandardSurfaceBSDF.slang

他の有名な物理ベースマテリアルモデルには, Disney BRDFUE4 BRDFなどがあります. いずれもLambert BRDF, Microfacet BSDFなどの複合BSDFとして構成されています. 各マテリアルモデルでは採用されるBRDFの種類, BRDFの内部パラメーター, 係数, ユーザーからの入力パラメーターの扱いなどが異なり, それが各マテリアルモデルの使いやすさ, レンダリング結果の違いになっています. 重要なのはいずれも複合BSDF + α\alphaによる表現に落ち着いているということです.

レンダラーで複合BSDFを実装する場合, 複合BSDFの評価とサンプリングが必要になります. これについては24日目の記事で説明しています.

最後に

物理ベースマテリアルは現在も研究開発が進んでいる領域であり, 今後新たな種類のBSDFや, マテリアルモデルが出てくる可能性があります. しかし, この記事で紹介した複合BSDFに基づくマテリアルモデルは今後もベースになっていくと思われるので, 知っておく価値はあるかと思います.

References