BRDF理论及shader实现(上)

摘要

本文将从渲染方程谈起,介绍实时渲染中常用的几种BRDF公式,相关理论及其代码实现。

篇幅所限,整篇文章分为两部分,下篇连接:

BRDF理论及shader实现(下)

理论介绍

渲染这个事情解决的是入射光线照射到物体上,反射光线怎么计算的问题。如渲染方程所写:

L o ( v ) = ∫ Ω f ( l , v ) ⊗ L i ( l ) cos ⁡ θ i d ω i L_o({\bf{v}})=\int_\Omega f({\bf{l}},{\bf{v}})\otimes L_i({\bf{l}})\cos\theta_id\omega_i Lo(v)=Ωf(l,v)Li(l)cosθidωi

其中, L o ( v ) L_o({\bf{v}}) Lo(v)表示出射光线的radiance; L i ( l ) L_i({\bf{l}}) Li(l)表示入射光线的radiance; f ( l , v ) f({\bf{l}},{\bf{v}}) f(l,v)是BRDF项,表示材质对物体的作用; θ i \theta_i θi是入射角度;积分对象是入射光线,积分范围是 cos ⁡ θ i > 0 \cos\theta_i>0 cosθi>0的半球面。

渲染方程是一种非常理想的情况,但是由于它包含一个球面积分,在实时计算中是几乎不可能求解出来的。因此,我们需要一些近似的方法求解渲染方程。

BRDF

BRDF(Bidirectional Reflectance Distribution Function)表示的是出射光线的辐射率radiance与入射光线的辐照度irradiance之间的比值,公式为:

f ( l , v ) = d L o ( v ) d E ( l ) = d L o ( v ) cos ⁡ θ i L i ( l ) d ω i f({\bf{l}},{\bf{v}})=\frac{dL_o({\bf{v}})}{dE({\bf{l}})} = \frac{dL_o({\bf{v}})}{\cos\theta_iL_i({\bf{l}})d\omega_i} f(l,v)=dE(l)dLo(v)=cosθiLi(l)dωidLo(v)

其中, v {\bf{v}} v表示视角方向,即出射光线方向, l {\bf{l}} l表示入射光线方向。有一个很常被问到的问题是,为什么BRDF是radiance与irradiance的比值,而不是radiance比radiance或者irradiance?这里给出一个我个人觉得比较合理的解释,那就是BRDF的定义来自于渲染方程(没错又是渲染方程),其单位自然取决于渲染方程需要的单位。 我们再看一下渲染方程是怎么写的:

L o ( v ) = ∫ Ω f ( l , v ) ⊗ L i ( l ) cos ⁡ θ i d ω i L_o({\bf{v}})=\int_\Omega f({\bf{l}},{\bf{v}})\otimes L_i({\bf{l}})\cos\theta_id\omega_i Lo(v)=Ωf(l,v)Li(l)cosθidωi

左边是出射光线的radiance,右边积分里面分别是BRDF、入射光线radiance、cosine角度,然后对立体角进行积分。radiance的单位是 W / m 2 s r W/m^2sr W/m2sr,irradiance的单位是 W / m 2 W/m^2 W/m2那么BRDF的单位就是radiance/(radiance*立体角) = radiance/irradiance,即 s r − 1 sr^{-1} sr1

在光栅化渲染中,对BRDF的近似通常是将其分解为两部分:

  • diffuse部分,记为 f d f_d fd
  • specular部分,记为 f s f_s fs

这里为了行文通顺,就不采用中文译名漫反射、高光了,直接用英语。这两个分量的示意图如下:

diagram_fr_fd

diffuse表示对各个方向均匀反射的光线部分,specular表示遵循反射定律朝特定方向反射的光线部分。二者的物理意义不同,计算起来也非常不一样。

但是实际上,diffuse和specular仅仅是对真实物体的近似。物理上,光线打在物体表面,只会有两种物理现象——反射和折射。反射部分就是specular,这个比较好理解。折射部分则进入了物体内部,经过在物体内部的多次反射,最终在距离入射点一定距离的地方折射出物体,此时出射光线的方向近似随机的,也就是diffuse部分。

diagram_scattering

顺便一提,这种光线折射进入物体表面多次反射最终折射出去的现象,称为次表面散射。用diffuse来近似次表面散射现象的方法是比较“偷懒”的,但是也是比较高效的。完整的次表面散射算法可以用来模拟皮肤的通透效果,但是也会复杂得多。

再说回diffuse部分。这里就可以引入金属conductor和介电质dielectric的一个不同了。conductor是没有次表面散射现象的,也就是没有diffuse分量。但是dielectric有。通常我们可以用metallic来表示物体的金属性,后面会提到怎么用它来控制diffuse和specular分量。

