games101 五、材质
漫反射材质
Diffuse / Lambertian Material
对于漫反射材质,我们认为一束入射光线会向四面八方反射,根据前面所学内容,其中某一束反射光和入射光能量存在一个比例 \(f_r\),在光线追踪中,我们将其称为 brdf。

光线追踪的渲染方程体现出一种入射光和反射光的能量关系,一束出射光 \(L_o(\omega_o)\) 是所有入射光 \(L_i(\omega_i)\) 经过材质反射后的总和(注意,这里所说的出射光不是某个入射光的反射分量,而是所有入射光的积分总和):
假设入射光和反射光都是均匀的,这意味着 \(L_i(\omega_i)\) 和 \(f_r\) 都是常数,那么上式可以简化为:
当一束入射光能量和反射光能量相等时,意味着入射光和出射光能量守恒,材质完全不吸收能量,即,
我们可以定义一个反射率 \(\rho\)(albedo),范围为 0~1,体现材质反射多少光,\(\rho=1\) 表示完全反射,\(\rho=0\) 表示完全吸收,那么,最终的漫反射 brdf 定义为:
如果 \(\rho\) 是一个三通道的颜色值(三个 0~1 范围内的值),则可以定义不同颜色的 brdf,这就是漫反射材质的定义。
漫反射材质渲染出的颜色可以看作是物体的本色。
光泽材质
Glossy Material
不完全是镜面反射,也不完全是漫反射,比如一个磨砂的金属表面。
理想反射材质
Ideal Reflective Material(BSDF)
这是指水面或者玻璃这种既能反射又能折射的材质。
完美镜面反射
Perfect Specular Reflection
令 入射光 \(\omega_i\)、出射光 \(\omega_o\)、法线 \(\mathbf{n}\) 都以表面上的一点为原点指向空中,入射角为 \(\theta_i\),出射角为 \(\theta_o\),它们满足以下关系:
如果从上往下看,入射光和出射光分别有一个方位角 \(\phi_i\) 和 \(\phi_o\),它们满足:

镜面折射
Specular Refraction
斯涅尔定律:

其中 \(\eta_i\) 和 \(\eta_t\) 分别是入射介质和折射介质的折射率,\(\theta_i\) 和 \(\theta_t\) 分别是入射角和折射角。
常见介质的折射率:
| 介质 | 折射率 \(\eta\) |
|---|---|
| 真空 | 1.0 |
| 空气(海平面) | 1.00029 |
| 水(20°C) | 1.333 |
| 玻璃 | 1.5–1.6 |
| 金刚石 | 2.42 |
从公式和图像上可以看出来,如果折射率更大的那一侧的角度大于一个临界值,是没有折射光的,这就是全反射现象。
斯涅尔窗效应:

前面讲到的光线追踪的 BRDF 函数,对折射来讲应该叫 BTDF,二者合起来叫 BSDF(双向散射分布函数)。
菲涅尔反射
Fresnel Reflection
一束入射光线会有一部分光线被反射,另一部分光线被折射,入射角越大,反射的光线越多,折射的光线越少,这就是菲涅尔反射现象。

不同材质的菲涅尔现象差距很大,准确的反射率计算公式非常复杂,通常我们会用一个近似的计算方法,叫做 Schlick 近似:
其中 \(n_1\) 和 \(n_2\) 分别是入射介质和折射介质的折射率,\(\theta\) 是入射角。
\(R_0\) 表示入射角为 0 时的反射率,\(R(\theta)\) 表示入射角为 \(\theta\) 时的反射率。
微表面理论
Microfacet Theory
一个凹凸不平的表面,从远处看(Macroscale),看起来是个粗糙的平面,但从近处看(Microscale),它是由很多小的平面组成的,每个小平面都可以看成是一个完美的镜面反射表面,这些小平面叫做微表面(Microfacet)。
简单来说,离近了看,看到的是一个复杂的几何结构,离远了看,看到的是一整个平面或者一种材质。
根据这个理论,可以将不同的材质看作是不同的法线分布,比如漫反射材质(Diffuse Material)可以看作是一个法线方向比较分散的材质,而光泽材质(Glossy Material)可以看作是一个法线方向比较集中的材质。
有了这个理论,我们可以将 BRDF 中的反射比例 \(f_r\) 写成更具体的形式:

