计算机图形学:PBR

PBR(Physically Based Rendering)

基于物理的渲染(Physically Based Rendering,PBR)是指使用基于物理原理和微平面理论建模的着色/光照模型,以及使用从现实中测量的表面参数来准确表示真实世界材质的渲染理念。

虽然如此,基于物理的渲染仍然只是对基于物理原理的现实世界的一种近似,这也就是为什么它被称为基于物理的着色(Physically based Shading) 而非物理着色(Physical Shading)的原因。

判断一种PBR光照模型是否是基于物理的,必须满足以下三个条件:
  • 基于微平面(Microfacet)的表面模型。
  • 能量守恒。
  • 应用基于物理的BRDF。

1. 微表面理论

所有的PBR技术都基于微平面理论。这项理论认为,达到微观尺度之后任何平面都可以用被称为微平面(Microfacets)的细小镜面来进行描绘。根据平面粗糙程度的不同,这些细小镜面的取向排列可以相当不一致:
image

产生的效果就是:一个平面越是粗糙,这个平面上的微平面的排列就越混乱。这些微小镜面这样无序取向排列的影响就是,当我们特指镜面光/镜面反射时,入射光线更趋向于向完全不同的方向发散(Scatter)开来,进而产生出分布范围更广泛的镜面反射。而与之相反的是,对于一个光滑的平面,光线大体上会更趋向于向同一个方向反射,造成更小更锐利的反射:

image

微表面理论(Microfacet Theory)认为我们看到的表面上的一点是由很多朝向各异且光学平的微小表面组成。当光线从 l \bm l l方向照射到这点,而我们在 v \bm v v方向观察时,由于光学平面只会将光线 l \bm l l反射到关于法线对称的 v \bm v v方向,而 l \bm l l v \bm v v已经确定,所以只有法线朝向正好是 l \bm l l v \bm v v的半角向量 h \bm h h的微表面才会将光线发射到 v \bm v v方向(如下图),从而被我们看见。
计算机图形学:PBR_第1张图片

2.能量守恒

2.1 光束运动

光线实际上可以被认为是一束没有耗尽就不停向前运动的能量,而光束是通过碰撞的方式来消耗能量。每一种材料都是由无数微小的粒子所组成,这些粒子都能如下图所示一样与光线发生碰撞。这些粒子在每次的碰撞中都可以吸收光线所携带的一部分或者是全部的能量而后转变成为热量。
计算机图形学:PBR_第2张图片

一般来说,并非所有能量都会被全部吸收,而光线也会继续沿着(基本上)随机的方向发散,然后再和其他的粒子碰撞直至能量完全耗尽或者再次离开这个表面。而光线脱离物体表面后将会协同构成该表面的(漫反射)颜色。不过在基于物理的渲染之中我们进行了简化,假设对平面上的每一点所有的折射光都会被完全吸收而不会散开。而有一些被称为次表面散射(Subsurface Scattering) 技术的着色器技术将这个问题考虑了进去,它们显著的提升了一些诸如皮肤,大理石或者蜡质这样材质的视觉效果,不过伴随而来的则是性能下降代价。

2.2 特殊的金属

对于金属(Metallic)表面,当讨论到反射与折射的时候还有一个细节需要注意。金属表面对光的反应与非金属材料还有电介质(Dielectrics)材料表面相比是不同的。 它们遵从的反射与折射原理是相同的,但是所有的折射光都会被直接吸收而不会散开,只留下反射光或者说镜面反射光。亦即是说, 金属表面不会显示出漫反射颜色。由于金属与电介质之间存在这样明显的区别,因此它们两者在PBR渲染管线中被区别处理

2.3 能量

折射能量 + 反射能量 <= 入射光能量

我们按照能量守恒的关系,首先计算镜面反射部分,它的值等于入射光线被反射的能量所占的百分比。然后折射光部分就可以直接由镜面反射部分计算得出:

float kS = calculateSpecularComponent(...); // 反射/镜面 部分
float kD = 1.0 - ks;                        // 折射/漫反射 部分

3. BRDF(Bidirectional Reflectance Distribution Function)双向反射分布函数

3.1 基本的几何概念

3.1.1 Spherical Coordinate (球面坐标)