微表面理论

现实世界中的表面通常不是平整的——至少不是物理意义上的绝对平整,而是有微小的起伏的。既然不是绝对平整,那么specular也不会完美地遵循反射定律。为了表示这种粗糙的表面,就有了微表面理论(microfacet theory)。

微表面理论承认宏观层面平整的表面在微观层面会有起伏,这些起伏使得微观层面的法向不完全等于宏观层面表现出来的法向;而每个微小的表面,我们认为它们都是绝对光滑的,光线满足反射定律。如下图。

diagram_macrosurface

第一个需要解决的问题是,微观上做到了局部的绝对光滑,宏观上的反射情况怎么表示呢?为解决这个问题,引入法向分布函数 D D D,normal distribution function(缩写为NDF),表示微观表面的法向分布。

法向分布函数 D

法向分布函数这个名称有一些迷惑性,因为 D D D并不是概率分布函数,而是法向量的分布函数,称为distribution of normals更恰当一些。如果是概率分布,那么 D D D应该满足:

∫ Ω D ( m ) d ω m = 1 \int_\Omega D({\bf{m}})d\omega_m = 1 ΩD(m)dωm=1

但是并不是这样的。 D D D的真实意义应该是对应法向的微表面投影到宏观表面上的面积的分布。满足:

∫ D ( m ) ( n ⋅ m ) d ω m = 1 \int D({\bf{m}})({\bf{n}}\cdot{\bf{m}})d\omega_m = 1 D(m)(nm)dωm=1

因此,积分 ∫ Ω D ( m ) d ω m \int_\Omega D({\bf{m}})d\omega_m ΩD(m)dωm必然是大于1的。这也符合常识:微表面的起伏会使得微表面的总面积大于宏观表面的面积,起伏越大微表面面积越大。

如果我们改变上式中的 n {\bf{n}} n,相应的,面积从投影到宏观表面(垂直于法向量 n {\bf{n}} n)变为投影到垂直于 v {\bf{v}} v的平面:

∫ D ( m ) ( v ⋅ m ) d ω m = v ⋅ n \int D({\bf{m}})({\bf{v}}\cdot{\bf{m}})d\omega_m = {\bf{v}}\cdot{\bf{n}} D(m)(vm)dωm=vn

如下图所示。

NDF-0

右侧图中的正负号表示当 v ⋅ m {\bf{v}}\cdot{\bf{m}} vm的正负,被遮挡的部分会相互抵消。

虽然积分中被遮挡的部分自行抵消了,但是这里面隐含着一个问题,即 D D D中包含的这些被遮挡的微表面,其实是对出射光线没有贡献的,我们只关心没有被遮挡的部分,如下图,这就引入了第二个问题,如何解决自遮挡现象。

NDF-1

遮挡函数 G

对于第二个问题,我们引入遮挡函数(masking function) G G G来描述微表面之间的自遮挡现象,通常也称为可见性(visibility)或者几何项(Geometry)。

∫ G 1 ( v , m ) D ( m ) ( v ⋅ m ) χ + ( v , m ) d ω m = v ⋅ n \int G_1({\bf{v}},{\bf{m}})D({\bf{m}})({\bf{v}}\cdot{\bf{m}})\chi^+({\bf{v}},{\bf{m}})d\omega_m = {\bf{v}}\cdot{\bf{n}} G1(v,m)D(m)(vm)χ+(v,m)dωm=vn

其中, G 1 G_1 G1描述的是从 v {\bf{v}} v方向看法向为 m {\bf{m}} m的微表面的可见性。从微观层面来看, G 1 G_1 G1是一个二值函数,可见/不可见;从宏观层面看 G 1 G_1 G1表示一个统计概率。 χ + \chi^+ χ+表示:

