实时渲染笔记:从光度学到PBR
这是笔者多年以来一直都在完善的实时渲染基础笔记,放出来给大家分享。
光度学与辐射度量学
光度学与辐射度量学是研究光与电磁辐射测量的姊妹学科。光度学(photometry)基于人眼的视觉响应特性,量化可见光的感知强度;辐射度量学(radiometry)则从物理角度客观测量电磁辐射能量,覆盖全波段(含不可见光)。两者在单位体系上存在严格对应关系,差异源于是否考虑人眼的光谱灵敏度。
光度学
光通量(luminous flux)\(\Phi\) 的国际单位是流明(lumen,lm),但它不是国际单位制的基本单位。光通量是考虑了人眼因素后的光的功率,因此某种意义上,与功率 \(\text{W}\) 的量纲可类比。
举例而言,1W 的 555nm 的绿光,1W 的 632.8nm 的红光和 1W 的 2000nm 的红外光,能量相同为 1W,但光通量不同:绿光是 1 流明,红光介于 0 到 1 流明之间,红外则是 0。具体的换算将涉及到光度函数 \(V(\lambda)\),这里不再赘述。
发光强度(luminous intensity)\(I\) 的国际单位(SI)是坎德拉(candela,cd;旧译烛光),它是国际单位制的基本单位之一,满足
\[ \text{cd} = \frac{\text{lm}}{\text{sr}} \]
其中 \(\text{sr} = \text{rad}^2\) 为立体角微元
\[ \mathrm d \omega = \frac{\mathrm dA}{R^2} = \frac{R^2 \sin \theta \mathrm d \theta \mathrm d \varphi}{R^2} = \sin \theta \mathrm d \theta \mathrm d \varphi \]
的量纲。
亮度(luminance)\(L\) 的国际单位是尼特(nit,nt),满足
\[ \text{nt} = \frac{\text{lm}}{\text{sr} \cdot \text{m}^2} \]
亮度对点光源是无效的,因为点光源的面积为 \(0\),因此该值会是无穷大。
此外还有照度或光照强度(illuminance)\(E\),国际单位是勒克斯(lux,lx)
\[ \text{lx} = \frac{\text{lm}}{\text{m}^2} \]
值得注意的是,照度 \(E\) 是定义在被光照的物体表面的,而非与其他光度学单位一样定义在光源表面。因此,一般不说面光源的强度单位是几勒克斯,而是说流明每平方米,尽管它们在量纲上完全一致。如果要用这一说法表达面光源的强度,它的物理量的名称是光度(luminosity),尽管有的领域并不把光度(luminosity)当作一个物理量。
游戏引擎中,方向光的强度单位是 lx,因为其很难定义功率,只能从被照射物体上间接定义。注意这里的方向光的“每平方米”是被照射物体的面积,而非光源的面积。
点光源的强度单位一般是 lm(总量)或 cd(某个方向),两者之间的转换公式(仅对点光源成立)为
\[ 1 \ \text{lm} = 4 \pi \ \text{cd}. \]
面光源的强度单位一般是 nit,该描述的隐含方向为光源的法线方向:如果一个正方形面光源的亮度为 1 nit,则无论光源面积多大,其每平方米表面在法线方向上发出的光强度为 1 cd 或 1 lm。等价地,有时,面光源的强度单位可能也用流明每平方米(或者直接用流明)描述,注意这里的“每平方米”是光源的面积而非被照射物体的面积。
- 如果游戏引擎用点光源模拟面光源(如 UE 的矩形光源),则有可能用 cd 描述其强度。
辐射度量学
在辐射度量学中,不考虑光度学这一套人眼因素的映射,直接使用功率体系。
- 光通量对应辐射通量(radiance flux)或功率
- 发光强度对应辐射强度(radiance intensity)
- 亮度对应辐射度或辐射率(radiance)
- 照度对应辐照度(irradiance)
- 光度对应辐光度(radiocity)
- 有时 radiocity 会被翻译成“辐射度”。这不是一个好的翻译,因为容易与 radiance 混淆。
辐射度(radiance)的量纲为
\[ L = \left[ \frac{\text{W}}{\text{sr} \cdot \text{m}^2} \right] \]
仅对点光源而言,其能量遵循平方反比定律,即
\[ L = \frac{I}{r^2}. \]
渲染与渲染方程
渲染的输入是场景(包括空间中的物体、光照等)和摄像机位置和角度,输出是基于该摄像机看向场景的图像。
大概在 1986 年,David Immel et al. 和 James Kajiya 基于物理原理,同时独立提出了渲染方程的概念,从此基于物理的渲染问题成为了一个严谨的数学问题。
方程
定义
\[ (\boldsymbol x_1 \cdot \boldsymbol x_2)_+ = \max(\boldsymbol x_1 \cdot \boldsymbol x_2, 0). \]
为正半球点乘。那么 BRDF 下的渲染方程,或反射方程为
\[ L_o(\boldsymbol x, \boldsymbol \omega_o) = L_e(\boldsymbol x, \boldsymbol \omega_o) + \int_{\Omega} L_i(\boldsymbol x, \boldsymbol \omega_i) f_r(\boldsymbol x, \boldsymbol \omega_o, \boldsymbol \omega_i) (\boldsymbol \omega_i \cdot \boldsymbol n)_{+} \, \mathrm d \boldsymbol \omega_i. \]
其中:
- \(L_o, L_e, L_i\) 分别为出射辐射度、表面自发光辐射度和入射辐射度
- \(f_r\) 为双向反射分布函数(BRDF),一般物体的实时渲染中通常只考虑纯反射。如果要考虑更一般的渲染方程,则需要使用双向光路分布函数(BXDF)
- \(\boldsymbol \omega_o, \boldsymbol \omega_i\) 分别为表面半球上的出射方向和入射方向
- \(\boldsymbol \omega_i \cdot \boldsymbol n\) 为 Lambert 余弦修正量。考虑光源方向越垂直,表面能量接收越多,且光均匀地反射,因此与观察者位置无关,故这里不使用 \(\boldsymbol \omega_o \cdot \boldsymbol n\)
镜面反射中的角度近似
记 \(\boldsymbol \omega_h = \frac{\boldsymbol \omega_i + \boldsymbol \omega_r}{||\boldsymbol \omega_i + \boldsymbol \omega_r||}\) 为 \(\boldsymbol \omega_i\) 和 \(\boldsymbol \omega_r\) 决定的半程向量。
通常地,一定有
\[ (\boldsymbol \omega_i \cdot \boldsymbol \omega_h)_+ = (\boldsymbol \omega_r \cdot \boldsymbol \omega_h)_+. \]
如果认为,在计算时 \(\boldsymbol \omega_o\) 总是位于镜面反射角附近(可能是因为这个 BRDF 模型只在镜面反射部分有支撑集),那么 \(\boldsymbol \omega_h \approx \boldsymbol n\),故
\[ (\boldsymbol \omega_i \cdot \boldsymbol \omega_h)_+ = (\boldsymbol \omega_r \cdot \boldsymbol \omega_h)_+ \approx (\boldsymbol \omega_i \cdot \boldsymbol n)_+ \approx (\boldsymbol \omega_r \cdot \boldsymbol n)_+ = \cos \theta \]
因此,有时会使用 \(\cos \theta\) 表示这些角度,Fresnel Schlick 近似也通常写成 \(\cos \theta\)。
在 IBL 中,通常可以用 \((\boldsymbol \omega_r \cdot \boldsymbol n)_+ = \cos \theta\) 采样 BRDF LUT 的横轴。这一 LUT 的其中一种构建方法是:假设法线为 \(\boldsymbol n = (0,0,1)\),因此可以用 \(\cos \theta\) 还原 \(\boldsymbol \omega_r\),最后对 BRDF 进行重要性采样还原 \(\boldsymbol \omega_h\) 和 \(\boldsymbol \omega_i\)。
BRDF 与材质
在视角固定之下的渲染过程只与光源信息、几何信息和物体的材质信息有关系。显然,渲染方程中的 \(f_r\) 恰好就是材质信息。如何取得一个近似的,易于计算的 \(f_r\),一直以来是实时渲染领域中的难题之一。
一般的单波长光传播函数与 BSSRDF
一般的单波长电磁波传播函数 \(f(\boldsymbol x_i, \boldsymbol x_o, \boldsymbol \omega_i, \boldsymbol \omega_o)\) 的参数包括入射点 \(\boldsymbol x_i\),出射点 \(\boldsymbol x_o\),入射角度 \(\boldsymbol \omega_i\) 和出射角度 \(\boldsymbol \omega_o\),其中 \(\boldsymbol x\) 是一个在物体表面的 uv 上变化的二维坐标,\(\boldsymbol \omega\) 代表一个半球面上的方向,可用球坐标系的两个分量描述,因此整体可以看作是一个八维函数。
BSSRDF 的参数列表与这个函数相同,它们都考虑了完整的模型次表面光路。
SVBXDF 与 BXDF
显然,八维函数的计算压力是很大的。如果近似认为,光线总是在同一点入射后出射,能量不会传播到其他点,那么 Spatial-Varying (SV) BXDF \(f(\boldsymbol x, \boldsymbol \omega_o, \boldsymbol \omega_i)\) 是一个六维函数,可直接用来描述该物体表面材质的变化信息。
如果我们不考虑材质在空间中的变化,那么 BXDF 就只具有两个输入:入射角度和出射角度。这样的 BXDF \(f(\boldsymbol \omega_o, \boldsymbol \omega_i)\) 可以看成是一个四维函数,可能包含多重散射,因此 BTDF、BSDF、BRDF 都可以是 BXDF 的组成部分(但 BSSRDF 不是)。它的定义式是
\[ f(\boldsymbol \omega_o, \boldsymbol \omega_i) = \frac{\text{Radiance outgoing}}{\text{Irradiance incoming}} = \frac{\mathrm d L_o(\boldsymbol \omega_r)}{\mathrm d E_i(\boldsymbol \omega_i)} = \frac{\mathrm d L_o(\boldsymbol \omega_o)}{L_i(\boldsymbol \omega_i) \cos \boldsymbol \omega_i \, \mathrm d \boldsymbol\omega_i} \]
BXDF 的量纲是
\[ f = \left[ \frac{1}{\text{sr}} \right] \]
这可以由 \(\mathrm d \boldsymbol \omega_i\) 的量纲为 \(\text{sr}\) 直接推出。它的含义是:BXDF 是单位立体角上光的传播比例。
BRDF
在只考虑纯反射的近似下,实时渲染中的 BXDF 都是 BRDF。BRDF 应当具有 BXDF 的以上性质,且如果它需要符合物理意义,那它就必须遵守光路可逆性,即
\[ f_r(\boldsymbol x, \boldsymbol \omega_o, \boldsymbol \omega_i) = f_r(\boldsymbol x, \boldsymbol \omega_i, \boldsymbol \omega_o) \]
以及能量守恒性,即
\[ \int_{\Omega} f_r(\boldsymbol x, \boldsymbol \omega_o, \boldsymbol \omega_i) (\boldsymbol \omega_i \cdot \boldsymbol n)_{+} \, \mathrm d \boldsymbol \omega_i \leq 1. \]
PBR 的 BRDF 都具有这些性质(使用半程向量代替反射向量计算会破坏性质,但仍近似具有性质),但很多经验光照模型如 Blinn-Phong,以及 NPR 的 BRDF 并不具有这些性质。
纹理
最后,我们知道,现实生活中的物体材质其实并不均匀。因此,我们需要考虑同一物体的材质在空间中的变化。我们可以使用二维纹理来存储这一系列的变化,然后在运行时采样这一纹理贴图,获取相应的材质信息。
在其他领域中,“材质”和“纹理”可能会有一些其他的解释方式:
- 纹理可用于材质,也可用于其他光照、深度表达和物理仿真等,如法线纹理、阴影映射、三维空间中的 SDF。
- 图形 API 如 OpenGL 中的纹理,基本上是一个可采样的高维数组,因此帧缓冲也可以看作是“纹理”。图形 API 一般不会主动抽象“材质”。
- UE5 里的材质是一个可编程的,计算光照时会调用的对象,而纹理则是一个图片。材质可以索引纹理,也可以完全由计算节点产生(程序化纹理)。
最后,我们可以给实时渲染中参与光照计算的材质下个定义:材质信息是物体表面存储的,与渲染有关的信息,包含 BRDF 模型信息和纹理信息。值得一提的是,法线贴图、flowmap 等等虽然也是纹理,但并不是本文讨论的“参与光照计算的”纹理。
解析的 BRDF
直接使用四维或六维的查找表存放 BRDF ,在实时渲染中通常不具备可行性。因此,实时渲染中通常使用解析模型进行逼近。此时,我们只需要存储几个有限的参数,参数 \(\boldsymbol \omega_i, \boldsymbol \omega_r\) 会直接参与计算,所以这样解析的 BRDF 是一个存储上“零维”的函数。
由于解析的 BRDF 是 0D 的,所以只需一系列二维纹理(albedo, matallic, normal 等)即可表达物体表面。因此,这样的 SVBRDF 在存储上是 2D 的。
(Blinn-) Phong 模型
(Blinn-) Phong 模型可以说是最经典非物理的 BRDF 模型之一,它计算简洁,效果合理,至今仍在硬件性能不高的实时渲染应用中得到广泛应用。
严谨地说,由于 ambient 项的存在,这一模型实际上是对渲染方程做了近似,而非对 BRDF 做了近似。
但如果认为全局的 ambient 项近似等价于从积分中获取间接光照,可以认为,Blinn-Phong 模型就是 Lambert 漫反射模型 + Blinn-Phong 高光模型。
PBR:Albedo-metallic 工作流
经过工业界和学术界的共同探索,基于物理的渲染(PBR)成为了十几年来次世代渲染模型的代名词,在无数影视和游戏作品中大放异彩。Albedo-metallic 工作流是 PBR 的代表模型,即运用微表面模型的光照模型的代表。这一工作流的 BRDF 为
\[ f_r(\boldsymbol \omega_i, \boldsymbol \omega_r) = (1-m) af_d(\boldsymbol \omega_i, \boldsymbol \omega_r) + ((1-m)F_0 + ma)f_s(\boldsymbol \omega_i, \boldsymbol \omega_r) \]
其中:
- \(a \in [0,1]^3\) 为 base color。它与 Albedo Specular 工作流中的 diffuse 有细微差别。
- \(m \in [0,1]\) 为 metallic,\(k_d = 1 - m\)。
- \(F_0 \in [0,1]\)
为法线方向反射度,即 0
度入射(垂直入射)时的菲涅尔反射率。对电介质,一般取 \(F_0 = R = 0.04 = \left| \frac{n_1 - n_2}{n_1 +
n_2} \right |^2\),其中 \(n_1 = 1.5,
n_2 = 1.0\) 为介质折射率,此时 \(F_0\)
为单分量标量。对金属(导体),其折射率为复数,不能用上式计算 \(F_0\),一般不使用物理正确的 \(F_0\),详见下文“菲涅尔项”。
- 有时,美术可能希望控制非金属的 \(F_0\),UE 提供了 specular 用于控制该参数。因此,UE 中可能会同时出现 metallic 和 specular 贴图,但 specular 贴图只在 \(m < 1\) 时有效,此时 \(F_0\) 不再是 \(0.04\) 或其他单分量标量,而是 specular 贴图存储的数据(三分量标量)。
- \(k_s = \text{lerp}(F_0, a, m) = (1-m)F_0
+ ma\)。如果 \(m < 1\),一般
\(F_0 = 0.04\) 或由 specular 决定(在
UE 中,specular = \(\text{saturate}(\frac{F_0}{0.08})\),因此默认
specular = 0.5 对应 \(F_0=0.04\))。
- 有时,为了让美术达到效果,在某些材质中,可能会为镜面反射项乘上 specular tint(高光染色)这个参数,而不是 \(\text{lerp}(F_0, a, m)\),这类似于仅在镜面反射部分有效的 base color。
- \(f_d\) 为漫反射(diffuse)分量,通常为 Lambert 模型。
- \(f_s\) 为镜面反射(specular)分量,通常为微表面模型。
PS:
- Albedo Metallic 工作流中的 base color 和 Albedo Specular 工作流中的 diffuse 都可以叫 albedo。
- Albedo Metallic 工作流中,不止漫反射,镜面反射也与 albedo (base color) 有关。Albedo Specular 工作流中,镜面反射与 albedo (diffuse) 无关。
- Albedo Metallic 工作流中,对混合材质,其 base color 贴图中会额外存储其 \(F_0\) 贴图(总计四通道,但可以“压缩”到三通道)。Albedo Specular 工作流中,specular 贴图就是 \(F_0\) 贴图(三通道)。
- 在 UE 中,为节省空间,可能会合并多个单通道贴图至一个多通道贴图。
解析的漫反射 BRDF
Lambert 模型
\[ f_d(\boldsymbol \omega_i, \boldsymbol \omega_r) = \frac{1}{\pi}, \]
由于 Lambert 模型过于简单,与 \(\boldsymbol \omega_i, \boldsymbol \omega_r\) 均无关,因此也有 Disney 改进的漫反射模型(并不能量守恒),考虑了表面的粗糙度,其与 \(\boldsymbol \omega_i, \boldsymbol \omega_r\) 的余弦有关。Frostbite 引擎中的漫反射可选用 Disney 改进的漫反射模型。
Lambert 模型中,漫反射与粗糙度(微表面法线偏离宏表面法线的程度)没有关系。这是因为,漫反射的原理是:光进入物体被吸收,光线在内部“随机”地继续向内被吸收或向外反射出去。在 Lambert 的假设下,由于经历了多次弹射,这些向外反射的方向宏观上是均匀的,故产生了全向的漫反射,不需要考虑表面的粗糙度。但在现实物理中,漫反射会与表面粗糙度有关,因此可以运用微表面模型进行更复杂的建模(尽管在实时渲染中一般用不到)。
对于金属 \(m = 1\) 的情形,没有漫反射,可以理解为此时金属全部吸收了非 base color 的光线,没有在内部经过多次弹射再从其他角度反射出去,而 base color 的光线则全都镜面反射出去了。
Half Lambert 模型
这是《半条命》的光照模型,让暗面也有亮度的变化。它没有物理依据,但能带来提亮的视觉效果,也常用于 NPR 中。
\[ f_d(\boldsymbol \omega_i, \boldsymbol \omega_r) = \frac{\alpha(\boldsymbol \omega_i \cdot \boldsymbol n) + \beta}{\pi (\boldsymbol \omega_i \cdot \boldsymbol n)_{+}}, \]
其中 \(\alpha\) 和 \(\beta\) 为可调节的参数。注意分子的点积可以为负值。对于背光面,\(\boldsymbol \omega_i \cdot \boldsymbol n < 0\),一般取 \(\alpha = \beta = 1/2\),如此即可将分子结果映射到 \([0,1]\),同时让暗面具有亮度变化。
分母的 \((\boldsymbol \omega_i \cdot \boldsymbol n)_{+}\) 是为了抵消渲染方程积分项中的那一项而存在的。
其他漫反射模型
漫反射也可以用微表面模型建模,但那大概是离线渲染才会考虑的内容,此处不再赘述。
解析的镜面反射 BRDF
完全镜面反射模型
如果镜面反射仅发生在 \(\text{reflect}(\boldsymbol \omega_i)\) 这个方向上,那么 BRDF 形如冲激函数
\[ f_s(\boldsymbol \omega_i, \boldsymbol \omega_r) = \frac{\delta(\boldsymbol \omega_r - \text{reflect}(\boldsymbol \omega_i))}{K} \]
其中 \(K\) 是用于归一化的校正因子,满足 \(K = (\boldsymbol \omega_i \cdot \boldsymbol n)_{+}\),因为渲染方程积分项里面有这个,但镜面反射不考虑 Lambert 修正量,所以要抵消它。
Phong 高光模型
这是一个古老的 Specular BRDF:
\[ f_s(\boldsymbol \omega_i, \boldsymbol \omega_r) = \frac{(\boldsymbol \omega_r \cdot \text{reflect}(\boldsymbol \omega_i))_{+}^{\alpha}}{K} \]
其中
- \(K\) 的意义同上
- \(\alpha\) 为光泽度,值越大高光越明显。但较大的 \(\alpha\) 并不会让材质显得光泽,反而会很假
Blinn-Phong / Kajiya-Kay 高光模型
这是一个在 Phong 的基础上改进的,古老的 Specular BRDF:
\[ f_s(\boldsymbol \omega_i, \boldsymbol \omega_r) = \frac{(\boldsymbol \omega_h \cdot \boldsymbol n)_{+}^{\alpha}}{K} \]
\(K\) 和 \(\alpha\) 的意义同上。
半程向量常与 \(\boldsymbol n\) 做点积,该结果越大,则此处的微表面呈现高光(镜面反射)越明显。
https://zhuanlan.zhihu.com/p/135910659
(Blinn-) Phong 和 Kajiya-Kay 其实是同一个光照模型,只不过前者用于一般物体表面(正半球)上,后者用于毛发表面(微圆柱的一个截面)上,因此后者会用圆柱的走向向量 \(\boldsymbol t\) 代替法向量 \(\boldsymbol n\) 进行光照计算,实际上是只取了一个影响最大的法线做 Blinn-Phong 光照计算,得到近似的结果,公式为
\[ f_s(\boldsymbol \omega_i, \boldsymbol \omega_r) = \frac{\left(\sqrt { 1 - (\boldsymbol \omega_h \cdot \boldsymbol t)^2}\right)^{\alpha}}{K} \]
Marschner 高光模型
这是一个关于毛发的散射模型,比较复杂。
\[ f_s(\boldsymbol \omega_i, \boldsymbol \omega_r) = \text{Gaussian}(\dots) \]
用于镜面反射的微表面模型
这是当下实时渲染引擎统一使用的 Cook-Torrance Specular BRDF (microfacet specular BRDF):
\[ f_s(\boldsymbol \omega_i, \boldsymbol \omega_r) = \frac{D(\boldsymbol \omega_h) F(\boldsymbol \omega_r, \boldsymbol \omega_h) G(\boldsymbol \omega_i, \boldsymbol \omega_r, \boldsymbol \omega_h)}{4 (\boldsymbol n \cdot \boldsymbol \omega_i)_+ ( \boldsymbol n \cdot \boldsymbol \omega_r)_{+}}, \]
其中:
法线分布函数
法线分布函数(NDF),定义为物体表面微元的微表面面积与宏表面面积之比,再除以单位立体角。其量纲与 BRDF 相同。一般采用 GGX(ground glass unknown),为
\[ D(\boldsymbol \omega_h) = \frac{\alpha^2}{\pi((\boldsymbol \omega_h \cdot \boldsymbol n)_{+}^2 (\alpha^2 - 1) + 1)^2} \]
- 其中 \(\alpha \in [0,1]\) 为粗糙度(roughness),为微表面法线偏离宏表面法线的程度。光滑度(glosiness)= 1 - 粗糙度。
- 当 \(\alpha\) 较大时,specular 主要呈现 Diffuse Reflection,高光不明显——有人将这样 \(\alpha\) 较大的材质称为“漫反射材质”,实际上这与一般讨论的 Lambert 漫反射项没有关系,或称“粗糙反射材质”较合适。
- 当 \((\boldsymbol \omega_h \cdot \boldsymbol n)_{+}^2 = 1\) 时,\(D = \frac{1}{\pi \alpha^2}\),即在镜面反射方向上,粗糙度越低,高光的亮度越高。
- 当 \((\boldsymbol \omega_h \cdot \boldsymbol n)_{+}^2 = 0\) 时,\(D = \frac{\alpha^2}{\pi}\),即在镜面反射方向的垂直方向上,粗糙度越高,粗糙反射的亮度越高。
- 当 \(\alpha = 1\) 时,\(D = \frac{1}{\pi}\),此时为完全粗糙反射,类似 Lambert 漫反射。
- 当 \(\alpha \to 0^+\) 时,\(D \to \frac{0^+}{\pi(1- (\boldsymbol \omega_h \cdot \boldsymbol n)_{+}^2)}\),此时越接近镜面反射方向,高光的亮度越高,但需要很完美的镜面反射方向才能采集到高光,即高光与非高光区域的阶跃更明显。当 \(\alpha = 0\) 时,一般 \(D=0\),但在镜面反射方向,有 \(D = \frac{0}{0}\),常见的处理方式是直接认为 \(D = 0\),此时不存在高光,\(f_s = 0\)。为了避免这种反直觉的情况出现,一般的引擎会 clamp \(\alpha\) 的值,例如令其最小值为 \(0.001\)。
菲涅尔项
菲涅尔项为 \(F\),描述在掠射角(\((\boldsymbol \omega_r \cdot \boldsymbol \omega_h)_{+}\) 接近 \(0\))时能观察到更强烈的镜面反射的现象,一般采用 Schlick 近似
\[ F(\boldsymbol \omega_r, \boldsymbol \omega_h) = F_0 + (F_{90} - F_0) (1 - (\boldsymbol \omega_r \cdot \boldsymbol \omega_h)_{+})^5 \]
- 其中 \(F_0\), \(F_{90}\) 为材料在 $ _r, _h $ 分别为 0 度(垂直入射)和 90 度(掠射)时的菲涅尔反射率
- 由于这是镜面反射部分的菲尼尔项,因此 \((\boldsymbol \omega_i \cdot \boldsymbol \omega_h)_+ = (\boldsymbol \omega_r \cdot \boldsymbol \omega_h)_+ \approx (\boldsymbol \omega_i \cdot \boldsymbol n)_+ \approx (\boldsymbol \omega_r \cdot \boldsymbol n)_+ = \cos \theta\),式中的 \((\boldsymbol \omega_r \cdot \boldsymbol \omega_h)_{+}\) 完全可以由不同的方式出现。
- \(F_0, F_{90}\)
都有公式解,基于物体表面与光线传播介质的折射率。通常情况下,\(F_{90}\) 可以用 1.0
近似,因为在掠射角的镜面反射相当强烈。
- 对非金属,一般取 \(F_0 = \left| \frac{n_1 - n_2}{n_1 + n_2} \right |^2 = 0.04\);如果 specular 生效,\(F_0\) 由 specular 决定
- 对金属,\(F_0 = a\)(albedo)。然而其实 Schlick 近似仅对非金属是正确的,对金属并非物理正确,但这样设置的视觉效果整体上是对的
- 对 metallic \(m \in (0,1)\) 的材质,可设 $F_0 = (0.04, a, m) $。当然这也不是物理正确的,但视觉上是对的。
- 一些渲染引擎可能还会有一些 hack,详见 Filament 的做法,这里不再赘述
在游戏引擎中,菲涅尔项
\[ F = \text{saturate}(F_0 + (1-F_0)(1- \boldsymbol n \cdot \boldsymbol v)^\gamma) \]
往往可以用来做一些非物理的“造假”视觉效果。例如:
- 获取物体边缘。可以想象对一个球体而言,物体边缘位于 \(\boldsymbol n \cdot \boldsymbol v \to 0\)
的位置,因此 \(F \to 1\),反之 \(F \to
0\),即可获得物体边缘的蒙版。进而可以:
- 进行卡通渲染描边。
- 勾勒透明物体的视效。观察到日常生活中,玻璃的边缘往往具有较高的不透明度,而中间往往透明度高。
- 线性插值折射率,获得玻璃变形效果(UE 的
refraction
节点) - 对掠射角下的片元做额外着色。一些天鹅绒材质可能应用这种效果(sheen)
几何函数
几何函数为 \(G\),为统计学上的微表面遮挡关系,近似方式多种多样。
分母
分母 \(4 (\boldsymbol n \cdot \boldsymbol \omega_i)_+ ( \boldsymbol n \cdot \boldsymbol \omega_r)_{+}\) 为校正因子。当 \((\boldsymbol n \cdot \boldsymbol \omega_i)_+\) 或 \(( \boldsymbol n \cdot \boldsymbol \omega_r)_{+}\) 接近于 0 时,整个 \(f_s\) 可能很大,产生光晕的 artifact,这个时候就需要 \(G\) 项来修正:\(G\) 在这种情况总会是一个很小的值。