计算机图形学:PBR_第3张图片

  • 方向相对法线的角度 θ \bm \theta θ,称为 极角(Polar Angle) 或天顶角(Zenith Angle)
  • 方向在平面上的投影相对于平面上一个坐标轴的角度 φ \bm \varphi φ,称为方位角(Azimuthal Angle)
3.1.2 立体角(Solid Angle)

立体角是度量三维角度的量,用符号w表示,单位为立体弧度(也叫球面度,Steradian,简写为sr),等于立体角在单位球上对应的区域的面积,单位球的表面积是 4 π 4\pi 4π,所以整个球面的立体角也是 4 π 4\pi 4π

Light generally arrives at or leaves a surface point from a range of directions that is denoted by solid angles. solid angles represents a 3D generalization of angle formed by a region on a sphere.

d w = d s r 2   d A = ( r d θ ) ( r s i n θ d φ ) = r 2 s i n θ d θ d φ   d w = d A r 2 = s i n θ d θ d φ \mathbf{dw=\frac{ds}{r^2}}\\ \ \\ \mathbf{dA=(rd\theta)(rsin\theta d\varphi)=r^2sin\theta d\theta d\varphi}\\ \ \\ \mathbf{dw = \frac{dA}{r^2} = sin\theta d\theta d\varphi}\\ dw=r2ds dA=(rdθ)(rsinθdφ)=r2sinθdθdφ dw=r2dA=sinθdθdφ

计算机图形学:PBR_第4张图片

3.1.3 Foreshortened Area(投影面积)

The apparent area of a surface patch according to the angle at which it is viewed

计算机图形学:PBR_第5张图片

a r e a = A c o s θ \mathbf{area=Acos\theta} area=Acosθ


3.2 辐射

3.2.1 Radiant Energy (辐射能量)

能量(Energy),用符号 Q Q Q表示,单位焦耳( J J J),每个光子都具有一定量的能量,和频率相关,频率越高,能量也越高。

计算机图形学:PBR_第6张图片

3.2.2 Radiant Flux (辐射通量)

辐射功率(Power),单位瓦特(Watts),或者焦耳/秒( J / s J/s J/s)。辐射度学中,辐射功率也被称为辐射通量(Radiant Flux)或者通量(Flux),指单位时间内通过表面或者空间区域的能量的总量,用符号$\Phi $表示,定义:

Φ = d Q d t \Phi = \frac{dQ}{dt} Φ=dtdQ

计算机图形学:PBR_第7张图片

3.2.3 Irradiance (辐照度)

辐照度(Irradiance),指单位时间内到达单位面积的辐射能量,或到达单位面积的辐射通量,也就是通量对于面积的密度。用符号 E E E表示,单位 W / m 2 W/m^2 W/m2。定义:

E = d Φ d A E = \frac{d\Phi}{dA} E=dAdΦ

计算机图形学:PBR_第8张图片

辐出度(Radiant Existance),也称为辐射出射度、辐射度(Radiosity),用符号M表示。辐出度与辐照度类似,唯一的区别在辐出度衡量的是离开表面的通量密度,辐照度衡量的是到达表面的通量密度。辐照度和辐出度都可以称为辐射通量密度(Radiant Flux Density)。

计算机图形学:PBR_第9张图片

处理通量密度时,我们需要注意表面朝向和光线方向的角度。如上图所示,当光线垂直表面照射时,照射到表面上时的间距为d;而当光线倾斜照射表面时(光照向量l和表面法线n的夹角为 θ i \theta_i θi),间距为 d / c o s θ i d/cos\theta_i d/cosθi,光线间距相对垂直照射时变大了,也就是说倾斜照射时通量密度降低了 。光照角度影响通量密度在我们日常生活中有很多实际例子,地球的季节变化就是因为光照角度变化,导致通量密度发生了变化。

假定不垂直于光线传输方向的表面面积为 A A A,将它投影到垂直于光线方向得到一个虚拟表面,这个虚拟表面的面积为 A c o s θ i Acos\theta_i Acosθi,通过这两个面积的通量是相同的,均为 Φ \Phi Φ,地表面接收到的辐照度 E = Φ A E=\frac{\Phi}{A} E=AΦ,虚拟表面上的辐照度 E L = Φ A ⊥ = Φ A c o s θ i E_L=\frac{\Phi}{A^\perp}=\frac{\Phi}{Acos\theta_i} EL=AΦ=AcosθiΦ,于是 E = E L c o s θ i E=E_Lcos\theta_i E=ELcosθi