χ + ( x ) = { 1 , where  x > 0 0 , where  x ≤ 0 \chi^+(x)= \begin{cases} 1, & \text{where $x > 0$} \\ 0, & \text{where $x \leq 0$} \end{cases} χ+(x)={1,0,where x>0where x0

对于 G 1 G_1 G1应该怎么选取,有一个洞见就是,对于 ( v ⋅ m ) ({\bf{v}}\cdot{\bf{m}}) (vm)小于0的微表面, G 1 G_1 G1必然是0,因为这些微表面不是被其他微表面遮挡不遮挡的问题了,它们压根就不会被看到。

那对于 ( v ⋅ m ) ({\bf{v}}\cdot{\bf{m}}) (vm)大于0的微表面,又具有怎样的性质呢?由于我们假设的微表面是一阶不连续的,即相邻的微表面的法向没有相关性, ( v ⋅ m ) ({\bf{v}}\cdot{\bf{m}}) (vm)大于0的微表面的可见性与微表面的法向没有关系,只与视角方向有关。这样,我们可以将 G 1 G_1 G1写为:

G 1 ( v , m ) = G 1 local ( v , m ) G 1 dist ( v ) G_1({\bf{v}},{\bf{m}})=G_1^{\text{local}}({\bf{v}},{\bf{m}})G_1^{\text{dist}}({\bf{v}}) G1(v,m)=G1local(v,m)G1dist(v)

其中, G 1 local ( v , m ) G_1^{\text{local}}({\bf{v}},{\bf{m}}) G1local(v,m)用于筛选 ( v ⋅ m ) ({\bf{v}}\cdot{\bf{m}}) (vm)大于0的微表面,记为:

G 1 local ( v , m ) = χ + ( v , m ) G_1^{\text{local}}({\bf{v}},{\bf{m}})=\chi^+({\bf{v}},{\bf{m}}) \\ G1local(v,m)=χ+(v,m)

G 1 dist ( v ) G_1^{\text{dist}}({\bf{v}}) G1dist(v)可以从 D D D推导出来:

v ⋅ n = ∫ G 1 ( v , m ) D ( m ) ( v ⋅ m ) χ + ( v , m ) d ω m = ∫ G 1 local ( v , m ) G 1 dist ( v ) D ( m ) ( v ⋅ m ) χ + ( v , m ) d ω m = G 1 dist ( v ) ∫ χ + ( v , m ) D ( m ) ( v ⋅ m ) d ω m G 1 dist ( v ) = v ⋅ n ∫ D ( m ) ( v ⋅ m ) χ + ( v , m ) d ω m \begin{aligned} {\bf{v}}\cdot{\bf{n}} & = \int G_1({\bf{v}},{\bf{m}})D({\bf{m}})({\bf{v}}\cdot{\bf{m}})\chi^+({\bf{v}},{\bf{m}})d\omega_m \\ & = \int G_1^{\text{local}}({\bf{v}},{\bf{m}})G_1^{\text{dist}}({\bf{v}})D({\bf{m}})({\bf{v}}\cdot{\bf{m}})\chi^+({\bf{v}},{\bf{m}})d\omega_m \\ & = G_1^{\text{dist}}({\bf{v}})\int \chi^+({\bf{v}},{\bf{m}})D({\bf{m}})({\bf{v}}\cdot{\bf{m}})d\omega_m \\ G_1^{\text{dist}}({\bf{v}}) & = \frac{{\bf{v}}\cdot{\bf{n}}}{\int D({\bf{m}})({\bf{v}}\cdot{\bf{m}})\chi^+({\bf{v}},{\bf{m}})d\omega_m} \end{aligned} vnG1dist(v)=G1(v,m)D(m)(vm)χ+(v,m)dωm=G1local(v,m)G1dist(v)D(m)(vm)χ+(v,m)dωm=G1dist(v)χ+(v,m)D(m)(vm)dωm=D(m)(vm)χ+(v,m)dωmvn

那么有:

G 1 ( v , m ) = χ + ( v , m ) v ⋅ n ∫ D ( m ) ( v ⋅ m ) χ + ( v , m ) d ω m G_1({\bf{v}},{\bf{m}}) = \chi^+({\bf{v}},{\bf{m}}) \frac{{\bf{v}}\cdot{\bf{n}}}{\int D({\bf{m}})({\bf{v}}\cdot{\bf{m}})\chi^+({\bf{v}},{\bf{m}})d\omega_m} G1(v,m)=χ+(v,m)D(m)(vm)χ+(v,m)dωmvn

同时, G 1 dist ( v ) G_1^{\text{dist}}({\bf{v}}) G1dist(v) G 1 ( v ) G_1({\bf{v}}) G1(v)也可以写成如下的形式,[16]给出了详细的推导过程:

G 1 dist ( v ) = 1 1 + Λ ( v ) G 1 ( v ) = χ + ( v , m ) 1 + Λ ( v ) \begin{aligned} G_1^{\text{dist}}({\bf{v}}) & =\frac{1}{1+\Lambda({\bf{v}})} \\ G_1({\bf{v}}) & =\frac{\chi^+({\bf{v}},{\bf{m}})}{1+\Lambda({\bf{v}})} \end{aligned} G1dist(v)G1(v)=1+Λ(v)1=1+Λ(v)χ+(v,m)

引入函数 Λ ( v ) \Lambda({\bf{v}}) Λ(v)使得 G 1 dist ( v ) G_1^{\text{dist}}({\bf{v}}) G1dist(v)更简洁。

到这一步,可以看出,只要确定了法向分布函数 D D D,就可以求出遮挡函数 G 1 G_1 G1

到现在为止,我们推导出了 G 1 ( v , m ) G_1({\bf{v}},{\bf{m}}) G1(v,m)的公式,它表示的是从出射光线方向看,微表面的遮挡情况。但是在BRDF中,除了出射光线方向会遮挡,入射光线方向也会被遮挡。两者的遮挡都会影响出射光线。这个描述存在两个方向遮挡的函数为 G 2 ( l , v , m ) G_2({\bf{l}},{\bf{v}},{\bf{m}}) G2(l,v,m),关于怎么用 G 1 G_1 G1构造 G 2 G_2 G2,有比较多的方法。

Separable G

最简单的 G 2 G_2 G2,也是最常用的一种smith形式,就是:

G 2 ( l , v , m ) = G 1 ( l , m ) ⋅ G 1 ( v , m ) = χ + ( l , m ) 1 + Λ ( l ) ⋅ χ + ( v , m ) 1 + Λ ( v ) \begin{aligned} G_2({\bf{l}},{\bf{v}},{\bf{m}}) & = G_1({\bf{l}},{\bf{m}}) \cdot G_1({\bf{v}},{\bf{m}})\\ & = \frac{\chi^+({\bf{l}},{\bf{m}})}{1+\Lambda({\bf{l}})}\cdot\frac{\chi^+({\bf{v}},{\bf{m}})}{1+\Lambda({\bf{v}})} \end{aligned} G2(l,v,m)=G1(l,m)G1(v,m)=1+Λ(l)χ+(l,m)1+Λ(v)χ+(v,m)

这个公式被称为分离的(separable) G G G,因为它确定的遮挡概率只跟微表面的法向有关,而忽略了微表面的高度遮挡。它的误差存在于高度遮挡频繁的情况:

  1. 粗糙的表面;
  2. 入射角和出射角接近于 90 ° 90\degree 90°,即掠射角的情况。

另外可以考虑这样一种特殊情况,当光线入射角度等于出射角度的时候,也就是视角和光源来源一样的时候,理论上 G 2 ( l , v , m ) G_2({\bf{l}},{\bf{v}},{\bf{m}}) G2(l,v,m)应该等于 G 1 ( v , m ) G_1({\bf{v}},{\bf{m}}) G1(v,m),因为入射光线和出射光线的遮挡是一样的。但是在上式的情况下, G 2 = G 1 2 G_2=G_1^2 G2=G12,这就不对了。准确的说,这个形式给出的阴影比实际要强。

尽管不够准确,但是smith形式的 G 2 G_2 G2已经足够模拟真实情况,因此应用非常广泛。

Height-correlated G

第二种形式,被称为高度相关的(height-correlated) G G G

G 2 ( l , v , m ) = χ + ( l , m ) χ + ( v , m ) 1 + Λ ( l ) + Λ ( v ) G_2({\bf{l}},{\bf{v}},{\bf{m}})=\frac{\chi^+({\bf{l}},{\bf{m}})\chi^+({\bf{v}},{\bf{m}})}{1+\Lambda({\bf{l}})+\Lambda({\bf{v}})} G2(l,v,m)=1+Λ(l)+Λ(v)χ+(l,m)χ+(v,m)

这个形式的 G G G对于入射光线和出射光线差别较大的情况下,更准确,但是当入射光线和出射光线非常接近的时候,同样有着比实际更强的阴影。具体的推导过程可以参考[16]。

Direction-correlated G

第三种形式,是为了解决入射光线和出射光线非常接近时的误差。考虑一种极端的情况,当入射光线和出射光线平行的时候,阴影其实是消失了的。这个现象被称为hotspot effect(热点现象?)。方向相关的(direction-correlated) G G G就是基于这个洞察提出的:

G 2 ( l , v , m ) = λ ( ϕ ) G 1 ( l , m ) ⋅ G 1 ( v , m ) + ( 1 − λ ( ϕ ) ) min ⁡ ( G 1 ( l , m ) , G 1 ( v , m ) ) G_2({\bf{l}},{\bf{v}},{\bf{m}}) = \lambda(\phi)G_1({\bf{l}},{\bf{m}}) \cdot G_1({\bf{v}},{\bf{m}})+(1-\lambda(\phi))\min{(G_1({\bf{l}},{\bf{m}}), G_1({\bf{v}},{\bf{m}}))} G2(l,v,m)=λ(ϕ)G1(l,m)G1(v,m)+(1λ(ϕ))min(G1(l,m),G1(v,m))

其中的 ϕ \phi ϕ表示 l {\bf{l}} l v {\bf{v}} v在垂直于 n {\bf{n}} n的平面上的夹角(可以理解为球坐标系下 ϕ \phi ϕ坐标的差值)。 λ ( ϕ ) \lambda(\phi) λ(ϕ)的取值决定了 G 2 G_2 G2的形态,当入射角和出射角非常接近的时候, λ ( ϕ ) = 0 \lambda(\phi)=0 λ(ϕ)=0,此时 G 2 G_2 G2退化到 G 1 G_1 G1的形态。

Height-direction-correlated G

第四种形式,高度方向均相关的 G G G

G 2 ( l , v , m ) = χ + ( l , m ) χ + ( v , m ) 1 + max ⁡ ( Λ ( l ) , Λ ( v ) ) + λ ( l , v ) min ⁡ ( Λ ( l ) , Λ ( v ) ) G_2({\bf{l}},{\bf{v}},{\bf{m}})=\frac{\chi^+({\bf{l}},{\bf{m}})\chi^+({\bf{v}},{\bf{m}})}{1+\max(\Lambda({\bf{l}}),\Lambda({\bf{v}}))+\lambda({\bf{l}},{\bf{v}})\min(\Lambda({\bf{l}}),\Lambda({\bf{v}}))} G2(l,v,m)=1+max(Λ(l),Λ(v))+λ(l,v)min(Λ(l),Λ(v))χ+(l,m)χ+(v,m)

这个形式是前面两种形式的混合,它既能在入射角和出射角接近的时候退化到 G 1 G_1 G1的形态,也能在入射角和出射角分开的时候逐渐变为高度相关的 G G G。唯一需要确定的是 λ ( l , v ) \lambda({\bf{l}},{\bf{v}}) λ(l,v)的形式,对此不同的paper有着不同的提议,在此不再展开。

重新回到微表面理论。

至此,基于微表面理论的BRDF函数表示为:

f x ( l , v ) = 1 ∣ n ⋅ v ∣ ∣ n ⋅ l ∣ ∫ Ω D ( m , α ) G 2 ( v , l , m ) f m ( v , l , m ) ( v ⋅ m ) ( l ⋅ m ) χ + ( v , m ) χ + ( l , m ) d m f_x({\bf{l}},{\bf{v}}) = \frac{1}{\mid{\bf{n}}\cdot{\bf{v}}\mid\mid{\bf{n}}\cdot{\bf{l}}\mid}\int_\Omega D({\bf{m}},\alpha)G_2({\bf{v}},{\bf{l}},{\bf{m}})f_m({\bf{v}},{\bf{l}},{\bf{m}})({\bf{v}}\cdot{\bf{m}})({\bf{l}}\cdot{\bf{m}})\chi^+({\bf{v}},{\bf{m}})\chi^+({\bf{l}},{\bf{m}})d{\bf{m}} fx(l,v)=nvnl1ΩD(m,α)G2(v,l,m)fm(v,l,m)(vm)(lm)χ+(v,m)χ+(l,m)dm

其中, n {\bf{n}} n表示该点的(宏观)法向方向, m {\bf{m}} m表示微观表面的法向。

D D D G 2 G_2 G2前面介绍过了,不在赘述。

f x f_x fx既可以表示diffuse分量,也可以表示specular分量,二者的差别在于 f m f_m fm的选取。

另外一个对 f m f_m fm的理解是,相对于 f x f_x fx表示宏观的BRDF项, f m f_m fm可以理解为微观的BRDF项。它的物理意义是在微观表面,出射光线的辐射率radiance与入射光线的辐照度irradiance之间的比值:

f m = d L o ( v , m ) l ⋅ m ⋅ L i ( l ) d ω i f_m = \frac{dL_o({\bf{v}}, {\bf{m}})}{{\bf{l}}\cdot{\bf{m}} \cdot L_i({\bf{l}})d\omega_i} fm=lmLi(l)dωidLo(v,m)

这样,利用微表面理论我们构建了一个绝对光滑的局部表面,通过选取理想情况下的BRDF项 f m f_m fm,我们就可以还原宏观表面的真实的 f x f_x fx。可以说,微表面理论填补了理想表面与真实物体之间的鸿沟,让我们可以用物理理论还原真实物体的情况。

下篇就具体看一下对于diffuse和specular,BRDF的具体形式,以及对应的shader实现。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值