《Real-Time Rendering》第九章 基于物理的着色

基于物理的着色(Physically Based Shading)

  在这一章中我们将会讨论基于物理的着色的不同方面。首先从光与物质交互的物理开始,接着展示这些物理与着色过程的联系。然后,专注于用于构造基于物理的着色模型的基本组成要素以及这些模型本身,这个部分会涵盖大量的材质类型。最后,我们讨论材质是如何被混合到一起的,并且讨论用于避免走样并保持表面外观的滤波方法。

光的物理(Physics of Light)

  光与物质的交互是基于物理的着色的基石。为了理解这些交互,最好对光的本质有个大概的了解。
  在物理光学中,光被建模为电磁横波Transverse Wave),即一种电场和磁场相对于传播方向垂直振荡的波。磁场向量和电场向量的都是相互垂直的,它们的幅值比率是固定的。这个比率会和相速度相等,这会在后续进行讨论。
  下图是个简单的光波

img

这是种较为简单的光波,是完美正弦函数。它只有一个波长Wavelength),使用希腊字母\(\lambda\)来表示。正如前一章了解的那样,光的感知颜色和它的波长强相关。正是因为这样,只有一个波长的光被称为单色的Monochromatic)光。然而,现实的光波中绝大多数都是多色的Polychromatic),包含着许多波长。
  上图这种光波在另一方面也很简单。它是线性偏振的Linearly Polarized)。这意味着对于空间中固定的一点来说,电场和磁场会在直线上来回移动。在这本书中,我们将会聚焦于非偏振的Unpolarized)光,这种光更普遍一些。在非偏振光中,场的振荡会均匀向垂直于传播轴线的所有方向进行。除了很简单以外,它也能被用来理解单色线性偏振的波,因为任何光都可以被分解成这种光的组合。
  如果我们追踪波上的一点,我们会发现它会随时间变化以固定的速度运动,这个速度为波的相速度Phase Velocity)。对于在真空中传播的光波来说,相速度为\(c\),它通常表示光的速度,大约\(300000 \; \mathrm{km/s}\)
  之前的部分我们讨论过可见光的波长范围大致在400到700纳米。这个长度是一根蛛丝长度的三分之一到二分之一,小于人类头发的五十分之一,下方为一张示例图

img

在光学中通常谈到的是相对于光的波长的尺寸。在这种情况下我们会说蛛丝的宽度大约为\(2\lambda\)\(3\lambda\),而头发的宽度大约为\(100\lambda\)\(200\lambda\)
  光波携带能量。能量流的密度与电场和磁场大小的乘积相等,。我们在这里专注于电场,因为它相比于磁场来说对物质的影响更大。在渲染中,我们关心的是随时间的平均能量流,它与波的振幅平方成比。这个平均能量流密度是辐照度,使用\(E\)来表示。
  光波可以被线性地结合。然而,由于辐照度和振幅的平方成比,这看起来会导致悖论。例如,对于辐照度来说合成两个波会不会有\(1+1=4\)这种情况?由于辐照度是能量流的度量,这难道不会违背能量守恒吗?这两个问题的答案分别是“有时候会有”和“不会违背能量守恒”。
  为了详细了解下,我们了解下叠加n个单色波的不同情况,这些波的振幅都为\(a\),如下图所示。

img

我们之前提到过,辐照度\(E\)与振幅的平方成比,因此可以用\(E=ka^2\)来表示,其中\(k\)为常量。在左边这种情况中,波之间没有相位差,叠加后的振幅因此为\(na\),所以总的辐照度为\(E=k(na)^2\),这种情况为相长干涉Constructive Interference)。在中间这种情况中,每两个波相互抵消,合成后的波的振幅为0,因此辐照度为\(E=0\),这种情况为相消干涉Destructive Interference)。
  相长干涉和相消干涉是两种特殊情况的相干叠加Coherent Addition),波峰波谷以某种一致的方式对齐。取决于相位的相对关系,n个相同波相干叠加后的辐照度可以是\(0\)或某单独一个波的辐照度的\(n^2\)倍。
  然而通常情况下,叠加的波都是相互非相干的Incoherent),也就是说相位都是相对随机的。就像右图那样,在右图这种情况中,叠加后的振幅为\(\sqrt{n}a\),辐照度为某单独一个波的辐照度的\(n\)倍,正如我们之前期望的那样。
  似乎相消干涉和相长干涉违背了能量守恒。但是之前那几个例子并没有展示全貌,它只展示了光在某个位置的交互。当波在空间中传播时,波之间的相位关系会在不同地方改变,下图是个相关的例子

img

在某些地方波之间有相长干涉,这让辐照度大于每个波辐照度值的叠加。而在另外一些地方,波之间发生相消干涉,导致合成后的辐照度小于每个波辐照度值的叠加。从总体上看其实并没有违背能量守恒定律。
  当物体中的电荷振荡时光波会发出。导致振荡的部分热能、电能、化学能会被转化为光能,从物体出发并辐射到周围。在渲染中,这种物体会被当作光源。在着色基础这一章,我们讨论过不同的光源,在接下来的局部光照这一章会立足于更基于物理进行讨论。
  当光波被发出后,它们会在空间传播直到遇到物质并与其交互。光与物质交互背后的核心现象很简单,和之前提到的光波的发射很像。振荡的电场会推拉物质中的电荷,让这些电荷也振荡。振荡的电荷会发出新的光波,把入射的光波的一些能量重定向到一个新的方向上。这个反应,被称为散射Scattering),它是许多光学现象的基础。
  散射后的光波和原始的光波有着相同的频率。通常情况下,原始的波包含多个单频率的波,这些波都会逐一与物质交互。入射的光在某个频率的能量不会贡献到发出光的其它频率上,除了某些特定的相对罕见的情况,例如荧光(Fluorescence)和磷光(Phosphorescence)。
  一个孤立的分子会向所有方向散射光,强度在不同方向会有区别。更多的光会从靠近原始光的传播轴线的方向发出,包括相同方向和相反方向。分子作为散射体的效率,其附近光波被散射的概率,会随波长显著变化。短波光相比于长波光会散射得更加有效。
  在渲染中,我们关心的是许多分子的集合。光与这种聚合体的交互不会和之前所说的孤立分子的例子相似。从附近的分子散射的波通常都是相互相干的,因此展现出干涉,因为它们都源于相同的入射波。余下的部分将讨论光从多个分子散射的重要且特殊的一些情况。

粒子(Particles)

  在理想的气体中,分子之间不会相互影响,因此它们的相对位置都是完全随机不相关的。尽管这是一个抽象,但是对于正常大气压下的气体来说是个好的模型。在这种情况下,从不同分子散射的波的相位差异会随机并持续改变。因此,从不同分子散射的波是非相干的并且能量可以线性叠加。
  相反,如果分子紧密地聚集在一起,比光的波长还要小,那么散射的光波会有相同相位并且会产生相长干涉。这会导致散射波的能量平方叠加。这意味着如果把分子压缩到很小的一块地方,散射光的强度会显著上升。保持密度不变持续添加分子,散射光的强度会进一步提升,直到分子团的直径接近光的波长。超过这一点时,额外的分子添加不会进一步增加光的强度。
  这一过程解释了云和雾的散射光为什么如此强烈。它们都是通过凝华形成的,这是水分子在空气中聚集到更大的集群的一个过程。它显著地加强了被散射的光。云的渲染会在Section 14.4.2部分讨论。
  当讨论光散射时,粒子这一术语同时指代孤立的分子和多分子集群。由于从直径比波长小的多分子粒子散射的光是从孤立分子散射的放大版本,展现了相同的方向上的变化和波长依赖。这种散射的类型对于大气粒子这种情况下被称为瑞利散射Rayleigh Scattering),而对于嵌入固体中的粒子这种情况则被称为丁达尔散射Tyndall Scattering)。
  当粒子尺寸比波长要大时,散射后的波的相位会变化,散射逐渐偏向前向方向,同时波长依赖性减弱,直到所有可见光波长几乎被同等散射。这种散射称为米氏散射Mie scattering)。

介质(Media)

  另一种重要的情况是光在均匀介质Homogeneous Medium)内传播,它是一个均匀地填充着相同分子的三维体。分子的间距不一定要如同水晶那样完美规则。液体和非晶固体可以是光学均匀的,如果它们的构成是单纯的,并且没有间隙或气泡。
  在一个均匀介质中,散射波会在除传播方向上的所有方向发生相消干涉。原始的波会和从每个分子散射的波结合,最终合成的波除相速度和振幅之外会和原始的波一样。最终的波不会展现任何的散射,因为被相消干涉抑制了。
  原始的相速度和新的波的相速度的比率定义了介质的一个叫折射率Index Of RefractionRefractive Index)的光学属性,用字母\(n\)来表示。有些介质是吸收性的Absorptive)。它们会转化光的一部分能量到热能,让波的振幅随距离增加指数降低。衰减率被定义为衰减系数Attenuation Index),使用希腊字母\(\kappa\)来表示。\(n\)\(\kappa\)都会随波长变化。这两个数字一起定义了介质对给定波长的光的影响,它们通常会被结合到一个单独的复数\(n+i\kappa\),被称为复折射率Complex Index Of Refraction)。折射率是光与物质在分子级交互的细节的抽象,它让我们能把介质当作一个连续体,让这个过程的模拟简单得多。
  尽管光的相速度不会直接影响外表,但是速度的变化会产生影响,我们会在后面进行解释。在另一方面,光吸收对视觉会有着直接影响,因为这会降低光的强度。下图展示了光吸收的一些例子。

img

  非均匀介质通常可以建模为嵌入散射粒子的均匀介质。抑制均匀介质散射的相消干涉是因为均匀介质有着排列整齐的分子,这么建模因此能生成散射波。任何局部的分子分布的变化都能破坏相消干涉,从而让散射波得以传播。这种局部改变可以是不同类型的分子集群、气隙、气泡或密度变化。不论是哪种情况,都会像之前提到过的粒子那样散射光,散射属性会相似地依赖于集群的尺寸。甚至是气体也能这样建模。对于这些例子来说,“散射的粒子”是由分子持续运动导致的瞬时密度涨落。这个模型使得有意义的\(n\)值得以为气体建立,对于理解气体的光学属性来说非常有用。下图展示了光散射的一些例子

img

  散射和吸收都是尺度依赖的。在小场景中没有产生显眼的散射的介质在更大尺度范围可能产生非常显眼的散射。例如,当观察房间里瓶子里的水时,空气的光散射和水的光吸收不会显眼。然而,在更广的环境中,这两种效果会感觉非常显著,如下图所示。

img

  在一般情况下,介质的外表是由散射和吸收组合形成的,如下图所示

img

散射程度决定了浑浊度,高散射会制造一种不透明的外观。有极少数的例外情况,就比如乳光玻璃,在固态和液态介质的粒子倾向于比光的波长要大,因此倾向于均匀散射所有可见波长的光。因此任何的色偏通常由波长依赖的吸收导致。介质的亮度是两种现象作用的结果。对于白色来说,它是高散射和低吸收的结合。会在Section 14.1进行更深入的讨论。

表面(Surfaces)

  从光学的角度来看,一个物体的表面是个分离有着不同折射率的三维体的二维界面。在典型的渲染场景中,外部的三维体包含空气,它有着大约1.003的折射率,通常被看作1。内部的三维体的折射率取决于物体是由什么物质构成的。
  当光波击中表面时,两个方面对结果有着重要的影响,其一是两边的物质,其二是表面的几何结构。我们首先聚焦于物质这一影响因素,先假设一个极其简单的平整表面。我们令“外部”(光起始的地方)的折射率为\(n_1\),“内部”(光即将要透射到的地方)的折射率为\(n_2\)
  在之前的部分我们已经了解光波遇到材质构成不连续或密度不连续(折射率不同)等情况会散射。分离不同折射率的平面是种特殊类型的不连续,会以某种特定的方式散射光。边界条件要求电场平行于表面的部分是连续的。用另一句话来说,电场向量到表面的投影必须在界面两侧保持一致。这有着如下的一些暗示

  1. 在表面,任何散射后的波必须与入射波同相位或\(180^\circ\)反相。因此在表面,散射后的波的波峰必须与入射波的波峰或波谷对齐。这限制散射后的波只有两种可能的方向,一种进入表面,另一种远离表面。进入表面被称为透射波Transmitted Wave),而远离表面的被称为反射波Reflected Wave)。

  2. 散射后的波必须和入射波有着相同的频率。我们在这里只假定一个单色波。

  3. 当光波从一个介质进入到另一个介质时,相速度也就是波在介质中传播的速度的改变会和相对折射率(\(n_1/n_2\))成比。由于频率是固定的,波长的改变也和(\(n_1/n_2\))成比。

  最终结果如下图所示