3.2.4 Radiant Intensity (辐射强度)

辐射强度(Radiant Intensity),指通过单位立体角的辐射通量。用符号 I I I表示,单位 W / s r W/sr W/sr,定义:

I = d Φ d w I = \frac{d\Phi}{dw} I=dwdΦ

计算机图形学:PBR_第10张图片

之所以引入辐射强度,是因为有时候要度量通过一个点的通量的密度,但因为点的面积是0,无法使用辐照度,所以引入辐射强度。辐射强度不会随距离变化而变化,不像点光源的辐照度会随距离增大而衰减,这是因为立体角不会随距离变化而变化。

3.2.5 Radiance (辐射率, 光亮度)

辐射率(Radiance),指每单位面积每单位立体角的辐射通量密度。用符号 L L L表示,单位 W / m 2 s r W/m^2sr W/m2sr,定义:
L = d Φ d w d A ⊥ L = \frac{d\Phi}{dwdA^\perp} L=dwdAdΦ

辐射率实际上可以看成是我们眼睛看到(或相机拍到)的物体上一点的颜色。在基于物理着色时,计算表面一点的颜色就是计算它的辐射率。

计算机图形学:PBR_第11张图片

辐射率不会随距离变化而衰减,这和我们日常感受一致,在没有雾霾的干扰时,我们看到的物体表面上一点的颜色并不会随距离变化而变化。为什么辐照度会随距离增大而衰减,但是我们看到的颜色却不会衰减呢?这是因为随着距离变大,我们看到的物体上的一块区域到达视网膜的通量密度会变小,同时这块区域在视网膜表面上的立体角也会变小,正好抵消了通量密度的变化。


3.3 BRDF

我们的最终目标是 L o ( v ) L_o(v) Lo(v)(LightOut)
3.3.1 基本定义

我们看到一个表面,实际上是周围环境的光照射到表面上,然后表面将一部分光反射到我们眼睛里。双向反射分布函数 BRDF(Bidirectional Reflectance Distribution Function)就是描述表面入射光和反射光关系的。

对于一个方向的入射光,表面会将光反射到表面上半球的各个方向,不同方向反射的比例是不同的,我们用BRDF来表示指定方向的反射光入射光比例关系,BRDF定义为:

f ( l , v ) = d L o ( v ) d E ( l ) \mathbf{f(l, v) = \frac{dL_o(v)}{dE(l)}} f(l,v)=dE(l)dLo(v)

  • 其中 f f f就是BRDF, l l l是入射光方向, v v v是观察方向,也就是我们关心的反射光方向。
  • 辐射率
    • L o ( v ) L_o(v) Lo(v)指表面反射到 v v v方向的反射光的辐射率,来自于表面上半球所有方向的入射光线的贡献
    • d L o ( v ) dL_o(v) dLo(v)特指来自方向 l l l的入射光贡献的反射到 v v v方向的微分辐射率。
  • 辐照度
    • E E E指表面接收到的辐照度,来自上半球所有方向的入射光线的贡献
    • d E ( l ) dE(l) dE(l)特指来自于方向 l l l的微分辐照度。
3.3.2 用BRDF来计算表面辐射率

我们考虑来自方向 l l l入射光辐射率(LightIn) L i ( l ) L_i(l) Li(l)(辐射进来的单位面积单位立体角的能量),由辐射率和辐照度的定义:

L i ( l ) = d Φ d w i d A c o s θ i = d E ( l ) d w i c o s θ i \mathbf{L_i(l) = \frac{d\Phi}{dw_idAcos\theta_i} = \frac{dE(l)}{dw_icos\theta_i} } Li(l)=dwidAcosθidΦ=dwicosθidE(l)

则照射到表面来自于方向 l l l的入射光贡献的微分辐照度 (照射进来的单位时间单位面积的能量)

d E ( l ) = L i ( l ) d w i c o s θ i \mathbf{dE(l) = L_i(l)dw_icos\theta_i} dE(l)=Li(l)dwicosθi

表面反射到 v v v方向的由来自于方向 l l l的入射光贡献的微分辐射率:

d L o ( v ) = f ( l , v ) ⊗ d E ( l ) = f ( l , v ) L i ( l ) d w i c o s θ i \mathbf{dL_o(v) = f(l,v)\otimes dE(l) = f(l,v)L_i(l)dw_icos\theta_i} dLo(v)=f(l,v)dE(l)=f(l,v)Li(l)dwicosθi

