Chapter 9 – Physically Based Shading 基于物理的着色

9.13 Blending and Filtering Materials(材质的融合与过滤)

材质融合的过程就是组合材质的多种属性,比如多种材质的BRDF参数。如果我们要模拟一片带有灰尘污点的金属,首先我们绘制一张mask贴图来控制灰尘污点的位置,并且使用该贴图在金属材质与灰尘材质的属性之间进行blend(镜面反射的颜色F0,漫反射的颜色ρ以及粗糙度α)。Blending的过程可以是一个预处理的过程,那么我们就能创建一个新的贴图,该过程通常被称为“baking烘培”,或者我们也能在shader中进行这一类操作。虽然表面的法线n并不是BRDF中的一个参数,但是改变该向量也会该表物体表面的外观。所以材质间的blending通常也会包含法线映射贴图之间的blend。

材质间的blend在实时渲染领域中是非常重要的。例如,The Order:1886有一个复杂的材质blend系统,其允许使用者从一个材质库中对多个材质进行blend,而blend的具体效果则有不同的空间mask所控制。大多数的材质blend都是一个离线的预处理过程,但是某些“组合”的操作也可以放在运行时进行,当然这取决于游戏的需求(动态的破坏效果,玩家对于装备的定制,或者增加角色或者环境的外观细节)。而实时的材质blend,通常用于场景中的环境,其能够加强tiling之后的贴图的独特性。常用的材质工具,Substance Painter与Substance Designer也使用了类似的方法。

有时,一个材质可能会“覆盖”在另一个半透明的材质上进行blend,那么我们就必须进行“部分”blend。即使两个完全不透明的材质进行blend,那么那些位于mask边缘的像素(或者texel)也会需要进行“部分”blend。无论是哪一种情况,正确的做法都是先计算出每一个材质的着色模型,再对结果进行blend。但是,另一方面来说,如果我们对BRDF的参数进行blend,再来计算出着色模型的结果,将会大大增加我们的效率(节省了一次BRDF计算)。因此,如果材质的参数与最终的着色结果有着线性或者几乎线性的关系,例如漫反射与镜面反射的参数,那么对参数直接进行blend并不会造成太多的错误。许多情况是,即使参数与最终的着色结果有着极不线性的关系(例如镜面反射的粗糙度),现对参数进行blend后得到的着色结果仍然是可以接受的。

法线映射贴图间的blend会与上述情况略有不同。我们可以基于法线映射贴图来倒推出相应的height map,之后再对height map进行blend能得到更好的效果。

材质的filtering与材质blend有着紧密的关系。一般来说,材质的属性都会存储在贴图中,而贴图会通过GPU的bilinear filter与mipmap进行filter。但是,这一做法的前提是filter的对象与最终的着色结果有着线性的关系。因此如果我们对法线映射贴图以及那些含有非线性关系的BRDF参数的贴图(粗糙度)进行mipmap处理,那么会造成视觉表现上的错误。例如镜面反射将会发生闪烁,或者物体表面与camera的距离发生变化之后会产生意想不到的高光效果。当然,这些错误中,镜面反射的闪烁是最容易被玩家发现的;缓解这些外观错误的方法通常被称为specular antialiasing

9.13.1 Filtering Normals and Normal Distributions

首先我们需要了解,为什么会发生上述这种显示错误,并且如何解决这些错误。在之前的章节中我们提到,NDF描述了子像素表面的结构。当camear与物体表面的距离增加时,原先覆盖多个像素的表面结构可能会减小到子像素的尺寸,也就是说将从bump map的领域进入NDF的领域。这一转换将与mipmap有着紧密的联系。

Marcroscale宏观层面的几何由模型的三角形负责,mesoscale中观层面的几何由贴图负责,而microscale微观层面的几何,其尺寸小于一个单一的像素,则由BRDF负责。如下图所示,左侧的圆柱体模型将被用于渲染。模型的外观通常都会假设一个有限的观察范围。左侧的圆柱体,我们使用的了原始的法线映射贴图进行渲染,其中的法线进行了简单的平均操作并且重新就行了标准化。中间部分,我们使用了分辨率较低的法线映射贴图。右侧的部分,我们使用了相同的低分辨率的法线映射贴图,但是使用了合适的NDF。

在上图中,原始的圆柱体有着较好的外观表现。但是,如果我们改变观察的范围呢?

如下图所示,其展示了物体表面的一小部分(对应上图中的圆柱体),其被法线映射贴图中的四个texel所覆盖。假设,我们在渲染该物体的表面时,法线映射贴图中的每一个texel都能覆盖一个像素。对于每一个texel来说,其对应的法线如红色箭头所示,并被Beckmann NDF所包围(黑色箭头所示)。而法线与NDF共同定义了物体表面的结构,表面在中间处的凸起源自于法线映射贴图,而小的褶皱则源于微观表面的结构。法线映射贴图中的每一个texel与粗糙度共同体现了该texel所覆盖区域的法线分布。