img

可以看到反射波方向与入射波方向和法线的夹角都为\(\theta_i\)。而透射波方向则弯曲到了\(\theta_t\),它和\(\theta_i\)有着如下的联系

\[\sin(\theta_t)=\frac{n_1}{n_2}\sin(\theta_i) \]

这个关系被称为斯涅尔定律Snell's Law)。它被用于全局折射效果中,在Section 14.5.2中会被讨论。
  尽管折射通常与透明的材质例如玻璃、水晶等联系,它其实也发生在不透明的表面。当折射在不透明物体的表面上发生时,散射后向物体内传播的光会被吸收。在这种情况下,光会与物体的介质交互就如同下图那样

img

如果是金属,内部的许多自由电子会“吸收(并耗散)”折射光的能量,并将其重定向到反射波上。这就是为什么金属有着高吸收率和高反射率。
  我们讨论过的反射和折射需要折射率的突变,而且要发生于小于单个波长的一段距离上。折射率的平滑改变不会让光分裂,而是让光的路径弯曲,就好比是不连续的折射连续发生。当空气密度由于温度的影响变化时,这种效果会发生,比如海市蜃楼和热扰动,下图是个相关的例子

img

  甚至一个有着明确定义边界的物体如果嵌入到了有着相同折射率的物体中,那么将不会有可见的表面。如果没有折射率的改变,那么反射和折射就不能发生。一个例子如下图所示

img

注解:图中水中的装饰性球体和水有着相同的折射率,位于水面之上的球体有着可见的表面,水面之下的球体则变得不可见,有部分球体可见的原因是因为它们会吸收颜色。

  到目前为止我们聚焦于了光波击中表面时,界面两边的物体起的效果。我们接下来将会讨论另一个很重要的影响表面外观的因素,即几何结构。严格地来说,完美平整的表面是不可能的。每个表面都会不平整,甚至是单个原子构成表面这一情况。然而,表面的比波长小得多不平整结构对光没有作用,而比波长大得多的不规整结构会让表面倾斜而又不影响它的局部平整度。只有那些尺度在1到100倍波长的不平整结构能让表面表现得和平整的平面不一样,这背后其实是一个叫衍射Diffraction)的现象,会在Section 9.11被讨论。
  在渲染中,我们通常使用几何光学Geometrical Optics),它忽略了干涉和衍射这种波效应。这等价于假设所有表面的不平整结构要不是比光的波长小得多要不是比光的波长大得多。在几何光学中,光被建模为光线而不是波。当光线击中表面某一点时,那一点附近的局部区域将会被当作平面。下图的左下部分可以被看作是反射和折射的几何光学图片,而其它部分可以看作是波图片。

img

在接下来的部分我们将会一直使用过几何光学,直到Section 9.11,这个部分专门讨论了基于波光学的着色模型。
  正如我们之前提到的那样,表面比波长大得多的不平整结构会改变表面的局部朝向。当这些不平整结构太小而不能被单独渲染时(比像素还小),我们指代它们为微几何结构Microgeometry)。反射和折射的方向取决于表面的法线。微几何结构的作用就是在表面的不同位置改变法线,反射和折射光的方向因此被改变。
  尽管表面上的点只会把光反射到一个方向上,但是每个像素覆盖的许多表面点会反射光到不同的方向。最终的外表会由所有不同的反射方向决定。下图展示了有着相似的形状但是在微观尺度上有着显著不同的微几何结构的两个表面的外表

img

  对于渲染来说,与其显式建模微几何结构,不如统计地对待它并把表面看作好像有着随机分布的微几何法线。因此,我们建模表面折射(和反射)光的连续方向分布。分布的宽度越大,反射和折射的细节就越模糊,这取决于微几何结构的法线向量的统计方差,用另一句话来说就是微观尺度的粗糙度Roughness)。下图是个相关的例子

img

次表面散射(Subsurface Scattering)

  折射光会继续与物体的内部交互。如之前提到的那样,金属会反射大部分的入射光并迅速吸收剩下的那一部分。非金属物质则相反,展现了不同的散射和吸收性,正如下图所示

img

有着低散射和低吸收的材质会表现得透明,透射任何折射光,并让其穿过整个物体。在第五章的透明度部分,我们已经讨论过了不应用折射渲染这种材质的方法,应用折射的方法的细节将会在Section 14.5.2部分被讨论。在这一章中,我们将会聚焦于不透明物体,这种物体会让透射光经历多次散射和吸收,直到有一些重新从表面发出。下图是个相关的例子

img

  可以看到这种次表面散射的Subsurface-scattered)光离开表面的位置与入射光进入表面的位置有着不同的距离。这个进入-离开距离的分布取决于材质中的散射粒子的密度和属性。这些距离和着色尺度(像素的大小或着色样本之间的距离)之间的关系是非常重要的。如果这个距离相比于着色尺度小,那么可以将其假定为0用于着色。这能让次表面散射和表面的反射结合到局部着色模型中,让从表面某点离开的光只取决于从那个点入射的光。然而,由于次表面散射的光和从表面反射的光有着显著不同的外观,因此最好把它们分成两个着色项。一个镜面反射项Specular Term)模型建模表面反射,另一个漫反射项Diffuse Term)建模局部次表面散射Local Subsurface Scattering)。
  如果进入-离开距离相比于着色的尺度要大,那么另一个特殊的渲染技术则需要被用来捕捉光从表面一个地方进入并从另一个地方离开的视觉影响。这些全局次表面散射Global Subsurface Scattering)技术会在Section 14.6被详细讨论。下图展示了局部次表面散射和全局次表面散射的区别。

img

  值得注意的一点是局部次表面散射和全局次表面散射模型是完全相同的物理现象。对于每个情况的最好选择不止取决于材质属性,还取决于观察的尺度。例如,当渲染儿童玩塑料玩具的场景时,全局技术会被需要用来精确地渲染儿童的皮肤,对于玩具来说局部技术则足够。这是因为散射距离在皮肤上比在塑料上大得多。然而,如果相机足够远,皮肤的散射距离会比像素小,在这种情况下对皮肤和玩具使用局部着色模型就够。相反地,在一个极其近的视点观察,塑料将会展现可见的非局部次表面散射,这个时候就需要使用全局技术来精确地渲染玩具。

相机(The Camera)

  正如Section 8.1.1提到的那样,在渲染中我们会计算从表面着色点到相机位置的辐亮度。这模拟了胶片相机、数字相机、人眼的成像系统的一个简化模型。
  这些系统都包含一个由许多离散的小传感器构成的传感器表面。比如眼睛里的视杆细胞和视锥细胞,还有数字相机里的光电二极管,或胶片里的染料颗粒。这些传感器会侦测表面上的辐照度值并生成一个颜色信号。辐照度传感器本身不能生成图像,因为它们会平均所有入射方向上的光线。正是因为这样,一个完整的成像系统会包含一个遮光的只留着一个小光圈(Aperture)(开口)的封闭腔体,这能限制光击中传感器的入射方向。一个镜片会在光圈摆放来聚焦光线,让每个传感器只接收到小的入射方向范围内的光。封闭腔体、光圈、和镜片让传感器变成了方向选择的Directionally Specific)的传感器。它们平均一小范围的和一小部分入射方向上的光。这些传感器因此测量的是平均辐亮度而不是辐照度。
  从历史上说,渲染模拟了一个简单的针孔相机Pinhole Camera),如下图所示

img

一个针孔相机有着非常小光圈,在理想的情况下它的大小为0,不需要镜片。点光圈限制了传感器表面上的每个点只能收集一个方向的光,传感器表面上离散的传感器因此只能收集窄的锥体内的光线。渲染系统以一种些许不同(但等价)的方式建模了针孔相机,如下图所示

img

针孔光圈的位置使用\(\mathbf{c}\)来表示,它通常也指代“相机位置”或“眼位置”。此外,也是透视变换的投影中心。
  当渲染时,每个着色样本对应着一条光线,因此也对应着传感器表面上的一个采样点。抗走样这一过程因此能被解释为重建每个离散的传感器表面上收集的信号。然而,渲染不被物理传感器的限制所约束,我们因此能以更一般的方式对待渲染这个过程,把抗走样看作是从离散样本的连续图像信号的重建。
  实际的针孔相机相比于现实中的绝大多数相机还有人眼来说是个比较差的模型。一个使用镜片的成像系统如下所示。它包含了一个允许使用大光圈的镜片,这极大地增加了光的收集量。然而,这会造成相机有着受限的深度场,过远或过近的物体会被模糊。

img

  除了受限的深度场,镜片也有着其它影响。每个传感器位置会接收锥体内的光线,甚至是对于哪些完美对焦的点来说也会有。理想化的每个着色样本表示单独一个视线方向的模型有时候会引入数学奇异性、数值不稳定、视觉走样。在渲染图像的时候把这些物理模型放在心上可以帮我们辨别并解决问题。

双向反射分布函数(The BRDF)

  最终,基于物理的渲染都要计算进入相机的光线的辐亮度。对于给定的视线来说我们令这个视线方向上的辐亮度为\(L_i(\mathbf{c},-\mathbf{v})\),其中\(\mathbf{c}\)是相机位置,而\(\mathbf{-v}\)是视线方向。我们在这里使用\(\mathbf{-v}\)是因为两个符号惯例。其一是\(L_i()\)中的方向向量总是背离给定点,给定点在我们这个情况下是相机位置。其二是因为视线方向\(\mathbf{v}\)总是指向相机。
  在渲染中,场景通常被建模为一些物体以及物体之间的介质。通常来说,物体之间的介质一般是纯净的空气,对光线的辐亮度不会有显著地影响,因此对于渲染来说可以被忽略。有些时候光线可能会在较为影响它的辐亮度的介质中穿行,这些介质会吸收或散射。由于参与到了光在场景中的传输过程,这些介质因此被称为参与介质Participating Media)。参与介质会在第十四章进行深入地讨论。在这一章中,我们假设场景中不存在参与介质,进入相机辐亮度因此等于离开最近物体表面并指向相机的光线的辐亮度,即

\[L_i(\mathbf{c},-\mathbf{v})=L_o(\mathbf{p},\mathbf{v}) \]

其中的\(\mathbf{p}\)为视线与最近物体的交点。
  有了这个等式,我们的新目标就是计算\(L_o(\mathbf{p},\mathbf{v})\)。它是第五章讨论过的着色模型评估的基于物理的版本。有时候辐亮度会直接由物体发出。更一般的情况下,从物体表面离开的辐亮度源自于其它表面反射过来的光。在这一章我们先不管透明的情况以及全局次表面散射。用另一句话来说,我们聚焦于局部反射现象。这些现象包括表面反射和局部次表面散射,它们只依赖于光的入射方向\(\mathbf{l}\)和视线方向\(\mathbf{v}\)。局部反射率由双向反射分布函数Bidirectional Reflectance Distribution FunctionBRDF)量化,它被记为\(f(\mathbf{l},\mathbf{v})\)
  在一开始,BRDF被定义用于均匀表面。也就是说,BRDF在整个表面上是相同的。然而,现实世界(和被渲染的场景)中的表面上是很少有均匀的材质属性的。甚至是由单一材质构成的物体例如雕像会有划痕、氧化斑、污渍,还有其它的变化也会导致表面上的各个位置的视觉属性变化。从技术上说,基于空间位置捕捉BRDF变化的函数被称为空间变化的BRDFSpatially Varying BRDFSVBRDF)或空间BRDFSpatial BRDFSBRDF)。正是因为它在实践中很流行,所以被使用的BRDF通常会隐含着依赖于表面位置的假设。
  入射和出射方向有着两个自由度。被频繁使用的参数化方向涉及两个角度,一个为仰角\(\theta\),另一个为偏航角\(\phi\)。在这种情况下,BRDF是四个标量的函数。各向同性Isotropic)BRDF是一种特殊的类型。对于这种BRDF来说,当入射方向和出射方向绕表面法线旋转,并保持两个方向的相对角度不变时,会有相同的数值。下图展示了两种BRDF使用的变量