符号 ⊗ \otimes 表示按向量的分量相乘,因为 f f f L i L_i Li都包含RGB三个分量。

要计算表面反射到 v v v方向的来自上半球所有方向入射光线贡献的辐射率,可以将上式对半球所有方向的光线积分:

L o ( v ) = ∫ Ω f ( l , v ) ⊗ L i ( l ) c o s θ i d w i \mathbf{L_o(v) = \int_{\Omega}f(l,v)\otimes L_i(l)cos\theta_idw_i} Lo(v)=Ωf(l,v)Li(l)cosθidwi

上式称为反射方程 (Reflectance Equation),用来计算表面反射辐射率。

对于点光源、方向光等理想化的精准光源(Punctual Light),可以认为整个场景的辐照度是一个常数,对于点光源,辐照度随距离的平方衰减,用公式 E L = Φ 4 π r 2 E_L=\frac{\Phi}{4\pi r^2} EL=4πr2Φ计算过程可以大大简化。我们考察单个精准光源照射表面,此时表面上的一点只会被来自一个方向的一条光线照射到(而面积光源照射表面时,表面上一点会被来自多个方向的多条光线照射到),则辐射率:

L o ( v ) = ∫ Ω f ( l , v ) ⊗ d E ( l ) L o ( v ) = f ( l , v ) ⊗ E L c o s θ i \mathbf{L_o(v) = \int_{\Omega}f(l,v)\otimes dE(l)}\\ \mathbf{L_o(v) = f(l,v)\otimes E_Lcos\theta_i}\\ Lo(v)=Ωf(l,v)dE(l)Lo(v)=f(l,v)ELcosθi
其中乘以 c o s θ i cos\theta_i cosθi是因为地表面的面积比虚拟表面大,辐照度就小

对于多个精准光源,只需简单累加就可以了:

L o ( v ) = ∑ k = 1 n f ( l k , v ) ⊗ E L k c o s θ i k \mathbf{L_o(v) = \sum_{k=1}^{n}f(l_k,v)\otimes E_{Lk}cos\theta_{ik}} Lo(v)=k=1nf(lk,v)ELkcosθik

回头看看反射方程,是对表面上半球所有方向的入射光线积分,这里面包含了来自精准光源的光线,也包括周围环境反射的光线。处理来自周围环境的光线可以大幅提高光照的真实程度,在实时图形学中,这部分光照可以用基于图像的光照 IBL(Image Based Lighting) 来模拟。


4.Cook-Torrance模型

Cook-Torrance BRDF兼有漫反射镜面反射两个部分:

f ( l , v ) = k d f l a m b e r t + k s f c o o k t o r r a n c e f(l,v) = k_d f_{lambert} + k_s f_{cook_torrance} f(l,v)=kdflambert+ksfcooktorrance
这里的 k d \bm{k_d} kd是早先提到过的入射光线中被折射部分的能量所占的比率,而 k s \bm{k_s} ks是被反射部分的比率

4.1 Lambertian漫反射

BRDF的左侧表示的是漫反射部分。它被称为Lambertian漫反射,这和我们之前在漫反射着色中使用的常数因子类似,用如下的公式来表示:

f l a m b e r t = c π f_{lambert} = \frac{c}{\pi} flambert=πc
c表示表面颜色(回想一下漫反射表面纹理)。除以π是为了对漫反射光进行标准化,因为前面含有BRDF的积分方程是受π影响的

4.2 镜面反射

Torrance-Sparrow基于微表面理论,建立了高光BRDF模型:

f ( l , v ) = F ( l , h ) G ( l , v ) D ( h ) 4 c o s θ i c o s θ o = F ( l , h ) G ( l , v ) D ( h ) 4 ( n ⋅ l ) ( n ⋅ v ) \mathbf{f(l,v) = \frac{F(l,h)G(l,v)D(h)}{4cos\theta_icos\theta_o}=\frac{F(l,h)G(l,v)D(h)}{4(n\cdot l)(n\cdot v)}} f(l,v)=4cosθicosθoF(l,h)G(l,v)D(h)=4(nl)(nv)F(l,h)G(l,v)D(h)

