9.10 布料的BRDF模型
布料往往具有不同于其他类型材质的微观几何结构,根据织物类型的不同,它可能还会具有高度重复的编织微观结构、从表面垂直突出的圆柱体(线),又或是二者都有。由于布料表面独特的特征外观,因此通常需要使用专门的着色模型来进行渲染,这些独特外观包括:各向异性的镜面高光,粗糙散射[919](光线在突出的、半透明的纤维中发生散射,从而导致边缘明亮的效果), 甚至颜色也会随着观察方向的变化而变化(这是由织物中不同颜色的线所引起的)。
除了BRDF之外,大多数织物还具有高频空间变化,这也是生成令人信服的布料材质的关键因素[825],如图9.42所示。
布料的BRDF模型主要分为三大类:根据观察建立的经验模型、基于微表面理论的模型、微圆柱体模型。我们将从每个类别中分别举出一些值得注意的例子。
9.10.1 经验布料模型
在游戏《神秘海域2》[631]中,布料表面使用了以下的漫反射BRDF项:
其中是边缘光项(rim)的比例系数,是正面(内部,inner)亮度项的比例系数,是Lambertian项的比例系数。此外,和分别控制了边缘项和内部项的衰减。这种行为并不是物理正确的,因为这些效果只与观察方向有关,与入射光线的方向无关。
相比之下,《神秘海洋4》[825]中的布料材质使用了微表面模型或者微圆柱体模型,具体使用哪一种模型,取决于布料的高光项(会在之后的两个小节中进行详细描述),并且使用了一种叫做“环绕光照(wrap lighting)”的经验次表面散射方法,来对漫反射项进行近似:
这里我们使用了章节1.2中介绍过的符号,它表示0-1之间的限制操作。左侧这个奇怪的符号代表了这个模型会影响光照和BRDF,并使用箭头右边的项来取代左边的项。用户指定的参数是一种散射颜色;值的范围为,用于控制环绕光照的宽度。
对于布料材质的建模,迪士尼将他们的漫反射BRDF项 [214](详见章节9.9.4)和一个光泽项相结合,从而对粗糙散射(asperity scattering)进行模拟:
其中是用于调节光泽项强度的用户参数。光泽颜色会在白色和亮度归一化的之间进行插值(由另一个用户参数进行控制)。这里的亮度归一化是指用除以其亮度值,从而分离它的色相(hue)和饱和度(saturation)。
9.10.2 微表面布料模型
Ashikhmin等人[78]提出使用一个逆高斯NDF来模拟天鹅绒(velvet)材质。这个NDF在后续工作中[81]又进行了一些微调,同时还提出了一种用于模拟一般材质的微表面BRDF变体,这个变体没有 masking-shadowing项,也没有对分母进行修改。
在游戏《教团:1886》[1266]所使用的布料BRDF中,结合了改进的微表面BRDF、Ashikhmin和Premoze在后续报告[81]中提到的天鹅绒NDF的一般化形式、以及方程9.63中的漫反射项。天鹅绒NDF的一般化形式如下:
其中,控制了逆高斯分布的宽度,控制了逆高斯分布的振幅。完整形式的布料BRDF如下:
在游戏《神秘海域4》[825]中使用了这种BRDF的变体,用于模拟羊毛和棉花等粗糙纤维织物。
Imageworks [947]在光泽项中使用了一个不同的逆NDF,同时这个光泽项可以被添加到任何BRDF中,这个NDF的形式如下:
尽管对于这个NDF而言,并不存在Smith masking-shadowing函数的闭式解,但是Imageworks使用了一个解析函数来逼近其数值解。Estevez和Kulla [442]讨论了masking-shadowing函数的细节,以及光泽项和BRDF其余部分之间的能量守恒。图9.43展示了一些使用Imageworks光泽项进行渲染的样例。
到目前为止,我们所看到的各种布料模型,都仅限于对特定类型的布料进行模拟,而在下一节中讨论的模型则试图以一种更加一般的方式来对布料进行建模。
9.10.3 微圆柱体布料模型
用于布料材质的微圆柱体模型(micro-cylinder model),与用于头发材质的微圆柱体模型非常相似,因此章节14.7.2中有关头发模型的讨论,可以帮助你更好的理解这类模型。这类模型背后的思想是假设表面被很多一维线段所覆盖。Kajiya和Kay针对该假设建立了一个简单的BRDF模型[847],Banks也为该模型提供了坚实的理论基础[98],因此它也被称为Kajiya-Kay BRDF或者Banks BRDF。这个理念基于了这样的一个观察:一个由一维直线所组成的曲面,它在任何给定位置上都具有无限多的法线,这些法线是由垂直于该位置切向量的法线平面(normal plane)所定义的。虽然从这个理论框架中开发出了许多新的微圆柱体模型,但是由于其简单性,因此原来的Kajiya-Kay模型仍然有一些用途。例如:在游戏《神秘海域4》[825]中,Kajiya-Kay BRDF用于表示丝绸和天鹅绒等闪亮织物的高光项。
Dreamworks [348, 1937]使用了一种相对简单的、艺术家可控的微圆柱体模型来模拟布料材质,这个模型允许使用纹理用来改变粗糙度、颜色和线的方向,其中线的方向还可以指向表面以外,从而模拟天鹅绒以及其他类似的织物。这个模型还可以对经纬线(横向和竖向的线)设置不同的参数,从而模拟更加复杂的变色织物,例如闪光丝绸(shot silk)。
Sadeghi等人[1526]提出了一种基于织物样品和单根纤维测量的微圆柱体模型,这个模型还考虑了线和线之间的masking和shadowing效应。
在某些情况下,头发的BSDF模型(章节14.7)也可以用于布料模拟。RenderMan的PxrSurface材质[732]有一个“模糊”波瓣,它使用了来自Marschner等人[1128]提出的头发模型中的项(章节14.7)。Wu和Yuksel [1924, 1926]在实时布料渲染系统中所实现的模型之一,就是源自迪士尼动画电影[1525]中所使用的头发模型。
9.11波动光学的BRDF模型
我们在前几个节中所讨论的模型都依赖于几何光学,它把光的传播看作成一种射线而不是波。几何光学基于了这样的假设:任何表面的不规则性要么小于一个波长,要么大于100倍波长(大约)。
而现实世界中的表面并没有那么理想,它们在所有尺度上都具有不规则性,包括1-100倍波长范围内。我们将1-100倍波长范围内的不规则性称为纳米几何(nanogeometry),来与前几节所讨论的微观几何区分开来,前文中所讨论的微观几何,虽然它们的尺寸很小,无法单独进行绘制,但是却都大于100倍波长。纳米几何对于反射率的影响无法使用几何光学来进行模拟。因为这些影响取决于光的波动性,需要使用波动光学(wave optics,也称为物理光学,physical optics)来对它们进行建模。
厚度接近于光波长的表面或者薄膜,会产生与光的波动性有关的现象。
在本小节中,我们将涉及诸如衍射(diffraction)和薄膜干涉(thinfilm interference)之类的波动光学现象,并讨论它们在真实感渲染中的重要性(有时效果会令人十分惊讶),虽然这些材质可能看起来十分普通。
9.11.1 衍射模型
纳米几何会引起一种叫做衍射(diffraction)的现象,为了解释这种现象,我们使用了Huygens-Fresnel原理,它假设波前(wavefront,指具有相同波相位的一组点)上的每一个点都可以看作是新球面波的源,如图9.44所示。
当波遇到障碍物的时候,根据Huygens-Fresnel原理,它们会在拐角处轻微弯曲,这就是衍射的一个例子,这种现象是无法使用几何光学来预测的。当光线打到平面上时,几何光学确实可以正确预测光线在单一方向上的反射;也就是说,Huygens-Fresnel原理提供了更多的见解和认识(insight)。这个原理表明,当表面上的球面波恰好排列成一条直线时,会形成反射波前,所有其他方向的波都会通过相消干涉被抵消。当我们在观察具有纳米级不规则性的表面时,这种认识会变得非常重要。由于各个表面点的高度是不同的,因此表面上的球面波不会排列得那么整齐,如图9.45所示。
正如上述两张图片中展示的那样,光会被散射到不同的方向上,其中一部分光会发生镜面反射,即在反射方向上叠加成一个平面波前。而剩余的光则会以一种定向模式衍射出来,这取决于纳米几何结构的具体特性。镜面反射光和衍射光的划分取决于纳米几何凸起的高度,或者更加准确地说,取决于高度分布的方差。衍射光在镜面反射方向上的扩散角度,取决于光的波长与纳米几何凸起的相对大小。然而有点违背直觉的是,更大尺度的不规则性反而会导致更小的扩散角度,如果这个不规则性大于100倍波长的话,那么衍射光和镜面反射光之间的角度会很小,几乎可以忽略不计。 不规则性的尺寸减小会导致衍射光扩散到更大的范围内,直到表面的不规则性小于光的波长,此时该点上也就不会有衍射现象发生了。
在具有周期性纳米几何结构的表面上,衍射现象是最清晰可见的,因为重复的表面结构通过相长干涉会增强衍射光,从而产生彩虹颜色,这种现象可以在CD、DVD光盘以及一些某些昆虫中观察到。虽然衍射现象也可以发生在非周期性表面上,但是多年来计算机图形学界一直认为这种情况下的衍射现象是十分轻微的。出于这个原因,除了少数情况之外[89, 366, 686, 1688],多年来计算机图形学文献大多都忽略了衍射现象。
然而,在最近Holzschuch和Pacanowski [762]对测量材质的分析表明,在许多材质中存在着显著的衍射效应,这也许可以解释为什么当前的模型一直很难和这些材质与相匹配。Holzschuch和Pacanowski的后续工作[763]提出了一种结合微表面理论和衍射理论的模型,他们在通用的微表面BRDF(方程9.26)中,使用了一个考虑衍射现象的micro-BRDF。同时,Toisoul和Ghosh [1772, 1773]提出了一种用于捕捉由周期性纳米几何结构所产生的彩虹色衍射效果的方法,并且可以使用点光源和基于图像的照明来实时渲染这些效果。
9.11.2 薄膜干涉模型
薄膜干涉(Thin-film interference)是一种波动光学现象,当一个薄电介质层的顶部反射和底部反射的光路相互干扰时,就会发生这种现象,如图9.46所示。
不同波长的光会发生相长干涉或者相消干涉,具体取决于波长和路径长度差之间的关系。由于路径之间的长度差异会随着角度的变化而变化,因此最终产生的结果是偏移了的彩虹颜色,因为不同波长的光会在相长干涉和相消干涉之间不断切换。
薄膜之所以需要很薄才能产生这种效果,其原因与相干长度(coherence length)的概念有关。这个长度是指光波的副本在移动之后,仍然可以与原始光波发生干涉的最大距离。这个最大长度与光的带宽(bandwidth)成反比,光的带宽是指其光谱功率分布(SPD)延申的波长范围。激光具有极窄的带宽,因此其相干长度也极长;根据激光类型的不同,相干长度甚至可以达到几英里。这种关系是有道理的,因为一个很简单的正弦波在被许多不同波长的波取代之后,仍然会和原始波发生干涉。如果一个激光是完全单色的话(只包含一种波长的光),那么它就会具有一个无限大的相干长度,但是现实中的激光总会有一个不为0的带宽。相反,带宽极大的光将具有非常混乱无序的波形,具有这样一个波形的光波副本,只需要移动一段很短的距离,就会停止与原始波的干涉。
在理论上,理想的白光是由所有波长的光混合叠加而来的,其相干长度应当为0。然而,对于可见光而言,人类视觉系统的带宽(仅能感知波长在400纳米-700纳米范围内的光)最终决定了相干长度,大约为1微米。所以在大多数情况下,如果有人问你:“一层薄膜要多厚才不会引起可见的干涉现象?”这个问题的答案是:“大约1微米。”
与衍射现象类似,多年来,薄膜干涉被认为是一种特殊效应,只会发生在肥皂泡和油渍等表面。然而,Akin指出[27],薄膜干扰确实会给许多常见的表面带来一些微妙的色彩变化,模拟这种效果可以大大增加真实感,如图9.47所示。他的论文引起了人们对基于物理的薄膜干涉的极大兴趣,包括RenderMan的PxrSurface材质[732]以及Imageworks的着色模型[947]在内的各种着色模型,现在都已经支持了这种效果。
适合于实时渲染的薄膜干涉技术已经存在一段时间了。Smits和Meyer [1667]提出了一种有效的方法,来考虑一阶光路和二阶光路之间的薄膜干涉。他们观察到,最终产生的颜色主要是一个与路径长度差异有关的函数,这可以通过薄膜厚度、观察角度和折射率计算出来。他们的实现需要一个具有RGB颜色的一维查找表,这个表中的数据可以使用密集光谱采样(dense spectral sampling)预先计算,并将其转换为RGB颜色进行存储,这使得该技术运行起来效率很高。在游戏《使命召唤:无限战争》中,使用了一种不同的快速薄膜近似方法,它被作为分层材质系统[386]的其中一部分。这些技术无法模拟光在薄膜中的多次反射,也不能模拟其他的物理现象。Belcour和Barla [129]提出了一种更加精确的技术,虽然计算成本变高了,但是仍然可以用于实时渲染。
9.12 分层材质
在现实生活中,表面的材质通常是相互重叠的。这些表面可能被灰尘、水、冰、雪所覆盖;也可能是出于装饰或者保护的原因,表面会被涂上漆或者其他涂层;又或是它可能包含了多层基本结构,例如许多生物材料。
其中最简单和最具视觉重要性的分层案例之一就是透明涂层(clear coat,也叫做清漆材质),它指的是涂在其他材质基底上的光滑透明层。例如:在一个粗糙的木材表面涂上一层光滑的清漆。迪士尼原则着色模型[214]便包含了一个透明涂层项,虚幻引擎[1802]、RenderMan的PxrSurface材质[732]、以及Dreamworks Animation [1937]和Imageworks [947]所使用的着色模型,都包含这个透明涂层项。
透明涂层最显著的视觉效果,就是由光从透明涂层处反射与从底层基板处反射而产生的二次反射。当基底是金属材质的时候,这种二次反射的效果最为显著,因为此时透明电介质涂层和基底之间的折射率差异最大。当基底是电介质的时候,其折射率与透明涂层的折射率相近,因此第二次反射会相对较弱,这种效果类似于水下的材质,详见表9.4。
透明涂层也可以有颜色。从物理角度来看,这种着色是光线被部分吸收的结果。根据Beer-Lambert定律(章节14.1.2),光线被的吸收数量取决于穿过透明涂层的光路长度。而这个路径的长度则取决于观察视角、入射光的角度、以及材质的折射率。一些更加简单的透明涂层的实现,例如迪士尼原则模型和虚幻引擎,则没有对这种视角依赖性进行建模;而其他的实现则考虑到了这一点,例如PxrSurface材质,以及Imageworks和Dreamworks所使用的着色模型。Imageworks的模型还允许任意数量的、不同类型的层叠加在一起。
一般情况来说,不同的层(透明涂层和基板)可以有不同的表面法线。例如水流流过平坦的路面、凹凸不平的土壤表面上铺上一层光滑的冰、或者在纸板箱上盖上皱巴巴的保鲜膜等。电影行业中所使用的大多数分层模型,都支持为每一层设置单独的法线,而这种做法在实时图形应用中则并不常见,但是也有一些例外,例如虚幻引擎中的透明图层材质在实现上,将逐层的独立法线作为一个可选的特性。
Weidlich和Wilkie [1862, 1863]提出了一种分层的微表面模型,它假设表面层的厚度要比微表面的的尺寸小。他们所提出的模型支持任意数量的涂层相互叠加在一起,并且可以追踪从顶层到底层,再到顶层的反射事件和折射事件。它对于实时应用来说足够简单[420, 573],计算成本也不是很高,但是这个模型并没有考虑层与层之间的多次反弹。Jakob等人[811, 812]提出了一个全面而准确的框架模型用来模拟分层材质,这个框架还支持层与层之间的多次反弹;虽然它并不适合用于实时渲染,但是作为ground-truth而言还是十分好用的,而且它所使用的思想理念可能会对未来的实时分层材质有所启发。
游戏《使命召唤:无限战争》中所使用的分层材质系统[386]尤其引人注目,它允许用户将任意数量的材质层叠加在一起。该分层材质系统还支持折射、散射以、基于路径长度的层间吸收、以及逐层的表面法线。结合高效的实现方式,这个系统能够实现前所未有的复杂实时材质,尤其是对一个运行在60 Hz的游戏而言,如图9.48所示。
9.13 混合和过滤材质
材质混合(material blending)是指将多种材质的属性(即BRDF参数)结合在一起的过程。例如:为了模拟一个带有锈迹的金属材质,我们可以绘制一个蒙版纹理来控制铁锈出现的位置,并使用它来混合铁锈和金属的材质属性(高光颜色,漫反射颜色和粗糙度)。材质的参数都存储在纹理中,每种材质的属性也都可以在空间上发生变化。可以通过提前创建新的纹理来实现材质混合(这个过程通常称为“烘焙”),或者也可以在着色器中进行实时处理。虽然表面法线从技术上来说并不是一个BRDF参数,但是表面法线的空间变化对于材质外观的影响是非常重要的,因此材质混合通常也包括法线贴图的混合。
材质混合是很多实时渲染应用的关键。例如:游戏《教团:1886》就有一个十分复杂的材质混合系统[1266, 1267, 1410],它允许美术人员从扩展库中获取素材,并创建任意深度的材质堆栈,并使用各种空间蒙版来进行控制。大多数材质混合都是离线预处理完成的,但是其中一些合成操作可以根据需要,延迟到运行时完成,这种运行时处理通常用于环境材质,用于为平铺纹理添加一些独特变化。广泛流行的材质创作工具Substance Painter和Substance Designer便使用了类似的方法来进行材质合成,Mari纹理绘画工具也是如此。
将纹理元素动态混合在一起,可以实现很多种效果,同时节省内存开销,游戏应用基于各种目的使用了材质混合技术,例如:
- 展示建筑物、载具和生物(或不死生物)的动态伤害效果。 [201, 603, 1488, 1778, 1822]
- 允许用户自定义游戏中的装备和服装。 [604, 1748]
- 增加角色[603, 1488]和环境[39, 656, 1038]的视觉多样性,如图20.5所示。
有时,材质会以一种半透明的方式(即该层的不透明度小于100%)混合在另一种的材质上;但即使是完全不透明的混合材质,在蒙版边界上也存在一些像素(或者纹素texel,如果烘焙成纹理的话)需要进行部分混合。在任何一种情况下,正确的方法都是计算每种材质的着色模型,并将着色结果进行混合。但是这样需要计算两次着色过程,速度是很慢的,更快的方法是直接将BRDF的参数混合在一起,然后只计算一次着色。在材质属性与最终着色颜色之间具有线性关系或者近似线性关系的情况下(例如漫反射颜色和高光颜色),这种插值所引入的误差很小,或者根本没有误差。在很多情况下,即使材质参数与最终的着色颜色之间是高度非线性的(例如镜面粗糙度),在蒙版边界处所引入的误差也是可以接受的。
法线贴图的混合需要一些特殊考虑。通常可以从法线贴图中派生出高度贴图(height map),然后对高度贴图进行混合,从而获得不错的效果[1086, 1087]。在其他情况下,例如在一个基础表面上叠加细节法线贴图(detail normal map),也可以使用其他形式的混合方法[106]。
材质过滤(material filtering)是一个与材质混合密切相关的话题。材质的属性通常都会存储在纹理贴图中,并通过GPU双线性滤波和mipmap等机制进行过滤。然而,这些机制都基于了这样一个假设,即被过滤的参数(着色方程的输入)与最终的颜色(着色方程的输出)之间存在着线性关系。但是这种线性关系只适用于某些参数,并不适用于所有的情况。在法线贴图上使用线性mipmap方法,或者是在包含非线性BRDF参数的纹理上(例如粗糙度)使用线性mipmap方法,都会产生瑕疵。这些瑕疵可能会表现为高光锯齿(闪烁高光);或者是由于表面与相机之间的距离发生变化,从而导致表面光泽度和亮度的意外变化。在这两种瑕疵中,高光锯齿是更加明显的,消除这些瑕疵的技术通常被称为高光抗锯齿(specular antialiasing)技术,下面我们将讨论其中的几个方法。
9.13.1过滤法线与法线分布
大部分材质过滤的瑕疵(主要来自高光锯齿),以及最常用的解决方案,都与法线和法线分布函数的过滤有关。由于这部分十分重要,因此我们将对这个话题进行一些深入讨论。
为了理解这些瑕疵发生的原因以及解决它们的方法,这里我们回顾一下NDF,它是指亚像素表面结构的统计学描述。当相机与表面之间的距离增加时,之前在图像上覆盖多个像素的表面结构,现在只能覆盖若干个亚像素,即从凹凸贴图的控制领域转移到了NDF的控制领域中。这个转换过程与mipmap密切相关,mipmap可以将纹理细节压缩到亚像素尺度上。
现在让我们思考一下物体是如何进行建模和渲染的,例如图9.49中左侧的圆柱体。对材质外观的建模总会预设一定的观察尺度:宏观尺度(macroscale)下的几何图形会被建模为三角形网格,细观尺度(mesoscale)下的几何图形会被建模为纹理,而小于单个像素的微观尺度下的(microscale)几何图形则会通过BRDF进行建模。
根据图9.49所给定的观察尺度,将圆柱体建模为光滑网格(宏观尺度),并使用法线贴图(细观尺度)来表示凸起是较为合适的,同时使用了具有固定粗糙度的Beckmann NDF来模拟微观尺度上的法线分布。这种组合表示方法在这个尺度上对圆柱体的外观进行了很好地模拟。但是,当观察尺度发生改变时会发生什么呢?
如图9.50所示,第一行展示了表面的其中一小部分,这部分表面被四个法线贴图的纹素所覆盖。假设我们按照这样的一个比例来渲染表面,使得法线贴图中的每个纹素刚好被一个画面像素所覆盖。对于法线贴图中的每个纹素而言,图中的红色箭头代表了法线(法线分布的平均值),它被Beckmann NDF(黑色箭头)所包围。法线和NDF隐式表达了表面的微观几何结构,如图9.50第一行表面的横截面所示。中间的主要突起代表了法线贴图所定义的凸起,而周围的小摆动则代表了微观尺度的表面结构。法线贴图中的每个纹素,结合对应的粗糙度,可以被看作是,在这个纹素所覆盖的表面上收集到的法线分布。
现在我们假设相机到物体的距离变远了,此时屏幕上的一个像素只能覆盖四个法线贴图的纹素。在这个分辨率下,一个理想的表面表达方式应当是:能够准确表示该区域内所有法线的分布。这个分布可以通过计算上层mipmap中的,四个对应纹素的NDF的平均值来获得。图9.50左下角展示了这种理想的法线分布。这个平均后的法线结果如果用于渲染的话,可以最准确地代表在较低分辨率下的表面外观。
图9.50底部中间的图展示了分别对法线(法线分布的平均值)和粗糙度(对应了法线分布的扩散角度)进行平均的结果。最终的结果具有正确的平均法线分布(红色箭头),但是法线分布太窄了,这个误差会使得表面看起来过于光滑。更加严重的是,由于NDF太窄,因此将很容易造成瑕疵(闪烁高光)。
我们无法直接使用Beckmann NDF来表示理想的法线分布。但是如果我们额外使用一个粗糙度图的话,那么Beckmann粗糙度就可以在不同的纹素之间发生变化。想象一下,对于每个理想的NDF,我们都要找到与其最匹配的定向Beckmann波瓣,无论是在方向上还是总体扩散角度上。我们将Beckmann波瓣的中心方向(即法线分布的平均值)存储在法线贴图中,将粗糙度值存储在粗糙度贴图中。最终结果如图9.50右下角所示,这个NDF更加接近理想中的情况。与简单的平均方法(图9.50底部中间的图)相比,使用这种方法可以更加真实地表示圆柱体的外观,如图9.49所示。
为了获得最佳的效果,应当对法线分布应用过滤操作(例如mipmap),而不是对法线或者粗糙度值单独应用过滤操作,这样做意味着,需要使用一种稍微不同的方式来思考NDF和法线之间的关系。通常来说,NDF定义在由法线贴图的逐像素法线所确定的局部切线空间中,然而,在过滤不同法线的NDF时,可以将法线贴图和粗糙度贴图的组合,看作是定义在底层几何表面的切线空间中的倾斜NDF,这样来进行思考是十分有帮助的。
早期解决NDF过滤问题的尝试[91, 284, 658]是通过使用数值优化方法,来将一个或者多个NDF波瓣拟合到平均分布中。这种方法存在健壮性和速度上的问题,目前已经使用得不多了。相反,目前所使用的大部分技术,都是通过计算法线分布的方差来实现的。Toksvig [1774]观察到了这样一个事实:如果对法线进行平均化的而不是重新归一化的话,那么法线的平均长度与法线分布的宽度成反比。也就是说,原始法线分布的扩散角度越大,平均后得到的法线就越短。据此,他提出了一种基于法线长度来修改NDF粗糙度参数的方法,并使用修正后的粗糙度参数来重新计算BRDF,从而对过滤后的法线扩散效果进行近似。
Toksvig的原始方程是用于Blinn-Phong NDF的,其数学形式如下:
其中是原始的粗糙度值,是修正后的粗糙度值;是平均法线的长度。这个方程也可以使用等效替换(来自Walter等人[1833])来得到Beckmann NDF,因为这两个NDF的形状十分类似。使用GGX分布的方法就不太直接了,因为GGX和Blinn-Phong(以及Beckmann)之间并没有明确的等价关系。一种方法是强行让和相等,这样做的结果是,虽然高光中心的值是相同的,但是高光的外观却大不相同。更加麻烦的是,GGX分布中并没有定义法线分布的方差,因此在与GGX分布一起使用的时候,这种基于方差的技术并没有扎实的理论基础。尽管有这些理论上的困难,但是在GGX分布中使用方程9.76的情况是相当普遍的,通常是令,这样做在实践中还是相当有效的。
Toksvig方法的优点是在GPU纹理过滤中引入了法线方差,它也适用于最简单的法线mipmap方案(即对法线进行不归一化的线性平均)。这个特性对于那些动态生成的法线贴图(例如水面波纹)而言特别有用,因为对于这些法线贴图而言,它们的mipmap必须在运行过程中生成。但是这个方法对于静态的法线贴图而言并不是很好,因为它无法与常见的法线贴图压缩算法一起使用,原因在于这些压缩算法都要求法线是单位长度的。而Toksvig的方法依赖于平均法线的长度,这个长度是会发生变化的,因此使用这种方法的法线贴图必须要保持未压缩状态。但是即使这样,存储变短的法线也会导致精度问题。
Olano与Baker的LEAN映射技术[1320]基于的是法线分布协方差矩阵的映射,与Toksvig的方法一样,它可以很好地兼容GPU纹理过滤和线性mipmap,同时它还支持各向异性的法线分布。与Toksvig的方法类似,LEAN映射技术可以很好地处理动态生成的法线,但是为了避免精度不足的问题,因此在处理静态法线的时候需要大量的存储空间。Hery等人[731, 732]独立提出了一种类似的技术,并在皮克斯动画电影中被用于渲染亚像素级别的细节,例如金属薄片(metal flakes)和小划痕等。CLEAN映射[93]是LEAN映射的一个简化变体,它不支持各向异性的法线,但好处是降低了存储空间。LEADR映射[395, 396]对LEAN映射进行了扩展,同时也考虑了位移映射(displacement mapping)的可见性影响。
实时图形应用中所使用的大多数法线贴图都是静态的,并不是动态生成的,对于这种贴图而言,通常会使用方差映射技术。这些技术会在生成法线贴图mipmap的时候,会计算法线平均化所带来的方差损失。Hill指出[739],Toksvig技术、LEAN映射和CLEAN映射等技术,都可以使用这种方法来预先计算方差,从而消除这些技术在原始形式下的许多缺点。在某些情况下,预计算出来的方差值会单独存储在方差纹理以及它的mipmap中。通常,这些值会用于修改现有粗糙度贴图的mipmap。例如:游戏《使命召唤:黑色行动》[998]中的方差映射技术便采用了这种方法。修正后的粗糙度值是通过将原始粗糙度值转换为方差,并加入法线贴图的方差,最终转换回粗糙度计算而来的。在游戏《教团:1886》中,Neubelt和Pettineo [1266, 1267]以一种类似方法使用了Han [658]提出的技术,他们将法线贴图中存储的NDF与BRDF镜面项的NDF进行卷积,并将结果转换为粗糙度,最终将其存储在粗糙度贴图中。
还可以通过使用一些额外的存储空间来进一步改善结果,即在纹理空间的方向上分别计算方差,并将其存储在一个各向异性的粗糙度贴图中[384, 740, 1823]。这项技术本身局限于轴向的各向异性,这在一些人造表面中是很常见的,但是在自然形成表面中就不太常见了。还可以通过再多存储一个值,从而支持定向的各向异性(oriented anisotropy)[740]。
与原始形式的Toksvig、LEAN映射和CLEAN映射不同,方差映射技术并没有考虑由于GPU纹理过滤所引入的方差。为了弥补这一点,在方差映射的实现中通常会使用一个较小的滤波器[740, 998],对法线贴图的顶级mip进行卷积。当组合多个法线贴图的时候(例如细节法线贴图)[106],需要注意对法线贴图的方差进行正确组合[740, 960]。
模型的高曲率几何结构(高频信息)或者法线贴图会引入法线方差,前面我们所讨论的这些技术并不能缓解这种由方差所带来的的画面瑕疵,但是也有一些方法可以解决这些问题。如果在几何体上存在着唯一的纹理映射的话(通常是角色模型,较少与环境有关),那么模型的几何曲率可以被“烘焙”到粗糙度贴图中[740]。曲率还可以使用像素着色器中的导数指令来实时计算得出[740, 857, 1229, 1589, 1775, 1823]。如果可以使用法线缓冲的话,那么这种计算可以在几何体的渲染阶段中进行,或者是在处理后阶段中进行。
到目前为止,我们所讨论的方法主要集中在镜面反射上,但是法线方差同样也会影响到漫反射的着色。考虑法线方差对项的影响,可以帮助提高漫反射着色和镜面反射着色结果的准确性,因为二者在反射率积分中都会乘上这一项[740]。
方差映射技术将法线分布近似为光滑的高斯波瓣,如果每个像素中包含数十万个凸起的话,那么这种近似是合理的,因为它们可以被很平滑的平均。但是在大部分情况下,一个像素只能覆盖几百个或者几千个凸起,这会导致表面具有“闪闪发光(sparkly)”的材质外观,我们可以在图9.25中看到这样的例子,它包含了一系列图像,不同图像中球体上的凸起会逐渐减小。其中右下角图像中球体的凸起非常小,它们被平均后形成了十分平滑的高光;但是对于左下角和底部中心的图像而言,虽然球体的凸起小于一个像素,但是还不足以被很平滑地平均,不足以产生平滑的高光。如果这些小球动起来的话,那么充满噪声的高光会表现为一帧一帧的不断闪烁。
如果我们将这样一个曲面的NDF渲染出来的话,那么它看起来会像图9.51左侧那样。当球体运动起来的时候,半向量会在NDF上不断移动,穿过明亮和黑暗的区域,从而导致“闪闪发光”的外观。如果我们在这样的表面上使用方差映射技术,那么它会用一个类似于图9.51右侧的平滑NDF,来对左侧的NDF进行近似,从而失去闪烁细节。
在电影行业中,这个问题通常会使用大幅的超采样来解决,但是这在实时渲染应用中是不可行的,甚至在离线渲染中也是不可取的。但是已经出现了一些用于解决这个问题的技术,其中有一些并不适合实时渲染使用,但是却为未来可能出现的技术提供了研究方向[84, 810, 1941, 1942]。在这些方法中,有两种实现是用于实时渲染的。Wang和Bowles [187, 1837]提出了一种技术,用于在游戏《迪士尼无限3.0(Disney Infinity 3.0)》中渲染闪闪发光的雪花。这个技术的目的是产生一种看似闪亮的外观,而不是真的去模拟特定的NDF,它适用于具有稀疏闪光的材质,例如雪花等。Zirr和Kaplanyan [1974]的技术模拟了多个尺度上的法线分布,它可以用于更加广泛的材质外观,并且在空间上和时间上都是稳定的,
在本小节中,我们没有足够的篇幅来囊括所有有关材质过滤的文献,因此在这里我们将着重提及一些值得注意的参考文献。Bruneton等人[204]提出了一种用于渲染海洋表面的技术,它支持环境光照,其中方差处理的尺度可以从几何到BRDF。Schilling [1565]讨论了一种类似于方差映射的技术,该技术支持环境贴图的各向异性着色。Bruneton和Neyret [205]则对该领域的早期工作进行了全面概述。
补充阅读和资源
McGuire的《Graphics Codex》[1188]和Glassner的《数字图像合成原理》[543, 544]对于本章节中所涉及的许多主题而言,都是一个非常好的参考资料。虽然Dutre的《Global Illumination Compendium》[399]中的一些部分有点过时(尤其是BRDF模型部分),但是它是渲染数学非常好的参考资料(例如球形积分和半球积分)。其中Glassner和Dutre的参考资料都可以在网上免费获取。
对于想要更多了解光和物质相互作用的读者,我们非常推荐Feynman的讲座[469](可以在网上找到),其中的内容对于对于我们在撰写这一章的物理部分而言十分宝贵。另一个十分有用的参考资料是Fowles的《Introduction to Modern Optics》[492],这是一个是简短易懂的入门文章。Born和Wolf [177]的《Principles of Optics》是一本更“重”(字面意思上也是)书,它包含了对光学的深入讲解。Nassau [1262]的《Physics and Chemistry of Color》描述了物体颜色背后的物理现象,非常彻底且详细。