现在我们假设camera移动到了一个距离物体较远的位置,因此一个像素将会覆盖法线贴图中的四个texel。理论上讲,在这一分辨率下的物体表面需要表现出每一个像素所覆盖区域下的所有法线的分布。这一法线分布可以通过对顶层mipmap中的四个texel中的NDF求平均值来得到,如上图中左下角的部分所示。如果我们使用这一均值进行渲染,那么在该分辨率下能够最准确地表现出物体表面的外观。

上图中底部的中间部分,我们对于四个texel进行平均处理,也就是说,分别求出法线的平均值,NDF与粗糙度的平均值。法线均值(红色箭头)是正确的,但是NDF过窄。这会导致物体表面看上去过于光滑。同时,由于NDF过窄,还会导致镜面反射的闪烁。

因此我们无法直接通过Beckmann NDF求平均值的方法来表现出低分辨率下的法线分布。但是,如果我们使用一个roughness map,每一个texel拥有独立的Beckmann roughness αb。对于每一个NDF,我们能够找到最为接近的Beckmann lobe。我们将该Beckmann lobe的方向存储在法线映射贴图中,并将其粗糙度存储在roughness map中。也就是上图中底部的最右侧所示,该NDF更接近理想状态。而上图中最右侧的圆柱体使用了这一方法进行绘制。

为了得到最好的结果,filtering的操作,例如mipmap,应该应用在法线的分布,而不是直接运用于法线或者粗糙度。这意味着,我们要以另一个角度来思考NDF与法线之间的关系。一般来说,NDF是定义在局部的切线空间,而该空间则取决于法线映射贴图中的对应的法线。但是,当我们在不同的法线间对NDF进行filter时,可以认为法线映射贴图与roughness map的组合定义了一个歪的NDF。

现在大多通过计算法线分布的变化来解决NDF filter问题。Toksvig发现,如果我们对法线进行平均但并不重新标准化,那么平均后的法线的长度将于法线分布的宽度成反比。也就是说,如果原始法线的方向越是不同,那么平均后的法线的长度就会越短。他提出了一种基于该法线长度来修正NDF粗糙度参数的方法。将修正后的粗糙度代入BRDF,这样能够模拟filter后的法线的发散效果。

Toksvig的原始等式适用于Blinn-Phong NDF:

其中αp表述原始的粗糙度参数,α’p表示修正之后的值,而||n||表示平均后的法线的长度。该等式同样适用于Beckmann NDF,只需要再加上αp=2α-2b-2即可。如果需要将这一等式运用在GGX上,我们还需要一些额外的步骤。因为GGX与Blinn-Phong之间没有明确的关联等式。但是大多数情况下,我们仍然会使用αp=2α-2g-2等式,在实践中,其仍然能提供较好的效果。

Toksvig的方法的优势在于其考虑到了因为GPU进行贴图filter所造成的法线变化。其也适用于最简单的mipmap机制(进行单纯的线性平均不再次进行标准化)。该技术非常适用于动态生成的法线映射贴图,例如,水的波纹,对于这一类法线映射贴图我们只能实时在shader中生成mipmap。但是对于静态法线贴图,因为默认的压缩技术都是建立在法线是标准化长度的前提上,该技术可能并不适用。因此,如果我们想要使用Toksvig的技术,那么法线映射贴图并不能被压缩。

Olana与Baker的LEAN mapping技术则是基于法线分布的协方差矩阵。其类似于Toksvig的技术,能够较好地适应GPU的贴图filter与线性mipmap。此外,该技术也支持anisotropic法线分布。LEAN mapping也能适用于动态生成的法线,但是为了避免精确性的问题,当我们在使用静态法线时需要大量的存储空间。

在实时渲染领域,大多数法线映射贴图都是静态的而不是动态生成的。对于这一类法线映射贴图,我们常常会使用variance mapping技术。在这一类技术中,当法线映射贴图的mipmap chain生成时,在进行平均值计算时,我们将会丢失法线与法线之间的变化(variance)。Hill注意到,我们可以使用之前提到的Toksvig或者LEAN mapping的数学公式来预计算法线的变化。有时,预计算的变化值将存储在独立的variance贴图的mipmap中。更常见的情况是,这些变化值将用于修正roughness贴图的mipmap。例如,游戏Call of Duty:Ops采用了variance mapping技术。其将原始的粗糙度转换为variance,之后再加上法线映射贴图的variance,由此得到修正后的粗糙度。

留下评论

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据