img

各向同性BRDF是三个标量的函数,因为对于这种BRDF来说,偏航角只需要一个相对偏航角。
  由于我们忽略了荧光和磷光这种现象,我们因此可以假定入射光被反射后频率保持不变。取决于波长,反射的量可以变化,这可以使用两种方式的其中一种进行建模。要不波长被当做是额外的BRDF的输入变量,要不BRDF被当做是一个返回光谱分布值的函数。第一种有时候被离线渲染使用,而在实时渲染中第二种方法总是被使用。因为实时渲染器使用RGB三元组来表示光谱分布,这意味着BRDF会返回一个RGB值。
  为了计算\(L_o(\mathbf{p},\mathbf{v})\),我们将BRDF整合到反射率方程Reflectance Equation)中

\[L_o(\mathbf{p},\mathbf{v})=\int_{\mathbf{l} \in \Omega} f(\mathbf{l},\mathbf{v})L_i(\mathbf{p},\mathbf{l}) (\mathbf{n} \cdot \mathbf{l}) d\mathbf{l} \]

积分符号的下标\(\mathbf{l} \in \Omega\)表示积分是在表面法线指向的半球上进行的。为了简洁性,我们省略掉表面点\(\mathbf{p}\),反射率方程因此为

\[L_o(\mathbf{v})=\int_{\mathbf{l} \in \Omega} f(\mathbf{l},\mathbf{v})L_i(\mathbf{l}) (\mathbf{n} \cdot \mathbf{l}) d\mathbf{l} \]

  当计算反射率方程时,半球通常被球面坐标\(\phi\)\(\theta\)参数化。对于这个参数化来说,微分的立体角\(d\mathbf{l}\)等价于\(\sin(\theta_i)d\theta_id\phi_i\)。使用这个参数化,可以得出上述公式的一个双重积分等价形式,如下所示(\(\cos{\phi_i} = \mathbf{n} \cdot \mathbf{l}\)

\[L_o(\theta_o,\phi_o) = \int_{\phi_i=0}^{2\pi} \int_{\theta_i=0}^{\pi/2} f(\theta_i,\phi_i,\theta_o,\phi_o) L(\theta_i,\phi_i) \cos{\theta_i}\sin{\theta_i}d\theta_id\phi_i \]

  在一些情况下使用一个略微不同的参数化形式也许更方便一些,我们令\(\mu_i = \cos{\theta_i}\),令\(\mu_o=\cos{\theta_o}\),双重积分因此也可以是

\[L_o(\mu_o,\phi_o) = \int_{\phi_i=0}^{2\pi} \int_{\mu_i=0}^1 f(\mu_i,\phi_i,\mu_o,\phi_o) L(\mu_i,\phi_i) \mu_i d\mu_i d\phi_i \]

  BRDF只定义了光线方向和视线方向在表面之上的情况。当光线方向在表面之下时,可以将BRDF置0或不进行BRDF的评估。但是你可能也会想要是视线方向在表面之下呢?从理论上来说这种情况永远不会发生。因为这种表面是背离相机的,因此对于观察者来说是不可见的。然而,在实时应用中的顶点法线的插值和法线映射会有这种情况。对于视线在表面之下的情况,我们可以把\(\mathbf{n} \cdot \mathbf{v}\)钳制到0或使用绝对值,但是这两种方法会导致伪影。Frostbite引擎使用\(\mathbf{n} \cdot \mathbf{v}\)的绝对值再加上一个小量(\(0.00001\))来避免除以\(0\)的问题。另一个可能的解决方法是使用“软钳制”,当\(\mathbf{n}\)\(\mathbf{v}\)的角度越过\(90^\circ\)时,让\(\mathbf{n} \cdot \mathbf{v}\)渐变到0.
  物理定律对任何BRDF施加了两个约束。第一个约束是亥姆霍兹互易性Helmholtz Reciprocity),这意味着输入角度和输出角度可以被调换,函数会输出相同的值,也就是

\[f(\mathbf{l},\mathbf{v})=f(\mathbf{v},\mathbf{l}) \]

在实践中,被使用的BRDF通常会违背亥姆霍兹互易性,因为不会导致明显的伪影,除了那些要求互易性的离线渲染算法,比如双向路径追踪。然而,这个约束对于确定BRDF是否是物理上可行的来说很有用。
  第二个约束是能量守恒,出射光线的能量不能大于入射光线的能量(不涉及到发光的表面,因为这是种特殊情况)。离线渲染算法比如路径追踪会需要能量守恒来确保收敛。对于实时渲染来说,严格的能量守恒不是必要的,但是近似能量守恒是重要的。如果渲染表面使用的BRDF在较大程度上违背了能量守恒,那么表面会过亮,因此会有不真实感。
  方向-半球反射率Directional-hemispherical Reflectance\(R(\mathbf{l})\)是个和BRDF相关的函数。它可以被用来度量BRDF的能量守恒程度。它度量的是小量的入射光与表面交互后最终有多少量被反射出来。它的计算公式如下

\[R(\mathbf{l}) = \int_{\mathbf{v} \in \Omega} f(\mathbf{l},\mathbf{v}) (\mathbf{n} \cdot \mathbf{v}) d\mathbf{v} \]

另一个相似的函数为半球-方向反射率Hemispherical-directional Reflectance\(R(\mathbf{v})\)如下所示

\[R(\mathbf{v}) = \int_{\mathbf{l} \in \Omega} f(\mathbf{l},\mathbf{v}) (\mathbf{n} \cdot \mathbf{l}) d\mathbf{l} \]

如果BRDF是互易的,那么半球-方向反射率和方向-半球反射率是相同的函数。当这两个函数可互换时方向反照率Directional Albedo)可以作为一个统称。
  方向-半球反射率\(R(\mathbf{l})\)必须总是处于\([0,1]\)的范围,因为要达到能量守恒。反射率为0表示入射光全被吸收的一个情况。而为最大值1时,入射光全都会被反射。在绝大多数情况下反射率会介于0和1。和BRDF一样,\(R(\mathbf{l})\)的值会随波长变化,因此在渲染时它会被表达为RGB向量。由于每个分量被限制到了\([0,1]\),一个\(R(\mathbf{l})\)可以被看作是一个简单的颜色。要注意的是,BRDF不会有这个限制。作为一个分布函数,BRDF可以在某些方向上有着较高的值。一个BRDF如果要是能量守恒的,那么\(R(\mathbf{l})\)对于每个可能的\(\mathbf{l}\)来说不能超过\(1\)
  BRDF最简单的可能是朗伯,它对应着第五章着色基础讨论过的郎伯着色模型。朗伯BRDF有着常量。知名的\((\mathbf{n} \cdot \mathbf{l})\)因子不是朗伯着色的BRDF部分,而是\(L_o(\mathbf{v})=\int_{\mathbf{l} \in \Omega} f(\mathbf{l},\mathbf{v})L_i(\mathbf{l}) (\mathbf{n} \cdot \mathbf{l}) d\mathbf{l}\)这个公式的一部分。除了简单性之外,朗伯BRDF通常被用于实时渲染,来表示局部次表面散射(尽管有更加精确的模型,如Section 9.9 用于次表面散射的BRDF模型)。朗伯表面的方向-半球反射率也是个常量。使用之前提到的公式进行积分后能得到

\[R(\mathbf{l})=\pi f(\mathbf{l},\mathbf{v}) \]

  朗伯BRDF的常量方向-半球反射率值通常被指代为漫反射颜色Diffuse Color\(\mathbf{c}_\text{diff}\)反照率Albedo\(\rho\)。在这一章,为了强调它与次表面散射的联系,我们指代这个量为次表面反照率Subsurface Albedo\(\rho_\text{ss}\),通过上面这个式子我们能得出

\[f(\mathbf{l},\mathbf{v}) = \frac{\rho_\text{ss}}{\pi} \]

  一个用来理解BRDF的方法是让入射光的方向不变,接着计算与各个出射方向相关的BRDF并进行可视化,下图是个相关的例子。

img

其中绿线是光照入射方向,而另外一根线为理想的反射方向。球面部分为漫反射分量,椭球状部分是镜面反射瓣Specular Lobe)。可以看到这些反射瓣基本都朝着入射光的反射方向,它们的厚度代表着反射的粗糙程度。如果BRDF是互易的,那么上述的可视化也能告诉我们不同的入射光对单一出射方向的贡献。

光照(Illumination)

  \(L_i(\mathbf{l})\)是反射率方程中的一项,它表示在着色点处从\(\mathbf{l}\)方向入射的光。全局光照算法Global Illumination Algorithm)会模拟光在场景中的传播和反射并计算\(L_i(\mathbf{l})\)。这些算法使用渲染方程,反射率方程是一种特殊情况。全局光照会在第十一章进行讨论。在这章之后我们聚焦于局部光照Local Illumination),它使用反射率方程局部地计算每个表面点处的着色。
  在现实世界的场景中,每个点的各个方向上都有入射光,不管是来自光源还是从其它表面反射。不像定向光或点式光,现实世界的光源都是区域光源Area Light),它们都覆盖非零的立体角。在这一章中,我们使用\(L_i(\mathbf{l})\)的一种限制形式,只考虑定向光和点式光,留下更多的一般类型的光照环境在第十章进行讨论。做这个限制是为了进行更集中的讨论。
  尽管点式光和定向光是非物理抽象,它们可以被看作是物理光源的一个衍生近似。这样的一种衍生是非常重要的,因为它能让我们将这些光源整合到基于物理渲染的框架中,并且清楚地理解这种近似所带来的误差。
  我们取一个小的遥远的区域光,并定义指向它的中心的一个向量\(\mathbf{l}_c\)。我们也定义光的颜色\(\mathbf{c}_\text{light}\)作为面向光源的白色朗伯表面反射的辐亮度。这是一个用于参数设定的直观定义,因为光的颜色是直接对应于它的视觉影响。
  有了这些定义,一个定向光可以作为区域光源体积缩小而\(\mathbf{c}_\text{light}\)保持不变的极限情况的一种衍生。在这种情况下,反射率方程的积分可以简化为单独的一次BRDF评估,计算起来会非常方便,公式如下所示

\[L_o(\mathbf{v})=\pi f(\mathbf{l}_c,\mathbf{v}) \mathbf{c}_\text{light} (\mathbf{n} \cdot \mathbf{l}_c) \]

表面法线和光照方向的点乘通常会被钳制到0,这样可以跳过光照方向在表面之下的情况,修改后的公式为

\[L_o(\mathbf{v}) = \pi f(\mathbf{l}_c,\mathbf{v}) \mathbf{c}_\text{light} \text{max}(0,\mathbf{n} \cdot \mathbf{l}_c) \]

  点式光可以被相似地对待。区别是区域光不需要是遥远的,并且\(\mathbf{c}_\text{light}\)会平方反比衰减。考虑到多个点式光源,辐亮度的计算公式为

\[L_o(\mathbf{v}) = \pi \sum_{i=1}^n f(\mathbf{l}_{c_{i}},\mathbf{v}) \mathbf{c}_{\text{light}_i} \text{max}(0,\mathbf{n} \cdot \mathbf{l}_{c_i}) \]

  \(\pi\)因子消去了BRDF里通常出现的\(1/\pi\)。除法消去后能让着色方程更易阅读。当从学术论文中适配BRDF用于实时着色方程时,需要谨慎。一般来说,BRDF需要在使用前乘以\(\pi\)

菲涅尔反射率(Fresnel Reflectance)

  在之前的部分我们从一个较高的层级讨论了光与物质的交互。讨论完后,我们还了解了用数学表示这些交互的基本机制。现在我们可以了解特定的现象,并量化它们让我们得以在着色模型中进行使用。我们首先从平面的反射开始。
  一个物体的表面是分离周围介质和物体的组成物质的界面。光与两个物质之间的平面界面的交互遵从菲涅尔方程Fresnel Equation),它由Augustin-Jean Fresnel开发而来。菲涅尔方程需要遵从几何光学假设的平面界面。用另一句话来说,表面不会有介于光的1倍到100倍波长的任何不平整结构。小于这个范围的不平整结构对光没有影响,更大的不平整结构会让表面倾斜,但又不影响表面的局部平整度。
  平面上的入射光会被分成两个部分,一个为被反射的部分,另一个为被折射的部分。反射方向\(\mathbf{r}_i\)和入射方向\(\mathbf{l}\)是关于法线\(\mathbf{n}\)对称的,反射方向的计算公式因此为