\(F\) 是菲涅尔项,代表平面的反射率,\(D\) 是微表面的法线分布,只有当微表面的法线方向和半程向量方向一致时,才会有反射,法线分布描述的是微表面法线方向和半程向量方向一致的概率, \(G\) 代表微表面之间的相互遮挡程度。
各向同性/各向异性材质
Isotropic/Anisotropic Material
各向同性:微表面没有明显的方向性,比如一个磨砂的金属表面。
各项异性:微表面有明显的方向性,比如一个拉丝的金属表面。
对于各项异性表面,入射光线的方位角变换, \(f_r\) 也会随之变化。
BRDF 的性质
非负:\(f_r(\omega_i, \omega_o) \geq 0\)
线性:一个点的着色结果可以拆成多个部分单独计算,最后再加起来。
可逆:如果入射光线和出射光线交换位置,BRDF 的值不变,即 \(f_r(\omega_i, \omega_o) = f_r(\omega_o, \omega_i)\)。
能量守恒:对于任何入射光线 \(\omega_i\),所有出射光线 \(\omega_o\) 的反射比例之和不能超过 1。
各项异性和各向同性:对于各向同性材质,BRDF 的值只与入射光线和出射光线的相对方位角有关;对于各项异性材质,BRDF 的值还与绝对方位角有关。
测量 BRDF
现实中有一种材质,我们希望知道渲染这种材质时应该使用什么样的 BRDF,这时我们就需要测量这个材质的 BRDF。
一种方法是使用一个光源和一个相机,分别放在不同的位置,测量入射光线和出射光线的能量,然后根据 BRDF 的定义计算出 BRDF 的值。
MERL BRDF 数据库:一个公开的 BRDF 数据库,里面包含了很多不同材质的 BRDF 数据,可以用来渲染这些材质。
其他光线追踪方法
无偏和有偏蒙特卡洛估计
无偏(Unbiased)就是指估计的期望值等于真实值,有偏(Biased)就是指估计的期望值不等于真实值,如果有偏估计的样本值足够多,使得估计值足够接近真实值,这时叫做一致的有偏估计(Consistent)。
双向路径追踪(BDPT)
Bidirectional Path Tracing.
核心思路是分别从光源和相机出发,生成两条光线路径,最后将两条路径连接起来,形成一条完整的光线路径,这样可以更高效地采样到一些重要的路径,比如直接从光源到相机的路径。
实现困难并且计算量很大。
Metropolis 光线传播
Metropolis Light Transport.
这时另外一种光线追踪方法,叫做 Metropolis 光线传播。
Metropolis 光线传播利用了马尔科夫链蒙特卡洛方法(MCMC)进行采样,这个方法可以以任意形状的概率密度函数进行采样,之前在蒙特卡洛方法中提到过,蒙特卡洛方法的效果很大程度上取决于采样的概率密度函数,概率密度函数和被积函数的形状越接近,效果越好,而马尔科夫链能生成任意形状的概率密度函数。
Metropolis 光线传播的核心思路是,首先生成一条光线路径,然后在这条路径的基础上进行一些小的变动,生成一条新的路径,如果新的路径比旧的路径更重要(比如说它的贡献更大),就接受这条新路径,否则就拒绝这条新路径,继续使用旧的路径,这样就形成了一个马尔科夫链,最终可以得到一个很好的采样结果。
收敛速度不确定,上一帧和下一帧的结果可能差距很大。
光子映射
Photon Mapping.
是一种有偏估计。
适合处理镜面-漫反射-镜面这种渲染路径,适合渲染caustics(焦散)效果。
Vertex Connection and Merging
双向路径追踪和光子映射的结合。
实时辐射度算法
Instant Radiosity(IR).
光源发出的光线照射到物体表面后,会在表面上形成一个虚拟的点光源,叫做虚拟点光源(Virtual Point Light,VPL),这些虚拟点光源可以用来近似地计算间接照明,从而实现实时渲染。
外观建模
外观建模(Appearance Modeling)是指如何通过一些参数来描述一个材质的外观,这些参数可以是颜色、粗糙度、金属度等等,这些参数会改变 BRDF 函数形状,从而控制材质的外观。
非表面材质模型
散射介质
Participanting Media
云、雾等非表面材质,光线进去以后会被吸收和散射。
头发
Hair appearance model.
Kajiya-Kay 模型:一种简单的头发渲染模型,效果不太好。
Marschner 模型:一种更复杂的头发渲染模型,可以非常逼真地模拟头发的光学特性。
动物毛发
Fur appearance model.
Double Cylinder 模型。
颗粒材质
Granular Material
一粒一粒的材质,比如一堆小米、一堆绿豆、一堆沙子等等。
表面材质模型
透射材质
Translucent Material
和半透明不太一样,光线在材质内部会发生散射,这种材质是指会透光的材质,例如玉石。
次表面散射(Subsurface Scattering)模型:一种模拟透射材质的渲染模型,把 BRDF 扩展为了 BSSRDF,可以更逼真地模拟透射材质的光学特性,计算量较大。
Dipole Approximation:一种次表面散射模型的近似方法,可以更高效地计算次表面散射效果。
BSSRDF 方法可以把人脸渲染得非常逼真。
布料
布料渲染大概有三种方法:
- 将布料看作是一个表面,直接测量布料的 BRDF,然后用这个 BRDF 来渲染布料。
- 将布料看作是一个体积,光在布料内部发生散射,然后用体积渲染的方法来渲染布料。
- 将布料看作是由很多细小的纤维组成的,像渲染头发一样一根一根渲染布料上的纤维。
细节渲染
一个现实中存在的复杂场景,经常会因为渲染的过于完美而显得不真实,现实中的物体表面通常会有一些细微的瑕疵,这些瑕疵会让渲染出来的物体看起来更真实。
使用微表面理论来模拟这些细节,比如使用一个法线贴图(Normal Map)来模拟表面的细节,这样可以让渲染出来的物体看起来更真实。
再比如,一个白色的磨砂金属表面,放大仔细看,会发现表面上实际上是各种颜色,这涉及到了波动光学的知识。
程序化生成
Procedural Appearance.
物体的表面材质是通过一些3D noise 函数生成出来的。
比如花瓶上的花纹,木头的纹理等等,这些都是通过一些3D noise 函数生成出来的。