其中 n \bm n n是宏观表面法线, h \bm h h是微表面法线

下面我们介绍下Epic Games在Unreal Engine 4中所使用的函数

4.3 法线分布函数(Normal Distribution Function,简写为NDF)

4.3.1 概念

我们用法线分布函数 D ( h ) \mathbf{ D(h)} D(h)来描述组成表面一点的所有微表面的法线分布概率,现在可以这样理解:向NDF输入一个朝向 h \bm h h,NDF会返回朝向是 h \bm h h的微表面数占微表面总数的比例(虽然实际并不是这样,这点我们在讲推导过程的时候再讲),比如有1%的微表面朝向是 h \bm h h,那么就有1%的微表面可能将光线反射到[公式] v \bm v v方向。

4.3.2 D使用Trowbridge-Reitz GGX

N D F G G X T R ( n , h , a ) = a 2 π ( ( n ⋅ h ) 2 ( a 2 − 1 ) + 1 ) 2 \mathbf{NDF_{GGXTR}(n, h, a) = \frac{a^2}{\pi((n\cdot h)^2(a^2 - 1) + 1)^2}} NDFGGXTR(n,h,a)=π((nh)2(a21)+1)2a2

  • 在这里h表示用来与平面上微平面做比较用的中间向量 ( n + l ) 2 \frac{(n + l)}{2} 2(n+l)
  • a表示表面粗糙度。

如果我们把h当成是不同粗糙度参数下,平面法向量和光线方向向量之间的中间向量的话,我们可以得到如下图示的效果:

计算机图形学:PBR_第12张图片

4.3.3 Shader
float D_GGX_TR(vec3 N, vec3 H, float a)
{
    float a2     = a*a;
    float NdotH  = max(dot(N, H), 0.0);
    float NdotH2 = NdotH*NdotH;

    float nom    = a2;
    float denom  = (NdotH2 * (a2 - 1.0) + 1.0);
    denom        = PI * denom * denom;

    return nom / denom;
}

4.4 几何衰减因子(Geometrical Attenuation Factor)

4.4.1 概念

但实际上并不是所有微表面都能收到接受到光线,如下面左边的图有一部分入射光线被遮挡住,这种现象称为Shadowing。也不是所有反射光线都能到达眼睛,下面中间的图,一部分反射光线被遮挡住了,这种现象称为Masking。光线在微表面之间还会互相反射,如下面右边的图,这可能也是一部分漫射光的来源,在建模高光时忽略掉这部分光线。

计算机图形学:PBR_第13张图片

Shadowing和Masking用几何衰减因子 G ( l , v ) \mathbf{ G(l,v)} G(l,v)来建模,输入入射和出射光线方向,输出值表示光线未被遮蔽而能从 l \bm l l反射到 v \bm v v方向的比例。

4.4.2 G使用Smith’s Schlick-GGX。

几何函数从统计学上近似的求得了微平面间相互遮蔽的比率,这种相互遮蔽会损耗光线的能量。

计算机图形学:PBR_第14张图片

G S c h l i c k G G X ( n , v , k ) = n ⋅ v ( n ⋅ v ) ( 1 − k ) + k \mathbf{G_{SchlickGGX}(n, v, k) = \frac{n\cdot v}{(n\cdot v)(1-k) + k}} GSchlickGGX(n,v,k)=(nv)(1k)+knv

这里的k是α基于几何函数是针对直接光照还是针对IBL光照的重映射(Remapping) :

k d i r e c t = ( α + 1 ) 2 8   k I B L = α 2 2 \mathbf{k_{direct}=\frac{(\alpha + 1)^2}{8}}\\ \ \\ \mathbf{k_{IBL}=\frac{\alpha^2}{2}}\\ kdirect=8(α+1)2 kIBL=2α2

为了有效的估算几何部分,需要将观察方向(几何遮蔽(Geometry Obstruction))和光线方向向量(几何阴影(Geometry Shadowing))都考虑进去。我们可以使用史密斯法(Smith’s method)来把两者都纳入其中:

G ( n , v , l , k ) = G s u b ( n , v , k ) G s u b ( n , l , k ) \mathbf{G(n, v, l, k) = G_{sub}(n, v, k)G_{sub}(n, l, k)} G(n,v,l,k)=Gsub(n,v,k)Gsub(n,l,k)