\[\mathbf{r}_i = 2 (\mathbf{n} \cdot \mathbf{l}) \mathbf{n} - \mathbf{l} \]

下图为一张示例图

img

反射的量是由菲涅尔反射率Fresnel Reflectance\(F\)描述的,它取决于入射角度\(\theta_i\)
  如之前的部分描述的那样,反射和折射会被两边的物体的折射率影响。我们会继续使用那个部分使用的符号。\(n_1\)是“上方”(入射光处于的一面)物质的折射率,而\(n_2\)是“下方”(折射光传播的一面)物质的折射率。
  菲涅尔方程描述了\(F\)\(\theta_i\)\(n_1\)\(n_2\)的依赖关系。与其直接展示复杂的公式,不如先描述下它们的重要特性。

外反射(External Reflection)

  外反射External Reflection)会在\(n_1 < n_2\)时发生。用另一句话,就是光入射的这一边的折射率较低。通常来说,这一边一般都是空气,有着大约1.003的折射率,我们简单地假设其为1。从物体到空气的方向被称为内反射Internal Reflection),后续会进行讨论。
  对于给定的物质来说,菲涅尔方程可以看作是\(\theta_i\)的反射率函数\(F(\theta_i)\)。从原则上来说,\(F(\theta_i)\)会在整个可见光谱上连续变化。对于渲染来说,它的值会被看做是RGB向量。\(F(\theta_i)\)有着如下的性质

  • \(\theta_i=0^\circ\)时,也就是入射光方向垂直于表面时,\(F(\theta_i)\)的值是物质的一个属性。这个值被记为\(F_0\),它可以被看作是物质的特征镜面反射颜色。\(\theta_i=0^\circ\)的情况被称为法线入射Normal Incidence)。

  • \(\theta_i\)越来越大,也就是入射方向越来越倾斜时,\(F(\theta_i)\)的值会倾向于增加,当\(\theta_i=90^\circ\)时会达到最大值\(1\)

  下图展示了不同物质的\(F(\theta_i)\)的可视化情况

img

注解:三个物质从左到右分别为玻璃、铜、铝,第三排图像的横坐标是入射角的正弦。

可以看到曲线都是高度非线性的,在\(\theta_i=75^\circ\)之前都不怎么变化,接着快速地趋向于1。从\(F_0\)\(1\)的大多数情况都是单调增的,对于某些物体来说(比如上图所示的铝),它们的曲线在\(1\)之前会有个小坑。
  在镜面反射的情况下,出射方向或视线方向和入射角是相同的。这意味着相对于入射光有接近\(90^\circ\)\(\theta_i\)对于观察者来说也有相同的视线角度。。由于这个原因,反射率的增长主要在物体的边缘可见。而且,表面上的反射率增长最强的地方相对于相机的视角来说会是被缩短的,这些部分因此只占据了少量的像素。为了让菲涅尔曲线不同的部分与它们的视觉重要性成比,上图中的第三排使用的横坐标是\(\sin(\theta_i)\)而不是\(\theta_i\)。下图展示了为什么使用\(\sin(\theta_i)\)是一个好选择。

img

  从这里开始,我们会使用\(F(\mathbf{n},\mathbf{l})\)而不是\(F(\theta_i)\),不要忘了\(\theta_i\)\(\mathbf{n}\)\(\mathbf{l}\)的夹角。当菲涅尔函数被整合到了BRDF中时,一个不同的向量通常会替代表面法线\(\mathbf{n}\)。Section 9.8有更多相关的细节。
  掠射角附近的反射率增加在渲染相关的文献中通常被称为菲涅尔效应Fresnel Effect)。
  除了它们的复杂度,菲涅尔方程也有其它的属性让它们很难用于渲染。它们需要在可见光谱上采样折射率,这些值可能是复数。从之前的那张不同物质的反射率曲线的示例图可以得出一个基于特征镜面反射颜色\(F_0\)的更简单的近似方法。Schlick给予了一个菲涅尔反射率的近似公式

\[F(\mathbf{n},\mathbf{l}) \approx F_0 + (1-F_0)(1-\text{max}(0,\mathbf{n} \cdot \mathbf{l}))^5 \]

这个函数是白色和\(F_0\)之间的RGB插值。除了很简单以外,它的近似效果也挺准确。
  下图展示了和Schlick曲线有区别的一些物质的菲涅尔反射率曲线

img

这些物质的菲涅尔反射率曲线在到达白色之前都有显眼的小坑。可以看到有个物质的反射率曲线和Schlick近似的差别较大。但是甚至是对于这种物质来说,Schlick近似导致的错误是微不足道的,这可以从曲线下方的颜色条看出。如果有需求要精确地捕捉这种材质的行为,那么可以使用Gulbrandsen给予的一个替代近似。这个近似和金属的菲涅尔方程的匹配率很高,但是相比于Schlick的计算上的开销更昂贵。一个更简单那的选择是修改Schlick近似的最后一项的指数。这会改变曲线渐变到\(90^\circ\)的白色的“锐度”,这能有一个更加接近的近似。Lagarde总结了菲涅尔方程和一些近似公式。
  当使用Schlick近似时,\(F_0\)是唯一个控制菲涅尔反射率的参数。这对于我们来说是极其便捷的,可以通过标准的颜色挑选界面来控制效果,而且还可以使用纹理进行映射。此外,对于现实世界中的许多材质来说有很多可用的参考\(F_0\)值。折射率也可以被用来计算\(F_0\)\(n_1\)一般来说会被假设为\(1\),接近于空气的折射率的近似。此外\(n\)会被用来表示物体的折射率而不是\(n_2\)。这两个简化给予了如下的公式

\[F_0 = \left(\frac{n-1}{n+1}\right)^2 \]

对于复折射率来说,这个公式应该使用结果(复数)的模。对于折射率在可见光谱上显著变化的情况来说,为\(F_0\)计算精确的RGB值首先需要在波长上进行采样计算\(F_0\),接着使用第八章比色法部分中提到的方法将结果光谱向量转化为RGB值。
  在一些应用中一个更一般的Schlick近似形式会被使用

\[F(\mathbf{n},\mathbf{l}) \approx F_0 + (F_{90}-F_0)(1-\text{max}(0,\mathbf{n} \cdot \mathbf{l}))^\frac{1}{p} \]

这提供了菲涅尔曲线\(0^\circ\)\(90^\circ\)的颜色转变控制,同时也提供了转变的“锐度”的控制。这一种形式主要为美术师增加了控制,此外还能帮助匹配物理世界中的一些情况。正如上述讨论的那样,修改指数能够更接近地拟合某种材质。此外,设置\(F_{90}\)可以帮助匹配那些不太符合菲涅尔方程的材质,比如那些覆盖着有着精细颗粒的灰尘的表面。

典型的菲涅尔反射率值(Typical Fresnel Reflectance Values)

  物质可以根据它们的光学属性被分成三大组。这几组分别为:电介质Dielectric)、金属、半导体。其中,电介质是绝缘体,而金属为导体,半导体介于这两者之间。

用于电介质的菲涅尔反射率值(Fresnel Reflectance Values for Dielectrics)

  现实生活中遇到的绝大多数材质都是电介质,包括玻璃、皮肤、木头、毛发、皮革、塑料、石头、混凝土等等。水也是电介质。这看上去可能有点惊人,你可能马上想到水是导电的。其实不然,因为无杂质的纯水是不导电的。电介质通常有着较低的\(F_0\)值,通常为\(0.06\)或更低的值。法线入射处的低反射率让电介质的菲涅尔效应尤为显眼。电介质的光学属性在可见光谱上不会变化太多,这导致了无色的反射率值。常见电介质\(F_0\)如下表所示。

img

注解:纹理值是非线性编码,使用了8比特位的无符号整数,表中所展示的只是样本值,如果有范围,那么样本值表示的范围中间的数值。此外,还要注意到这些都是镜面反射颜色。这里的数值都是标量是因为这些材质在RGB通道上不会区别太大。

  对于其它的电介质来说,可以使用表中相似物质的参考值。对于未知的电介质来说,\(0.04\)是个合理的默认值。
  一旦光透射到了电介质中,它接下来会被散射或吸收。用于这个过程的模型会在Section 9.9部分被更深入地讨论。如果材质是透明的,那么光会持续传播,直到它“从另一边”击中物体的表面,这会在Section 9.5.3被讨论。

用于金属的菲涅尔反射率值(Fresnel Reflectance Values for Metals)

  金属有着较高的\(F_0\)值,几乎总是为0.5或更高的值。有些金属在可见光谱上有着变化的光学属性,这导致了有色的反射率值。用于一些金属的\(F_0\)值如下表所示

img

在这里的RGB值是使用sRGB(和Rec. 709)原色和白点定义的。金有着不寻常的\(F_0\)值。它的有色程度是最强的,有着略微高出1的红色通道,还有比较低的蓝色通道值。它也是最亮之一的金属,可以从上表的颜色看出。
  金属会瞬间吸收任何透射光,所以它们没有展现任何的次表面散射或透明。因此金属的所有可见颜色都源于\(F_0\)

用于半导体的菲涅尔反射率值(Fresnel Reflectance Values for Semiconductors)

  正如你想的那样,半导体有着介于最亮的电介质和最暗的金属的\(F_0\)值,如下表所示

img

在实践中很少需要渲染这样的物质,因为绝大多数被渲染的场景没有到处都是晶体硅块。在实践中应该避免介于\(0.2\)\(0.5\)之间的\(F_0\)值,除非你是有目的地想建模一个奇特或不现实的材质。

水中的菲涅尔反射率值(Fresnel Reflectance Values in Water)

  在我们之前的外反射讨论中,我们假设了被渲染的表面周围环绕着空气。如果不是,反射率会改变,这会取决于界面两边物质的折射率。我们因此需要把\(F_0 = \left(\frac{n-1}{n+1}\right)^2\)式中的\(n\)替换成\(n_1/n_2\),因此就有如下更一般的公式

\[F_0 = \left(\frac{n_1-n_2}{n_1+n_2}\right)^2 \]

  在水下进行渲染时,一般会使用这个公式。由于水的折射率大约为空气折射率的\(1.33\)倍,\(F_0\)的值在水中会有所不同。相比于金属来说,这对于电介质造成的影响更大。

参数化菲涅尔值(Parameterizing Fresnel Values)

  一个通常被使用的参数化会结合镜面反射颜色\(F_0\)和漫反射颜色\(\rho_\text{ss}\)。这个参数化主要利用了金属没有漫反射颜色以及电介质有着受限可能的\(F_0\)值,而且它包含了一个RGB表面颜色\(\mathbf{c}_\text{surf}\)和一个标量值\(m\),这个标量值被称为“金属度”。如果\(m=1\),那么\(F_0\)会被设置为\(\mathbf{c}_\text{surf}\)\(\rho_\text{ss}\)会被设置为黑色。如果\(m=0\),那么\(F_0\)会被设置为一个电介质值,\(\rho_\text{ss}\)会被设置为\(\mathbf{c}_\text{surf}\)
  “金属度”最早出现在被Brown大学使用的早期着色模型中,参数化目前的形式最开始被用于Pixar的Wall-E电影。对于迪士尼通用Disney Principled)着色模型来说,它被用于Wreck-It Ralph以及后续的迪士尼动画电影中,Burley增加了一个额外的标量“镜面反射”参数来在有限的范围内控制电介质\(F_0\)。这一形式的参数化被用于Unreal引擎中,而Frostbite引擎则使用一个有着更大范围的可能的电介质\(F_0\)的一个略微不同的形式。游戏Call of Duty: Infinite Warfare使用了一个变体来打包金属度和镜面反射参数到一个值,这节省了一些内存。
  对于那些使用金属度参数化而不是直接使用\(F_0\)\(\rho_\text{ss}\)渲染的应用来说,这背后主要的动机包括用户便捷性和节省纹理或G缓冲存储空间。在游戏Call of Duty: Infinite Warfare中,这个参数化被用于了一个不寻常的方法中。美术师会为了\(F_0\)\(\rho_\text{ss}\)绘制纹理,这些纹理会被自动地转化为金属度参数化,作为一个压缩方法。
  使用金属度有着一些缺点。它不能被用来表示某些材质类型,比如有着色偏的\(F_0\)值的涂层电介质。伪影会发生在金属和电介质之间的边界处。
  另一个实时应用参数化技巧利用了除了特殊的抗反射涂层外没有材质有着低于\(0.02\)\(F_0\)值这一事实。这个技巧被用来抑制表面上表示凹陷或空洞的区域的镜面高光。与其使用一个分开的镜面反射遮蔽纹理,低于\(0.02\)\(F_0\)值可以被用来“关闭”菲涅尔边缘增亮。这个技术首先由Sch¨uler提出,并被Unreal和Frostbite引擎使用。

内反射(Internal Reflection)

  尽管外反射在渲染中是最常遇到的,内反射有时也是很重要的。内反射会发生在\(n_1>n_2\)时。用另一句话来说,内反射会发生在光在透明物体的内部传播并在内部碰到物体的表面时,下方为一张示例图

img

在外反射中,一个有效的(更小的)$\sin\theta_t$的值对应着每个0到1之间的$\sin\theta_i$。这对于内反射而言并不成立。对于大于**临界角**(**Critical Angle**)$\theta_c$的$\theta_i$来说,斯涅尔定律($\sin(\theta_t)=\frac{n_1}{n_2}\sin(\theta_i)$)会要求$\sin\theta_t>1$,然而这没有解。在现实中,当$\theta_i>\theta_c$时,不会有透射光,所有的入射光都会被反射。这个现象被称为**全内反射**(**Total Internal Reflection**)。

  菲涅尔方程是对称的,也就是说入射向量和透射向量可以被调换,反射率依然会保持不变。结合斯涅尔定律,这个对称性意味着\(F(\theta_i)\)对于内反射来说会和一个“压缩后的”外反射曲线版本相似。\(F_0\)对于内反射和外反射来说都是一样的,内反射曲线会在\(\theta_c\)时到达完美反射率而不是在\(90^\circ\)时。下图为一张内反射率曲线和外反射率曲线的示例图

img

从图中可以看出从总体上来说内反射的反射率更高一些。比如,这就是为什么水下的空气泡看起来高度反光且有着银色的外表。
  内反射只发生在电介质上,因为金属和半导体会快速吸收任何在内部传播的光。由于电介质有着实数反射率,从折射率或\(F_0\)计算临界角非常直接,公式如下

\[\sin\theta_c = \frac{n_2}{n_1} = \frac{1-\sqrt{F_0}}{1+\sqrt{F_0}} \]

  通过把\(\theta_i\)替换成透射角度\(\theta_t\),Schlick近似可以被用于内反射。如果透射方向\(\mathbf{t}\)已经被计算出来了,那么它可以被用来找到\(\theta_t\)。要不然的话就需要使用斯涅尔定律来从\(\theta_i\)计算\(\theta_t\),但是这个过程的开销是昂贵的,而且需要折射率,可能在有些情况下是做不到的。

微观几何(Microgeometry)

  我们之前讨论过,表面上尺度小于一个像素的不平整结构是没有被显式建模的可行性的,BRDF因此统计地建模它们聚集起来的效果。现在,我们仍然保持使用几何光学,它假设不平整结构要不小于光的波长要不大于光的波长。尺度在这之间的“波光学域”的不平整结构的影响将在后续的部分被讨论。
  每个可见表面的点都包含着许多将光弹射到不同方向的微表面法线。由于单独微平面的朝向在一定程度上是随机的,因此用统计分布来建模它们有着合理性。对于大多数表面来说,微几何表面法线的分布是连续的,在宏观表面法线处有峰值。这个分布的“集中程度”由表面粗糙度决定。表面越粗糙,微几何法线分布得越广。
  微观尺度的粗糙度越高,物体反射的环境细节就会越模糊。对于小的明亮的光源来说,反射结果会更广而且镜面高光会更昏暗。更粗糙的表面有更暗的效果是因为光的能量往更大范围的方向上传播了。下方的现实中的摄影例子可以证实这一点。

img

  下图展示了每个微观尺度的表面细节的反射的聚集效果

img

上面这几张图像展示了被单一光源点亮的表面,可以看到凹凸的尺度在不断降低,直到尺度小于单个像素。许多微小高光的统计分布最终变成了聚集在一起的高光的形状中的细节。例如,周围的每个凹凸高光的相对稀疏度变成了远离中心的聚集高光的相对昏暗度。
  对于大多数表面来说,微观尺度的的表面法线分布是各向同性Isotropic)的,这意味着分布是旋转对称的,没有任何内在的方向性。另外一些表面则有着各向异性Anisotropic)微观尺度结构。这样的表面有着各向异性的表面法线分布,这会导致方向上的反射模糊和高光。下图是个相关的例子

img

  有一些表面有着高度结构化的微观几何结构,导致了各种微观尺度的法线分布和表面外表。织物就是常见的一个例子,表面上的天鹅绒和缎面因为它们各自的微观几何结构,有着独特的外表。织物的模型会在Section 9.10讨论。
  尽管多个表面法线是微观几何对反射的主要影响,其它方面的影响也很重要。阴影遮蔽Shadowing)指代微观尺度的表面细节对光源的遮挡,下图是个相关的例子

img

一些面相对于相机造成的(视线)遮挡Masking)如下图所示。

img

  如果微观几何的高度和表面法线是相互关联的,那么阴影遮蔽和视线遮挡能有效地改变法线的分布。例如,想象一个表面的隆起部分已经被风化或其它过程平滑化了,更低的部分则保持粗糙。在掠射角,表面的更低部分会趋向于被阴影遮蔽或视线遮挡,这样会导致一个等效地更平滑的表面。下图是个相关的示例图。

img

  对于所有的表面类型来说,表面的不平整结构的可见大小会随着入射角\(\theta_i\)的增大而减小。在极端的掠射角附近,不平整结构的观测尺寸可以比光的波长还要小,这会让这些不平整结构“消失”。当视线方向和光照方向与表面法线的夹角接近\(90^\circ\)时,这两个影响与菲涅尔效应会让表面表现得高度反光且像镜子一样。
  被微观尺度的表面细节遮挡的光不会消失。它会被反射,也许会被传播到其它的微观几何结构。光在到达眼睛前会经历多次这样的弹射。这样的一种交互如下图所示

img

由于光在每次反射时会被菲涅尔反射率衰减,多次反射在电介质中趋向于很微弱。由于金属缺乏次表面散射,多次弹射的反射因此是任何可见的漫反射的来源。来自有色金属的多次弹射的反射会相比于首次反射的光的颜色会更深,因为这些光与表面交互了很多次。
  至今为止,我们讨论了微观几何对镜面反射的影响。在某些情况下,微观尺度的表面细节也会影响次表面反射。如果微观几何的不平整结构比次表面散射的距离要大,那么阴影遮蔽和视线遮挡会导致逆反射Retroreflection)效应,光会被优先向入射方向反射。这个效应会发生是因为当视线方向和光照方向差异很大时,阴影遮蔽和视线遮挡会遮挡光亮区域。下图是个相关的示意图

img

逆反射倾向于给予表面平整的外表,下图是个相关的例子

img

微平面理论(Microfacet Theory)

  许多BRDF都基于被称为微平面理论Microfacet Theory)的微观几何对反射率的影响的数学分析。这个工具首先由光学社区的研究员开发出来。它在1977年由Blinn并且在1981年又一次由Cook和Torrance被引入计算机图形学。这个理论基于微观几何作为微平面Microfacet)的集合的建模。
  这些微小的面都是平整的,每个都有着微平面法线\(\mathbf{m}\)。每个微平面都根据微观BRDF \(f_\mu(\mathbf{l},\mathbf{v},\mathbf{m})\)反射光线,所有微平面的反射率的结合就是总的表面BRDF。对于每个微平面来说,通常的选择是让它们为完美的菲涅尔镜面,这导致了一个用于建模表面反射的镜面反射型微平面BRDF。然而,其它的选择也是可能的。有些漫反射型微观BRDF被用来创造一些局部次表面散射模型。一个衍射型微观BRDF可以被用来创建一个结合几何光学和波光学效应的着色模型。
  微平面模型一个重要的属性是微平面法线\(\mathbf{m}\)的统计分布。这个分布是通过表面的法线分布函数Normal Distribution FunctionNDF)定义的。有一些文献会使用法线的分布Distribution Of Normal)这一术语来避免与高斯正态分布之间的混淆。我们将会使用\(D(\mathbf{m})\)来指代方程中的NDF。
  NDF \(D(\mathbf{m})\)是微平面的表面法线在微观几何的表面区域的统计分布。在微平面法线的整个球面上积分\(D(\mathbf{m})\)可以得到微表面的面积大小。更有用的是,积分\(D(\mathbf{m})(\mathbf{n} \cdot \mathbf{m})\)(投影\(D(\mathbf{m})\)到宏观表面平面),可以得到按照约定等于1的宏观表面区域面积,下图是个相关的示意图

img

用另一句话来说,\(D(\mathbf{m})(\mathbf{n} \cdot \mathbf{m})\)是归一化的,即

\[\int_{\mathbf{m} \in \Theta} D(\mathbf{m})(\mathbf{n} \cdot \mathbf{m}) d\mathbf{m} = 1 \]

积分区域为\(\Theta\)表示的整个球面,这和前面的半球(\(\Omega\))积分不一样。这个符号被使用于绝大多数图形学文献中,尽管有些文献使用\(\Omega\)来指代整个球面。在实践中,绝大多数在图形学中使用的微结构模型都是高度场,这意味着对于所有的在\(\Omega\)之外的方向\(\mathbf{m}\)来说,都有\(D(\mathbf{m})=0\)。然而,上面这个式子对非高度场微结构也是有效的。
  更一般地来说,微表面和宏观表面投影到与视线方向\(\mathbf{v}\)垂直的任意平面都是相等的,即

\[\int_{\mathbf{m} \in \Theta} D(\mathbf{m})(\mathbf{v} \cdot \mathbf{m}) d\mathbf{m} = \mathbf{v} \cdot \mathbf{n} \]

上方的两个公式的点乘都没有被钳制到0,下面这张图展示了为什么不能进行钳制

img

如果\(D(\mathbf{m})\)是个有效的NDF,那么它必须符合上述两个公式。
  直观地来说,NDF就像是微平面法线的直方图。在微平面法线更有可能指向的方向有着较高的值。绝大多数的表面有的NDF在宏观表面法线\(\mathbf{n}\)附近有着尖峰。
  让我们再看看上图。尽管有着许多重叠投影,我们最终关心的是可见的微平面,比如在每个重叠集合中距离相机最近的微平面。可见的微平面的投影面积会等于宏观平面的投影面积。这个事实提供了另一个联系投影的微平面面积和投影的宏观几何面积的途径,可见的微平面的投影面积等于宏观平面的投影面积。我们可以通过定义视线遮挡函数Masking Function\(G_1(\mathbf{m},\mathbf{v})\)从数学上来表示,这个函数能告诉我们微平面法线\(\mathbf{m}\)对于视线方向\(\mathbf{v}\)来说有多少比率是可见的。\(G_1(\mathbf{m},\mathbf{v})D(\mathbf{m})\text{max}(0,\mathbf{v}\cdot\mathbf{m})\)在球面上的积分因此就是宏观表面投影到与\(\mathbf{v}\)垂直的平面上的面积,即

\[\int_{\mathbf{m} \in \Theta} G_1(\mathbf{m},\mathbf{v}) D(\mathbf{m}) \text{max}(0,\mathbf{v}\cdot\mathbf{m}) d\mathbf{m} = \mathbf{v} \cdot \mathbf{n} \]