使用史密斯法与Schlick-GGX作为 G s u b G_{sub} Gsub可以得到如下所示不同粗糙度的视觉效果:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LMtBObLT-1582885138714)(https://learnopengl-cn.github.io/img/07/01/geometry.png)]

几何函数是一个值域为[0.0, 1.0]的乘数,其中白色或者说1.0表示没有微平面阴影,而黑色或者说0.0则表示微平面彻底被遮蔽。

4.4.3 Shader
float GeometrySchlickGGX(float NdotV, float k)
{
    float nom   = NdotV;
    float denom = NdotV * (1.0 - k) + k;

    return nom / denom;
}

float GeometrySmith(vec3 N, vec3 V, vec3 L, float k)
{
    float NdotV = max(dot(N, V), 0.0);
    float NdotL = max(dot(N, L), 0.0);
    float ggx1 = GeometrySchlickGGX(NdotV, k);
    float ggx2 = GeometrySchlickGGX(NdotL, k);

    return ggx1 * ggx2;
}

4.5 菲涅尔方程(Fresnel Equations)

4.5.1 概念

光学平面并不会将所有光线都反射掉,而是一部分被反射,一部分被折射,反射比例符合菲涅尔方程 F ( l , h ) \mathbf{ F(l,h)} F(l,h)

image

如果你站在湖边,低头看脚下的水,你会发现水是透明的,反射不是特别强烈,如果你看远处的湖面,你会发现水并不透明,这说明反射非常强烈。这就是“菲涅尔效应”。

当视线垂直于表面时,反射较弱,折射越强,而当视线非垂直表面时,夹角越小(越平行于表面),反射越明显,折射越弱。

4.5.2 F使用Fresnel-Schlick近似(Fresnel-Schlick Approximation)

菲涅尔方程是一个相当复杂的方程式,不过幸运的是菲涅尔方程可以用Fresnel-Schlick近似法求得近似解:

F S c h l i c k ( h , v , F 0 ) = F 0 + ( 1 − F 0 ) ( 1 − ( h ⋅ v ) ) 5 \mathbf{F_{Schlick}(h, v, F_0) = F_0 + (1 - F_0)(1 - (h\cdot v))^5} FSchlick(h,v,F0)=F0+(1F0)(1(hv))5

F 0 F_0 F0表示平面的基础反射率,它是利用所谓 折射指数IOR(Indices of Refraction) 计算得出的。然后正如你可以从球体表面看到的那样,我们越是朝球面掠角的方向上看(此时视线和表面法线的夹角接近90度)菲涅尔现象就越明显,反光就越强:

计算机图形学:PBR_第15张图片

菲涅尔方程还存在一些细微的问题。其中一个问题是Fresnel-Schlick近似仅仅对电介质或者说非金属表面有定义。对于导体(Conductor)表面(金属),使用它们的折射指数计算基础折射率并不能得出正确的结果,这样我们就需要使用一种不同的菲涅尔方程来对导体表面进行计算。由于这样很不方便,所以我们预先计算出平面对于法向入射( F 0 F_0 F0)的反应(处于0度角,好像直接看向表面一样)然后基于相应观察角的Fresnel-Schlick近似对这个值进行插值,用这种方法来进行进一步的估算。这样我们就能对金属和非金属材质使用同一个公式了。

通过预先计算电介质与导体的F0值,我们可以对两种类型的表面使用相同的Fresnel-Schlick近似,但是如果是金属表面的话就需要对基础反射率添加色彩。我们一般是按下面这个样子来实现的:

4.5.3 Shader
vec3 F0 = vec3(0.04);
F0      = mix(F0, surfaceColor.rgb, metalness);

我们为大多数电介质表面定义了一个近似的基础反射率。F0取最常见的电解质表面的平均值,这又是一个近似值。不过对于大多数电介质表面而言使用0.04作为基础反射率已经足够好了,而且可以在不需要输入额外表面参数的情况下得到物理可信的结果。然后,基于金属表面特性,我们要么使用电介质的基础反射率要么就使用 F 0 F_0 F0来作为表面颜色。因为金属表面会吸收所有折射光线而没有漫反射,所以我们可以直接使用表面颜色纹理来作为它们的基础反射率。

Fresnel Schlick近似可以用代码表示为:

vec3 fresnelSchlick(float cosTheta, vec3 F0)
{
    return F0 + (1.0 - F0) * pow(1.0 - cosTheta, 5.0);
}

其中cosTheta是表面法向量n与观察方向v的点乘的结果。

4.6 Cook-Torrance反射率方程

随着Cook-Torrance BRDF中所有元素都介绍完毕,我们现在可以将基于物理的BRDF纳入到最终的反射率方程当中去了:

L o ( v ) = ∫ Ω ( k d c π + k s D F G 4 ( n ⋅ v ) ( n ⋅ l ) ) L i ( l ) ( n ⋅ l ) d w i \mathbf{L_o( v) = \int_{\Omega}^{}(k_d\frac{c}{\pi} + k_s\frac{DFG}{4(n\cdot v)(n\cdot l)})L_i(l)(n\cdot l) \mathrm{d}w_i} Lo(v)=Ω(kdπc+ks4(nv)(nl)DFG)Li(l)(nl)dwi
这个方程现在完整的描述了一个基于物理的渲染模型,它现在可以认为就是我们一般意义上理解的基于物理的渲染也就是PBR

5. PBR材质

在了解了PBR后面的数学模型之后,最后我们将通过说明美术师一般是如何编写一个我们可以直接输入PBR的平面物理属性的来结束这部分的讨论。PBR渲染管线所需要的每一个表面参数都可以用纹理来定义或者建模。使用纹理可以让我们逐个片段的来控制每个表面上特定的点对于光线是如何响应的:不论那个点是金属的,粗糙或者平滑,也不论表面对于不同波长的光会有如何的反应。

在下面你可以看到在一个PBR渲染管线当中经常会碰到的纹理列表,还有将它们输入PBR渲染器所能得到的相应的视觉输出:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-olw5P2iL-1582885138715)(https://learnopengl-cn.github.io/img/07/01/textures.png)]

  • 反照率(Albedo)纹理: 为每一个金属的纹素(Texel)(纹理像素)指定表面颜色或者基础反射率。这和我们之前使用过的漫反射纹理相当类似,不同的是所有光照信息都是由一个纹理中提取的。漫反射纹理的图像当中常常包含一些细小的阴影或者深色的裂纹,而反照率纹理中是不会有这些东西的。它应该只包含表面的颜色(或者折射吸收系数)。
  • 法线: 法线贴图使我们可以逐片段的指定独特的法线,来为表面制造出起伏不平的假象。
  • 金属(Metallic)贴图: 逐个纹素的指定该纹素是不是金属质地的。根据PBR引擎设置的不同,美术师们既可以将金属度编写为灰度值又可以编写为1或0这样的二元值。
  • 粗糙度(Roughness): 粗糙度贴图可以以纹素为单位指定某个表面有多粗糙。采样得来的粗糙度数值会影响一个表面的微平面统计学上的取向度。一个比较粗糙的表面会得到更宽阔更模糊的镜面反射(高光),而一个比较光滑的表面则会得到集中而清晰的镜面反射。某些PBR引擎预设采用的是对某些美术师来说更加直观的光滑度(Smoothness)贴图而非粗糙度贴图,不过这些数值在采样之时就马上用(1.0 – 光滑度)转换成了粗糙度。
  • AO环境光遮蔽(Ambient Occlusion)贴图: AO贴图为表面和周围潜在的几何图形指定了一个额外的阴影因子。比如如果我们有一个砖块表面,反照率纹理上的砖块裂缝部分应该没有任何阴影信息。然而AO贴图则会把那些光线较难逃逸出来的暗色边缘指定出来。在光照的结尾阶段引入环境遮蔽可以明显的提升你场景的视觉效果。网格/表面的环境遮蔽贴图要么通过手动生成,要么由3D建模软件自动生成。

美术师们可以在纹素级别设置或调整这些基于物理的输入值,还可以以现实世界材料的表面物理性质来建立他们的材质数据。这是PBR渲染管线最大的优势之一,因为不论环境或者光照的设置如何改变这些表面的性质是不会改变的,这使得美术师们可以更便捷的获取物理可信的结果。在PBR渲染管线中编写的表面可以非常方便的在不同的PBR渲染引擎间共享使用,不论处于何种环境中它们看上去都会是正确的,因此看上去也会更自然。

主要参考以下文档

  • 基于物理着色:BRDF
  • LearnOpenGL:PBR

你可能感兴趣的:(计算机图形学)