这里要进行钳制是因为背面是不可见的。\(G_1(\mathbf{m},\mathbf{v}) D(\mathbf{m})\)是可见法线的分布。
  尽管上式对\(G_1(\mathbf{m},\mathbf{v})\)施加了约束,但是并没有直接决定\(G_1(\mathbf{m},\mathbf{v})\)。对于给定的微平面法线分布\(D(\mathbf{m})\)来说有无限种满足约束的函数。这是因为\(D(\mathbf{m})\)没有完全地声明微表面。它只告诉了有多少微平面面向某个方向,但是没有告诉这些微平面是如何排布的。
  在这些年中,各种各样的\(G_1\)函数已经被提出了,Heitz的杰出论文解决了该使用哪个函数的困境。Heitz讨论了Smith视线遮挡函数,它最初是针对高斯分布推导得到的,后来泛化到了任意NDF。Heitz在它的文献中展示了一些视线遮挡函数,结果只有Smith函数和Torrance-Sparrow的“V-cavity”函数遵从上方的公式。他进一步指出Smith函数能更好地匹配随机的微表面的行为。Heitz也证明了Smith视线遮挡函数是唯一可能的遵从上方的公式并具有法线与遮挡独立性Normal-masking Independence)的函数。这意味着\(G_1(\mathbf{m},\mathbf{v})\)不依赖于\(\mathbf{m}\),只要\(\mathbf{m}\)不是背离的。Smith \(G_1\)函数的形式如下

\[G_1(\mathbf{m},\mathbf{v}) = \frac{\text{max}(0,\mathcal{X}(\mathbf{m}\cdot\mathbf{v}))}{1+\Lambda(\mathbf{v})} \]

其中\(\text{max}(0,\mathcal{X}(x))\)

\[\text{max}(0,\mathcal{X}(x)) = \begin{cases} 1, & \text{当} x>0 \\0, & \text{当} x \leq 0 \end{cases} \]

\(\Lambda\)函数对于每个NDF来说不一样。Walter等人和Heitz的文献中提到了为一个给定NDF得出\(\Lambda\)的流程。
  Smith视线遮挡函数有一些缺点。从理论上说,其所依赖的假设与真实表面的微观结构并不一致,并且甚至在现实中是物理上不可能的。从实践的角度来看,虽然它对于随机表面来说是非常准确的,但是对于那些法线方向和视线遮挡有着更强关联的表面来说准确度会降低,尤其是当表面有着重复结构时。尽管如此,直到有个更好的替代方法事前,这个函数对于绝大多数渲染应用来说是最好的选择。
  给定一个包含微观BRDF \(f_\mu(\mathbf{l},\mathbf{v},\mathbf{m})\)、法线分布函数\(D(\mathbf{m})\)、视线遮挡函数\(G_1(\mathbf{m},\mathbf{v})\)的微几何描述,总体的宏观表面BRDF可以由如下的公式得出

\[f(\mathbf{l},\mathbf{v}) = \int_{\mathbf{m} \in \Omega} f_\mu(\mathbf{l},\mathbf{v},\mathbf{m}) G_2(\mathbf{l},\mathbf{v},\mathbf{m}) D(\mathbf{m}) \frac{\text{max}(0,\mathbf{m}\cdot\mathbf{l})}{|\mathbf{n}\cdot\mathbf{l}|} \frac{\text{max}(0,\mathbf{m}\cdot\mathbf{v})}{|\mathbf{n}\cdot\mathbf{v}|} d\mathbf{m} \]

积分区域是以\(\mathbf{n}\)为中心的半球,因为要避免收集来自表面之下的光的贡献。上述公式使用了联合遮挡-阴影函数Joint Masking-shadowing Function\(G_2(\mathbf{l},\mathbf{v},\mathbf{m})\),而不是视线遮挡函数\(G_1(\mathbf{m},\mathbf{v})\)\(G_2\)这个函数来自\(G_1\),它能告诉我们有着法线\(\mathbf{m}\)的微平面有多少比率是相对于视线方向\(\mathbf{v}\)和光照\(\mathbf{l}\)同时可见的。这能让BRDF把视线遮挡和阴影遮蔽纳入考量,但是并没有考虑到微平面之间的多次反射。因此,这是从上述公式衍生的所有BRDF共同具有的一个限制。这种BRDF看起来会暗一些。我们后续将讨论一些解决这个限制的方法。
  Heitz讨论了\(G_2\)函数的一些版本。最简单的是可分形式,视线遮挡和阴影遮蔽会使用\(G_1\)分开进行评估,并且最后乘到一起,公式如下

\[G_2(\mathbf{l},\mathbf{v},\mathbf{m}) = G_1(\mathbf{v},\mathbf{m}) G_1(\mathbf{l},\mathbf{m}) \]

它假设视线遮挡和阴影遮蔽是不相关的事件。然而在现实中不是这样的,这样的一个假设会导致过暗的BRDF。想象一个极端的例子,当视线方向和光照方向相同时,\(G_2\)应该等于\(G_1\)
  如果微表面是个高度场(通常是用于渲染中的微表面模型),那么当\(\mathbf{v}\)\(\mathbf{l}\)之间的相对偏航角\(\phi\)等于\(0^\circ\)时,\(G_2(\mathbf{l},\mathbf{v},\mathbf{m})\)应该等于\(\text{min}(G_1(\mathbf{v},\mathbf{m}),G_1(\mathbf{l},\mathbf{m}))\)。这个联系提供了一个通用的来考量视线遮挡和阴影遮蔽相互之间的关系的方法,即

\[G_2(\mathbf{l},\mathbf{v},\mathbf{m}) = \lambda(\phi)G_1(\mathbf{v},\mathbf{m})G_1(\mathbf{l},\mathbf{m})+(1-\lambda(\phi))\text{min}(G_1(\mathbf{v},\mathbf{m}),G_1(\mathbf{l},\mathbf{m})) \]

其中\(\lambda(\phi)\)是随着角度\(\phi\)增加从0增长到1的函数。Ashikhmin等人建议使用一个有着\(15^\circ\)标准差的高斯函数

\[\lambda(\phi) = 1-e^{-7.3\phi^2} \]

Ginneken等人提出使用

\[\lambda(\phi) = \frac{4.41\phi}{4.41\phi+1} \]

  不考虑光照方向和视线方向的同向性,还有其它的原因让视线遮挡和阴影遮蔽在给定的表面点处相互关联。两者都和点与表面其它地方的相对高度相关。对于更低的点来说,视线遮挡的概率会升高,阴影遮蔽的概率也一样。如果使用的是Smith视线遮挡函数,这个相互关联可以使用Smith高度相关遮挡-阴影函数Smith Height-correlated Masking-shadowing Function )来考量。

\[G_2(\mathbf{l},\mathbf{v},\mathbf{m}) = \frac{\text{max}(0,\mathcal{X}(\mathbf{m} \cdot \mathbf{v}))\text{max}(0,\mathcal{X}(\mathbf{m} \cdot \mathbf{l}))}{1+\Lambda(\mathbf{v})+\Lambda(\mathbf{l})} \]

Heitz也描述了一种结合方向和高度的相互关系的Smith \(G_2\)形式

\[G_2(\mathbf{l},\mathbf{v},\mathbf{m}) = \frac{\text{max}(0,\mathcal{X}(\mathbf{m}\cdot\mathbf{v}))\text{max}(0,\mathcal{X}(\mathbf{m}\cdot\mathbf{l}))}{1+\text{max}(\Lambda(\mathbf{v}),\Lambda(\mathbf{l}))+\lambda(\mathbf{v},\mathbf{l})\text{min}(\Lambda(\mathbf{v}),\Lambda(\mathbf{l}))} \]

其中的\(\lambda(\mathbf{v},\mathbf{l})\)可以是个经验公式,又或者是NDF特定的函数。
  除了这些替代方法,Heitz建议使用Smith函数的高度相关的形式,因为这一形式和非相关的形式有着相似的开销并且更加精确,它在实践中是最常被使用的,尽管有些人选择使用可分的形式。
  一般形式的微平面BRDF在渲染中没有被直接使用。对于一个给定的微观BRDF \(f_\mu\)来说,它会被用来推导一个闭式解方案(精确或近似)。这种类型推导的一个例子将会在下一个部分被展示。

用于表面反射的BRDF模型(BRDF Models for Surface Reflection)

  除了一些例外情况,在基于物理的渲染中使用的镜面反射BRDF项来自微平面理论。在镜面型表面反射的情况中,每个微平面都是完美平滑的菲涅尔镜面。这里要回顾下之前的内容,这样的一个镜面会把入射光反射到一个单一方向上,并使其衰减。这意味着当光入射方向\(\mathbf{l}\)的反射向量\(\mathbf{r}\)不与\(\mathbf{v}\)平行时,每个面的微观BRDF \(f_\mu(\mathbf{l},\mathbf{v},\mathbf{m})\)都为0。因此,在这种情况下只有法线为\(\mathbf{l}\)\(\mathbf{v}\)半程向量Half Vector\(\mathbf{h}\)的微平面才能把入射光\(\mathbf{l}\)反射到\(\mathbf{v}\)方向。下面是半程向量的相关示例图以及具体的计算方式。

img

\[\mathbf{h} = \frac{\mathbf{l}+\mathbf{v}}{||\mathbf{l}+\mathbf{v}||} \]

  这样的一个菲涅尔镜面反射微观BRDF \(f_\mu(\mathbf{l},\mathbf{v},\mathbf{m})\)让半球积分变成了一次在\(\mathbf{m}=\mathbf{h}\)处的评估。因此就有了如下的镜面反射BRDF项

\[f_\text{spec}(\mathbf{l},\mathbf{v})=\frac{F(\mathbf{h},\mathbf{l})G_2(\mathbf{l},\mathbf{v},\mathbf{h})D(\mathbf{h})}{4|\mathbf{n}\cdot\mathbf{l}||\mathbf{n}\cdot\mathbf{v}|} \]

推导的细节可以在Walter等人、Heitz、Hammon的文献中找到。Hammon也展示了一个优化BRDF实现的方法,计算\(\mathbf{n} \cdot \mathbf{h}\)\(\mathbf{l}\cdot\mathbf{h}\)而不是\(\mathbf{h}\)
  我们在这里使用\(f_\text{spec}\)用于上方公式的BRDF项来表示它只建模表面的镜面反射。在一个完整的BRDF中,它会与另一个建模次表面(漫反射)着色的项配对。为了记忆并理解上方的公式我们可以这么想,\(D\)项是在计算反射\(\mathbf{l}\)方向上的入射光到\(\mathbf{v}\)方向上的微平面有多少比率。乘以\(G_2\)项是因为部分反射光会被微观的表面细节遮挡。乘以\(F\)项是因为每个微平面虽然是完美平滑的菲涅尔镜面,但是反射光会有能量损失。
  使用半程向量后遮挡-阴影函数可以有个小简化。由于涉及的角度不会超过\(90^\circ\),之前提到的公式中的\(\text{max}(0,\mathcal{X}(x))\)可以被移除。

法线分布函数(Normal Distribution Function)

  法线分布函数对于被渲染的表面的外表有着显著的影响。绘制在微平面法线的球面上的NDF的形状决定了反射光线的锥形分布的(镜面反射瓣)形状和宽度,于是相继决定了镜面反射高光的形状和尺寸。NDF会影响表面粗糙度的整体感知,以及更多的微小的视觉方面,比如高光是否有明显的边缘或是否被朦胧的泛光环绕。
  然而,镜面反射瓣不是NDF形状的简单拷贝。取决于表面的曲率和观察角度,高光的形状会有更大或更低程度的畸变。对于以掠射角被观察的水平表面来说,畸变会尤为强烈,下方为一张相关的示例图

img

Ngan等人展示了他们对畸变背后的原因的分析。

各向同性的法线分布函数(Isotropic Normal Distribution Function)

  绝大多数渲染中使用的NDF都是各向同性的,也就是关于表面法线\(\mathbf{n}\)旋转对称的。在这种情况下,NDF只和\(\mathbf{n}\)与微平面法线\(\mathbf{m}\)之间的角度有关。理想地来说,NDF可以用\(\cos\theta_m\)的表达式,这样计算起来效率更高。
  Beckmann NDF由光学社区开发而来,是最早一批微平面模型使用的法线分布。这个函数仍然还在被大范围使用。它也是Cook-Torrance BRDF选择的NDF。归一化的Beckmann分布的形式如下

\[D(\mathbf{m}) = \frac{\text{max}(0,\mathbf{n}\cdot\mathbf{m})}{\pi \alpha_b^2(\mathbf{n} \cdot \mathbf{m})^4} \text{exp} \left( \frac{(\mathbf{n}\cdot\mathbf{m})^2-1}{\alpha_b^2(\mathbf{n}\cdot\mathbf{m})^2} \right) \]

这里的\(\text{max}(0,\mathbf{n}\cdot\mathbf{m})\)确保了NDF的值对于指向宏观表面下方的微平面法线都为0。这一属性告诉了我们,这个NDF以及这个部分讨论的其它NDF描述了一个高度场微表面。参数\(\alpha_b\)控制着表面粗糙度。它与微观几何表面的均方根(Root Mean Square,RMS)坡度成正比,\(\alpha_b=0\)因此表示一个完美光滑的表面。
  为了给Beckmann NDF推导Smith \(G_2\)函数,我们需要对应的\(\Lambda\)函数。Beckmann NDF是形状不变的Shape-invariant),这简化了\(\Lambda\)的推导。如Heitz定义的那样,如果粗糙度参数的影响等价于缩放微表面,那么一个各向异性NDF是形状不变的。形状不变的NDF可以写作如下的形式。

\[D(\mathbf{m}) = \frac{\text{max}(0,\mathcal{X}(\mathbf{n}\cdot\mathbf{m}))}{\alpha^2(\mathbf{n}\cdot\mathbf{m})^4} g \left( \frac{\sqrt{1-(\mathbf{n}\cdot\mathbf{m})^2}}{\alpha(\mathbf{n}\cdot\mathbf{m})} \right) \]

其中的\(g\)表示一个任意的一元函数函数。对于一个任意各向同性的NDF来说,\(\Lambda\)取决于两个变量。一个是粗糙度\(\alpha\),另一个是向量\(\mathbf{v}\)\(\mathbf{l}\)的入射角。然而,对于形状不变的NDF来说,\(\Lambda\)只取决于\(a\)这个变量,它的计算公式为

\[a = \frac{\mathbf{n} \cdot \mathbf{s}}{\alpha \sqrt{1-(\mathbf{n}\cdot\mathbf{s})^2}} \]

其中的\(\mathbf{s}\)表示\(\mathbf{v}\)\(\mathbf{l}\)。只取决于一个变量的\(\Lambda\)对于实现来说很便捷。可以更加轻松地使用近似曲线来拟合一元函数,而且可以制为一维数组的表。
  Beckmann NDF对应的\(\Lambda\)函数为

\[\Lambda(a) = \frac{\text{erf}(a)-1}{2} + \frac{1}{2a\sqrt{\pi}} \text{exp}(-a^2) \]

这个公式由于包含\(\text{erf}\),因此评估的开销很昂贵。因此,通常需要使用近似方法

\[\Lambda(a) \approx \begin{cases} \frac{1-1.259a+0.396a^2}{3.535a+2.181a^2}, & \text{当}a<1.6 \\ 0, & \text{当}a \geq 1.6 \end{cases} \]

  接下来讨论的NDF是Blinn-Phong NDF。它在过去被计算机图形学广泛地使用,尽管在当下已经被其它分布替代了。当计算的开销很宝贵时,Blinn-Phong NDF会被使用,因为它的开销没有这个部分中其它的NDF那么大。
  Blinn-Phong NDF由Blinn推导出,作为(基于非物理的)Phong着色模型的修改,它的公式如下

\[D(\mathbf{m}) = \text{max}(0,\mathcal{X}(\mathbf{n}\cdot\mathbf{m})) \frac{\alpha_p+2}{2\pi} \]

指数\(\alpha_p\)是Phong NDF的粗糙度参数。较高的值表示光滑表面,较低的值则表示粗糙的表面。\(\alpha_p\)可以非常高,用于非常光滑的表面,完美的镜面要求\(\alpha_p = \infty\)。如果需要随机的表面(均匀NDF),那么可以设置\(\alpha_p=0\)\(\alpha_p\)操纵起来不便捷,因为它的视觉影响是高度不均匀的。小的数值改变对于小的\(\alpha_p\)值来说影响很大,但是对于较大的之来说则没那么大的影响。因此,\(\alpha_p\)通常会由用户操纵的参数通过非线性映射计算而来。比如,\(\alpha_p=m^s\),其中\(s\)是个介于0到1的参数,而\(m\)\(\alpha_p\)的上界。这个映射被用于一些游戏中,比如Call of Duty:Black Ops,在这个游戏中\(m\)被设置到了8192。

Beckmann和Blinn-Phong粗糙度参数的等价关系为\(\alpha_p=2\alpha_b^{-2}-2\)。当参数以这样一个关系匹配时,这两个分布会非常接近,特别是对于光滑的表面来说,正如下方的示例图所示

img

  Blinn-Phong NDF不是形状不变的,并且它对应的\(\Lambda\)函数的解析形式不存在。Walter等人建议使用等价的\(\alpha_b\)值,并利用Beckmann \(\Lambda\)函数进行计算。
  在同一篇1977年的论文中,Blinn采纳了Phong着色函数,以这个函数为基础开发出了一个微平面NDF,他也提出了其他两个NDF。在这三个分布中,Blinn推荐由Trowbridge和Reitz推导的那一个。这个建议在当时没有被太多人留意到,但是30年后,Trowbridge-Reitz分布被Walter等人独立重新发现,这些人将其命名为GGX分布。自那以后,这个分支快速得到了认可。在几年间,GGX分布开始被传播到了影视和游戏领域。而在如今,这个分布几乎是影视和游戏领域总是会使用的。在这本书中,我们将会使用GGX。
  GGX分布为

\[D(\mathbf{m}) = \frac{\text{max}(0,\mathcal{X}(\mathbf{n}\cdot\mathbf{m}))\alpha_g^2}{\pi(1+(\mathbf{n}\cdot\mathbf{m})^2(\alpha_g^2-1))^2} \]

\(\alpha_g\)参数提供的粗糙度控制和Beckmann中的\(\alpha_b\)参数提供的粗糙度控制相似。在迪士尼通用着色模型中,Burley提到给予用户的粗糙度控制为\(\alpha_g=r^2\),其中\(r\)为用户界面的粗糙度参数,取值在0到1之间。这能让粗糙度控制更线性,这个映射已经被大多数使用GGX分布的应用采纳。
  GGX分布是形状不变的,它对应的\(\Lambda\)函数相对来说很简单

\[\Lambda(a) = \frac{-1+\sqrt{1+\frac{1}{a^2}}}{2} \]

可以看到上式需要计算\(a^2\),这会让\(a = \frac{\mathbf{n} \cdot \mathbf{s}}{\alpha \sqrt{1-(\mathbf{n}\cdot\mathbf{s})^2}}\)的计算便捷一些,因为省略掉了平方根。
  由于GGX分布和Smith遮挡-阴影函数的受欢迎程度,有许多人致力于优化两者的结合。Lagarde观察到用于GGX的高度相关Smith \(G_2\)在与镜面微平面BRDF的分母结合时,其中有一些项会相互抵消。结合后的项因此可以简化为

\[\frac{G_2(\mathbf{l},\mathbf{v})}{4|\mathbf{n}\cdot\mathbf{l}||\mathbf{n}\cdot\mathbf{v}|} \Longrightarrow \frac{0.5}{\mu_o \sqrt{\alpha^2+\mu_i(\mu_i-\alpha^2\mu_i)}+\mu_i\sqrt{\alpha^2+\mu_o(\mu_o-\alpha^2\mu_o)}} \]

其中\(\mu_i=\text{max}(0,\mathbf{n}\cdot\mathbf{l})\),而\(\mu_o=\text{max}(0,\mathbf{n}\cdot\mathbf{v})\)。Karis提出了一个用于GGX的Smith \(G_1\)函数的近似形式,公式如下

\[G_1(s) \approx \frac{2(\mathbf{n}\cdot\mathbf{s})}{(\mathbf{n}\cdot\mathbf{s})(2-\alpha)+\alpha} \]

其中的\(\mathbf{s}\)可以使用\(\mathbf{l}\)\(\mathbf{v}\)来替代。Hammon指出这个近似形式可以为“高度相关Smith \(G_2\)函数与镜面BRDF分母组合项”提供一个高效的近似,公式如下

\[\frac{G_2(\mathbf{l},\mathbf{v})}{4|\mathbf{n}\cdot\mathbf{l}||\mathbf{n}\cdot\mathbf{v}|} \approx \frac{0.5}{\text{lerp}(2|\mathbf{n}\cdot\mathbf{l}||\mathbf{n}\mathbf{v}|,|\mathbf{n}\cdot\mathbf{l}|+|\mathbf{n}\cdot\mathbf{v}|,\alpha)} \]

\(\text{lerp}\)为简单的线性插值,即\(\text{lerp}(a,b,s) = a(1-s)+bs\)
  GGX与Beckmann分布的比较如下

img

上方的为Beckmann分布,下方的为GGX分布。可以看到两者从根本上有不同的形状。GGX具有更尖锐的峰值,同时在峰值周围具有更长的尾部。此外我们还可以看到GGX的更长的尾部创造了高光核心周围的朦胧或泛光。
  许多现实世界的材质会展示类似的朦胧高光,尾部甚至通常比GGX分布还要长。这也是GGX以及新的能更准确地拟合这种效果的分布越来越受欢迎的原因。
  Burley提出了广义 Trowbridge-ReitzGeneralized Trowbridge-ReitzGTR)NDF,它的目的是为了提供NDF形状的更多控制,尤其是分布的尾部

\[D(\mathbf{m}) = \frac{k(\alpha,\gamma)}{\pi(1+(\mathbf{n}\cdot\mathbf{m})^2(\alpha_g^2-1))^\gamma} \]

其中的\(\gamma\)参数控制着尾部的形状。当\(\gamma=2\)时,GTR和GGX一样。当\(\gamma\)降低时,尾部的分布会变得更长,反之则相反。在较高的\(\gamma\)值,GTR分布会和Beckmann相似。\(k(\alpha,\gamma)\)项为归一化参数,它比较复杂,我们在下方给出它的公式

\[k(\alpha,\gamma) = \begin{cases} \frac{(\gamma-1)(\alpha^2-1)}{(1-(\alpha^2)^{(1-\gamma)})}, & \text{当}\gamma \neq 1 \text{并且} \alpha \neq 1\\ \frac{(\alpha^2-1)}{\text{ln}(\alpha^2)}, & \text{当}\gamma =1 \text{并且} \alpha \neq 1 \\ 1, & \text{当} \alpha = 1 \end{cases} \]

  GTR分布不是形状不变的,这让它的Smith \(G_2\)遮挡-阴影函数的推导变得复杂。在这个NDF被发表的三年后,一个\(G_2\)的推导才被发布。这个\(G_2\)的推导非常复杂,对于不同的\(\gamma\)有着不同的解析解。GTR具有的另一个问题是,\(\alpha\)\(\gamma\)对感知粗糙度和“泛光”的影响方式不直观。
  Student t 分布(Student's t-distributionSTD)和指数幂分布Exponential Power DistributionEPD)NDF包含了形状控制参数。和GTR相反,这些函数这些函数相对于其粗糙度参数是形状不变的。在写作的这一段时间,这些分布是最新发表的,它们的应用场景还不明确。
  除了使用更加复杂的NDF,一个替代方案是使用多个镜面反射瓣。这个想法由Cook和Torrance提出。这个方案被Ngan通过实验测试过,对于许多材质来说,他发现增加第二个反射瓣确实能改善拟合的质量。Pixar的PxrSurface材质有着一个“粗糙镜面反射”瓣,正是用于这个目的。额外的反射瓣是完整的镜面反射微平面BRDF,有着所有关联的参数和项。Imageworks实施了一个更加精细且针对性的方法,使用了两个GGX NDF的混合,作为一个扩展NDF被暴露给用户,而不是一个完全单独的镜面反射BRDF项。在这种情况下,需要的额外参数为第二个粗糙度值和一个混合量。

各向异性法线分布函数(Anisotropic Normal Distribution Function)

  尽管大多数材质有着各向同性的表面统计特性,但是有些材质的微结构所具有的各向异性能显著地影响它们的外表。为了精确地渲染这样的材质,我们需要别的BRDF,尤其是那些也是各向异性的NDF。
  不像各向同性的NDF,各向异性的NDF不能只使用\(\theta_m\)角度来评估。额外的方向信息会被需要。在一般情况下,微平面法线\(\mathbf{m}\)需要被变换到局部坐标系Local Frame)或由法线\(\mathbf{n}\)、切线\(\mathbf{t}\)、副切线\(\mathbf{b}\)定义的切线空间Tangent Space)中。在实践中,这个变换通常会由三个点乘来表达,分别为:\(\mathbf{m}\cdot\mathbf{n}\)\(\mathbf{m}\cdot\mathbf{t}\)\(\mathbf{m}\cdot\mathbf{b}\)
  当结合法线映射和各向异性BRDF时,让法线贴图扰动切线、副切线、法线向量是非常重要的。这个通常是通过应用改进的格拉姆–施密特正交化Modified Gram-Schmidt)过程到扰动后的法线\(\mathbf{n}\)和插值后的顶点切线\(\mathbf{t}_0\)以及副切线\(\mathbf{b}_0\)做到的

\[\mathbf{t}^\prime = \mathbf{t}_0 - (\mathbf{t}_0\cdot\mathbf{n})\mathbf{n} \Rightarrow \mathbf{t} = \frac{\mathbf{t}^\prime}{||\mathbf{t}^\prime||} \]

\[\mathbf{b}^\prime = \mathbf{b}_0 - (\mathbf{b}_0\cdot\mathbf{n})\mathbf{n} \]

\[\mathbf{b}^{\prime\prime} = \mathbf{b}^\prime - (\mathbf{b}^\prime \cdot \mathbf{t})\mathbf{t} \Rightarrow \mathbf{b} = \frac{\mathbf{b}^{\prime\prime}}{||\mathbf{b}^{\prime\prime}||} \]

  对于拉丝金属或卷曲毛发来说,逐像素的切线方向修改是被需要的,通常可以通过提供切线贴图Tangent Map)来做到。这个帖图存储每像素的切线,和法线贴图类似。切线贴图通常存储切线向量到与法线垂直的平面的二维投影。纹理滤波可以很好地用于这种切线贴图。有一些应用会存储标量的旋转量,它被用来绕着\(\mathbf{n}\)旋转切线向量。尽管这个表示更加紧凑,但是当旋转角度从\(360^\circ\)环绕到\(0^\circ\)时,纹理滤波容易出现错误。
  一个用来创建各向异性的NDF的方法是泛化一个现存的各向同性NDF。这种通用的方法可以应用于任何形状不变的各向同性NDF,这是形状不变的NDF受欢迎的另一个原因。回顾下之前的内容,各向同性的形状不变的NDF可以写作如下的形式

\[D(\mathbf{m})=\frac{\text{max}(0,\mathcal{X}(\mathbf{n}\cdot\mathbf{m}))}{\alpha^2(\mathbf{n}\cdot\mathbf{m})^4} g \left( \frac{\sqrt{1-(\mathbf{n}\cdot\mathbf{m})^2}}{\alpha(\mathbf{n}\cdot\mathbf{m})} \right) \]

其中的\(g\)是一元函数,它表示NDF的形状。那么各向异性版本为

\[D(\mathbf{m}) = \frac{\text{max}(0,\mathcal{X}(\mathbf{n}\cdot\mathbf{m}))}{\alpha_x\alpha_y(\mathbf{n}\cdot\mathbf{m})^4} g \left( \frac{\sqrt{\frac{(\mathbf{t}\cdot\mathbf{m})^2}{\alpha_x^2}+\frac{(\mathbf{b}\cdot\mathbf{m})^2}{\alpha_y^2}}}{(\mathbf{n}\cdot\mathbf{m})} \right) \]

其中\(\alpha_x\)\(\alpha_y\)分别表示沿着\(\mathbf{t}\)\(\mathbf{b}\)方向上的粗糙度。如果\(\alpha_x=\alpha_y\),那么上式会变回各向同性的形式。
  用于各向异性NDF的\(G_2\)遮挡-阴影函数和各向同性的一样,除了变量\(a\)的计算不同

\[a = \frac{\mathbf{n}\cdot\mathbf{s}}{\sqrt{\alpha_x^2(\mathbf{t}\cdot\mathbf{s})^2+\alpha_y^2(\mathbf{b}\cdot\mathbf{s})^2}} \]

其中的\(\mathbf{s}\)可以被\(\mathbf{v}\)\(\mathbf{l}\)替代。
  使用这个方法,Beckmann NDF的各向异性版本为

\[D(\mathbf{m}) = \frac{\text{max}(0,\mathcal{X}(\mathbf{n}\cdot\mathbf{m}))}{\pi\alpha_x\alpha_y(\mathbf{n}\cdot\mathbf{m})^4} \text{exp} \left( - \frac{\sqrt{\frac{(\mathbf{t}\cdot\mathbf{m})^2}{\alpha_x^2}+\frac{(\mathbf{b}\cdot\mathbf{m})^2}{\alpha_y^2}}}{(\mathbf{n}\cdot\mathbf{m})^2} \right) \]

GGX NDF的各向异性版本为

\[D(\mathbf{m}) = \frac{\text{max}(0,\mathcal{X}(\mathbf{n}\cdot\mathbf{m}))}{\pi a_x a _y\left( \frac{(\mathbf{t}\cdot\mathbf{m})^2}{a_x^2} + \frac{(\mathbf{b}\cdot\mathbf{m})^2}{a_y^2} + (\mathbf{n}\cdot\mathbf{m})^2 \right)^2} \]

这两个版本的示例图如下图所示,其中上方的为Beckmann NDF的各向异性版本

img

  最常用的用来参数化各向异性NDF的直接方法是使用各向同性粗糙度参数化两次,一次用于\(\alpha_x\)另一次用于\(\alpha_y\),当然了也有其它的参数化方法。在迪士尼通用着色模型中,各向异性粗糙度参数\(r\)会与第二个在区间\([0,1]\)的标量参数\(k_\text{aniso}\)结合。\(\alpha_x\)\(\alpha_x\)是使用如下的公式计算的

\[\begin{align*} k_\text{aspect} &= \sqrt{1-0.9k_\text{aniso}}\\ \alpha_x &= \frac{r^2}{k_\text{aspect}}\\ \alpha_y &= r^2 k_\text{aspect} \end{align*} \]

公式中的0.9限制了纵横比到10:1。
  Imageworks使用了一个不同的参数化,这个参数化允许任意程度的各向异性

\[\alpha_x = r^2 (1+k_\text{aniso})\\ \alpha_y = r^2 (1-k_\text{aniso}) \]

多次弹射的表面反射(Multiple-Bounce Surface Relfection)

  正如之前提到的那样,微平面BRDF框架没有考虑到多次从微表面反射的光线。这个简化会导致能量流失并且过暗,特别是对于粗糙的金属来说。
  Imageworks使用了一个技术,它结合了前人的研究成果中的一些元素,来创建一个可以被加入BRDF的项,用于模拟多次弹射的表面反射,公式如下

\[f_\text{ms}(\mathbf{l},\mathbf{v}) = \frac{\overline{F}\overline{R_\text{sF1}}}{\pi(1-\overline{R_\text{sF1}})(1-\overline{F}(1-\overline{R_\text{sF1}}))} (1-R_\text{sF1}(\mathbf{l}))(1-R_\text{sF1}(\mathbf{v})) \]

其中的\(R_\text{sF1}\)\(f_\text{sF1}\)的方向反照率,\(f_\text{sF1}\)\(F_0\)设置到1的镜面反射BRDF项。函数\(R_\text{sF1}\)取决于粗糙度\(\alpha\)和仰角\(\theta\)。它相对来说是平滑的,因此可以被预计算,并被存储到一个小的二维纹理中。Imageworks发现\(32 \times 32\)的分辨率就足够了。
  \(\overline{R_\text{sF1}}\)函数是\(R_\text{sF1}\)在半球上的余弦-加权平均值。它只取决于\(\alpha\),它因此可以被存储到一个一维纹理中,或者使用开销不那么昂贵的曲线进行拟合。由于\(R_\text{sF1}\)是关于\(\mathbf{n}\)旋转对称的,\(\overline{R_\text{sF1}}\)因此可以使用一维的积分来计算。令\(\mu=\cos\theta\)\(\overline{R_\text{sF1}}\)的积分为

\[\overline{R_\text{sF1}} = \frac{\int_{\mathbf{s} \in \Omega} R_\text{sF1}(\mathbf{s})(\mathbf{n} \cdot \mathbf{s}) d\mathbf{s}}{\int_{\mathbf{s} \in \Omega} (\mathbf{n}\cdot\mathbf{s}) d\mathbf{s}} = \frac{1}{\pi} \int_{\phi=0}^{2\pi} \int_{\mu=0}^1 R_\text{sF1}(\mu) \mu d\mu d\phi \\ = 2\int_{\mu=0}^{1} R_\text{sF1}(\mu) \mu d\mu \]

最后,\(\overline{F}\)是菲涅尔项的余弦加权平均,它的计算公式为

\[\overline{F} = 2 \int_{\mu=0}^1 F(\mu) \mu d\mu \]

Imageworks提供了一个闭式解方法

\[\overline{F} = \frac{2p^2 F_{90}+(3p+1)F_0}{2p^2+3p+1} \]

如果使用的是原始的Schlick近似方法,那么可以简化到

\[\overline{F} = \frac{20}{21} F_0 + \frac{1}{21} \]

对于各向异性的情况,Imageworks使用了一个在\(\alpha_x\)\(\alpha_y\)之间的中间粗糙度,用于计算\(f_\text{ms}\)。这个近似避免了\(R_\text{sF1}\)查找表的维度增加,而且产生的错误会很小。
  Imageworks的多次弹射的镜面反射项的结果如下图所示

img

用于次表面散射的BRDF模型(BRDF Models for Subsurface Scattering)

  在上一个章节我们讨论了表面、镜面反射。在这个章节我们讨论问题的另一边,也就是光折射的这一情况。正如我们之前讨论的那样,光在这种情况下会经历散射和吸收,部分会被弹射离开表面。我们在这里专注于用于局部次表面散射的BRDF模型,或不透明电介质内的漫反射表面响应。金属不太相关,因为它们没有任何显著的次表面光线交互。透明的或展现全局次表面散射的电介质会在第十四章被讨论。

光滑表面次表面模型(Smooth-Surface Subsurface Models)

  在这里,我们将讨论光滑表面次表面模型。这些模型很适用于表面不平整结构比次表面散射距离小时。在这种材质中,漫反射着色没有被表面粗糙度直接影响。
  如之前的部分提到的那样,实时渲染应用通常使用朗伯项建模局部次表面散射。在这种情况下,BRDF漫反射项是

\[f_\text{diff}(\mathbf{l},\mathbf{v}) = \frac{\rho_\text{ss}}{\pi} \]

  但是对于基于物理的着色来说,次表面散射的光是由折射的那一部分光贡献的,被反射的光因此不能贡献于次表面散射的光。为了改善这个模型,应该有镜面反射项和次表面反射项之间的能量权衡。菲涅尔效应告诉我们这个能量权衡受入射角\(\theta_i\)的影响。当入射角越来越掠射时,漫反射率会随着镜面反射率增加而减小。我们可以这么简单地想一想,没有被反射的量就是被折射的量,假设被反射的比率为\(F\),那么没有被反射的比率为\(1-F\),因此漫反射项对于水平镜面来说有

\[f_\text{diff}(\mathbf{l},\mathbf{v}) = (1-F(\mathbf{n},\mathbf{l}))\frac{\rho_\text{ss}}{\pi} \]

如果镜面反射项是微平面BRDF项,那么漫反射项为

\[f_\text{diff}(\mathbf{l},\mathbf{v}) = (1-F(\mathbf{h},\mathbf{l}))\frac{\rho_\text{ss}}{\pi} \]

因为这两个式子的计算和\(\mathbf{v}\)无关,这两个公式会造成均匀分布的离开表面的光。这两个式子在某种程度上还是有道理的,因为被折射的光被弹射离开表面时会经历多次散射。然而,有那么几个原因让它不那么合理。由于漫反射BRDF项取决于光入射方向,亥姆霍兹互易性告诉我们它也会随着光的出射方向改变。其次,光在离开表面前必须经历折射,这会让离开表面的光有方向偏好。

posted @ 2026-05-06 23:07  TiredInkRaven  阅读(52)  评论(0)    收藏  举报