随着对游戏美术品质要求的提高,对整个开发从流程pipeline到从业人员的素质要求都开始增加。传统的美术工作流因为依赖个人的经验和感觉,所以在制作大体量项目的过程中很难达到理想效果。而这时,由项目组内的Technical Artist和Graphic Programmer来搭建起一套基于物理渲染的管线是非常有必要的。

Physical Based Rendering(PBR)基于物理的渲染,已经不是什么新鲜的渲染技术了。如今的美术从业者也很少会再从原先的手绘流程开始学起,都是清一色的PBR资产创建流程。虽然借助成熟的pipeline工具链已经能够批量生产美术资源,但如何在游戏引擎中正确设置这些资源则是一个大课题,这直接影响到游戏最后呈现出的美术品质。

引擎中往往是需要我们定制更多参数的,只有对Lighting的设置才能来保证这些美术资产能正确接收光照和环境光,从而保证高效的产出效率和相对便捷的pipeline。虽然Physical Based Rendering很早就在行业内开始普及,但仍然有一些制作组的美术/技术人员由于对这一套渲染流程的细节不够重视,认为有一些色感和审美之后自己就是合格的美术,过于依赖眼睛所看到的信息,在PBR的流程中还是按照自己的经验来根据主观判断调整材质中的specular、shadow、diffuse颜色, 最终得到错误的结果。例如在修改物体阴影时不调整Ambient Light而是直接在shader中强行改阴影颜色等操作。

整篇论文结构划分为构成PBR场景的三个要素,材质(Material),光照(Lighting),相机(Camera),本文作为整篇文章的开头,涉及了材质方面的所有内容。作者为Sebastian Lagarde。我们熟悉的Unity HDRP就是Sebastian在巴黎办公室带领团队编写的。作为Graphic界的扛把子,他本人在14年SIGGRAPH发布的这一篇论文就非常有说服力。借此机会,想把这一篇精彩的文章分享给各位。

本文可能也有很多没有理解到位的地方,会在之后不断更新修正,欢迎各位大佬一起交流学习。

Moving Frostbite to PBR - Frostbite​www.ea.com

Introduction

经过前几个月的回顾与反思,我们开始重新评估整个寒霜(Frostbite)[1]呈现出来的图像质量。我们最终的目标是让它看上去更有电影的质感,所以我们需要让整套流程都基于物理进行渲染(PBR)来达到预期的效果。我们根据行业内现有的一些成功案例来改进寒霜的美术表现,例如《杀戮地带(暗影坠落)》[Dro13]by Decima Engine,虚幻4引擎[Kar13]by Unreal4,Remember Me [LH13]by Unreal 3和《合金装备(Ground Zero)》[Koj+13]by Fox Engine… 在这基础之上,我们需要重新对已有的技术进行定义并解决当下这个领域中已经遇到的许多问题。

在R&D的过程中,我们使用了“经验证据(Ground Truth)”作为参考——去进行测量/渲染后得到的近似值——去评估我们得出结论的准确性。在当时要在引擎内完全实现渲染的物理准确是非常困难的,不像如今的引擎内可以实时对性能进行约束。然而在某些情况下使用近似值也成为了可能,在这样的限制下,我们会更倾向于使用看上去更正确的参数,而不是按照完全物理准确的标准来提升我们的渲染质量。

PBR已经成为了当前游戏行业中常见的术语,但实际上各个游戏引擎对它的定义都有很大区别。对于寒霜来说,一个最核心的PBR原则去确保场景内所有物体在视觉上的美观准确是尽可能的对引擎内的材质(Material)和光照(Lighting)信息进行解耦合(Decouple)。基于这个方法,场景内的物体和各层材质就可以接收到同样准确的光照信息,避免了一系列人为错误,如负值的光照强度或是计算两次光照等。从产品的角度上来讲,这也促进了在不同环境下美术资产和光照组建的复用性。同时,这也可以减少我们的对美术人员开放的参数,让面板看上去更清晰,提高易用性。然而这样完全分离的做法实际上是不现实的,因为会出于性能的考虑,材质和光照的代码耦合性很强,你会在之后的文章中看到更细致的解释。

我们在拥抱PBR时很明确的一点是整个图形的工作流(渲染器和制作工具)都需要进行对应的更新。有了这样一个认知我们在制作这个课程时的目标就需要针对大体量的游戏引擎覆盖到所有不同工具和流程的更新细则。包括对以往文献中遗漏的细节进行补充。首先在第二章节会解释经验证据(Ground Truth)的参考对PBR环境的重要性。第三章则对材质部分有一个更详细的介绍:光是如何与不同材质的物体进行交互的。接下来第四章会讲到光是怎么定义和发散(Emit)的。第五章关注在相机和最后输出的图像质量效果上,涉及到光照结果会经过怎么样的步骤输出到最后的像素中。最终我们在第六章对前面进行总结,回顾寒霜转换到PBR的开发流程,以及我们在这个过程中的一些思考和想法。

在继续之前,我需要先声明的是,这篇论文是许多处在游戏行业的人智慧的结晶。它收集了很多被广大群众分享到社区内的信息。他们应当被Credit为这篇文章的作者之一(具体名字见文章末的Acknowledge一栏)

文章中会用到的一些数学符号及其含义

2. Reference

2.1 Validating Models and hypothesis 验证已有的光照模型和一些设想

游戏行业在近十年都在往渲染更真实(Photorealistic)的画面上努力。但真实感(Photorealism)是一个很模糊的概念,我们无法用一个既定的方法来达到这样的意向,因为每个人对真实的解读都是不同的。不同于基于物理渲染(PBR)用模拟经验证据(Ground Truth)的行为和参数,它得到的结果可以用定量分析来判断。这就对我们的经验证据(Ground Truth)数据有了新的要求。在研究过程中,选择正确的假设和模型也是非常重要的,仔细观察并对比真实世界的现象是一个辅助我们判断这个技术/方法是否适用的好办法。在项目初期阶段可以用这样的方式更快速的抓住要点,比如物体在潮湿情况下的表面效果,在不同光照环境下的表现和其他在视觉上的区别等等,见图一。当把真实世界的物体作为材质参考时,我们需要在不同的光照设置下拍摄来获得更有效的参考。

图一:真实世界(左)和引擎(右)内的灯光效果对比

然而拍摄这样准确的数值是非常耗时的。一些已有的数据库如MERL【MER】使得我们可以直接获取到这些光照信息。在我们的工作中,我们会经常从这样的数据库中获取并验证数据,如光照强度、光照衰减,天空亮度和相机效果等。即使我们是去找现成的数据这样的工作仍然是十分耗时的。

2.2 Validating in-engine approximations 验证引擎内的近似值

目前的PBR光线追踪器(Path Tracer)像是Mitsuba[Jak10]可以渲染出最真实的图像效果。使用这样的软件[2]是一个非常简单的方式来替代之前所说的各种测量需求。在寒霜中我们编写了一个到Mitsuba的导出工具,用来快速验证对真实材质的模拟是否达到标准。这个导出工具允许我们将引擎内的模型、材质(不包括贴图)、光照设置信息一并导出。有了这样的流程,我们就可以检查材质所使用的光照模型,积分计算(Light Integration)和光照强度和真实材质的出入。实际上我们还可以通过这个流程来检查全局光照(Global Illumination)、环境光遮蔽(Ambient Occlusion)和反射信息(Reflection)。图二显示了在执行导出后引擎会自动生成一个对比引擎内实时渲染和离线光线追踪后的效果对比。在菜单栏你还可以对曝光度进行设置,这一点非常重要,因为在渲染器中最终输出的结果是输出成一张处于线性空间的Open EXR格式 HDR图像。

图二:我们编写的用于对比引擎内实时渲染和离线光追的结果,用于检查材质的准确性

2.3 Validating in-engine reference mode 验证引擎内的参考模式

在上一小节中我们提到了用于验证准确性的导出工具,但在导出后需要渲染场景的时间在几秒到几分钟不等。为了快速在不同的材质效果进行迭代测试,我们在引擎内加入了用于GPU光照计算的内部参考模式(如IBL和区域光),见图三。虽然渲染时间仍然偏长,但在大部分情况下都比之前的导出工具流程快。附录A中会包含我们所测试的所有光照模型数据。

图三:左:(引擎内)由几盏不同类型的区域光渲染的场景。 中:(引擎内参考)同样的场景设置,但使用GPU的重要排序进行渲染。 右:(离线渲染参考)相同设置在离线渲染器中的参考

Note:使用正确的参考是非常重要的。显而易见的是,如果使用的参考(Reference)就是不准确的那么我们所写的材质(Approximation)也一定是不准确的。例如我们在写渲染头发的渲染算法时应当选取真实世界的头发表现作为参考。在编写的过程中也应该用原有的头发算法而不是Oren-Nayar和Schlick这样的边缘光近似算法(Fresnel Equation)他们导致不准确的结果。世界上唯一能被完全信任的参照物永远处于真实世界中。

3. Material 材质

3.1 Material models 材质模型

3.1.1 Appearance 材质表象

不同材质的表现结果取决于入射光线和不同的表面材质属性。真实世界中的材质表现非常广泛,从一层的统一材质到多层次的,甚至是多种物质混合的材质,见图四。

图四:光和物体交互下的不同材质效果

这些材质可以被材质本身的物理属性归为不同的种类,如导电性(Conductivity),平均自由程(mean-free-path),漫反射率(absorption)。基于物体本身的属性,学术界归纳出了几种不同的材质模型用于区分在整条光谱(Spectrum)上特定范围内的材质表现。关于材质光照模型的学术研究已经非常充分了,由此派生出了许多不同精度和表现(Trade-off)的光照模型。这里提到的材质模型(material model)也被称为双向散射分布函数(BSDF:Bidirectional Scattering Distributing Function),它可以被分解为两个大类:反射计算部分(BRDF:Bidirectional Reflectance Distributing Function)和透明度计算(Transmittance)部分(BTDF:Bidirectional Transmittance Distributing Function)。这篇文章的主要关注点在反射部分,探讨什么样的光照模型适用于作为标准(Standard)来代表大多数的材质结果 i.e. 我们生活中可以接触到的各种材质。故之后我们讨论的“材质”会被限定在反射度(reflective),各向同性(isotropic), 非传导性的(dielectric),导电的(conductor),更短的平均自由程(short mean-free-paths)。

图五:(a)真实光照和物体间的交互 (b)BSDF光照模型 光线与“标准”平面交互产生的结果 左:光的交互 右:带有漫反射项(Diffuse Term)高光项(Specular Term)的BSDF光照模型

3.1.2 Material models 材质模型

在寒霜运用的标准的材质光照模型中,材质表面效果可以被划分为两个不同的项(term):对光线反应较平滑的部分被称为漫反射(diffuse),跨度较大的部分被称作高光(specular),见图五。物体的表面将空气和材质区分开,光滑的表面可以直接被菲涅尔准则概括,包括导体和非导体。但当物体表面是不规则的情况下,见图六,文献表明基于微面元的模型[CT82]非常适合概括这类光的表面相互作用。根据论文中得出的结论,微面元理论可以被以下等式所概括(见等式1):

等式1

等式中的D项代表微面元散射项(也被称作NDF,Normal Distribution Function)。G项代表微面元中的遮蔽(Occlusion)也可以称为阴影遮罩(shadow-masking)。这个理论共同适用于漫反射项和高光项。两者唯一的区分就集中在微面元BRDF光照模型了。对于高光项来讲 ,当处在一个完美平滑的镜面时 ,因此可以用菲尼尔定律F进行数学建模。于是就推导出下面这个著名的算法:

等式2

D项在表面外观中占据了一个非常重要的作用,见图六。文献表明[Wal+; Bur12]最近公布了一项被称为“long-tailed”NDF,像是著名的GGX分布理论一样,可以模拟计算真实世界的表面效果。不仅如此,G项在高粗糙度的表面中也扮演着重要的角色,Heitz [Hei14]最近表明,Smith Visibility函数的计算是精确的并可以被用于G项中。他也指出学界通常会使用Smith Visibility函数的近似值,同时使用更精确的阴影遮罩(Masking-Shadowing)函数可以模拟由于微表面高度导致的阴影和遮罩建的相关性(见等式3)。图七展示了简化版的Smith函数和与高度相关连的Smith函数(height-correlated Smith Function)的区别。

等式3
图六:展示了使用D项模拟的不同粗糙度的物体表面。上:光线和微表面间的交互。中:得到的BRDF结果 。 下:在物体表面产生的结果
图七:在不同粗糙度的电解质Dielectric(上)和金属铬Chrome Metallic(下)的球体上对两种不同的Smith Visibility函数进行比较。值得注意的是height-correlated版本在粗糙度比较高的情况下会返回更多的能量。

对于漫反射项,当 遵循兰伯特模型的情况下,等式1可以被简化为:

等式四

直到最近,漫反射项 仍被假设为兰伯特模型。然而,除了多层的材质漫反射的部分需要和高光项保持一致,同时也需要把物体表面的粗糙度也考虑在内[Bur12](例如:高光项和漫反射项应该使用同样的粗糙度项[3]),见图八。其实等式4并没有具体的解,Oren et al. [ON94]使用高斯NDF分布式和V-Cavity G项推算出了这个等式的经验近似值,也就是我们常说的Oren-Nayar模型。为了充分证明我们的算法模型,需要按照Gotanda[Got14]中提到的GGX NDF算法求等式4的近似值。具体对漫反射模型的研究细节可以被收录在附录B中。

图八:展示了光在微面元上与有反射BRDF fm的高光fr项(左)和有漫反射BRDF fm(右)的漫反射项fd的交互结果

Burley[Bur12]公布了另一种根据真实世界表面计算的漫反射模型,参见等式5. 因为这是一个经验等式,所以我们可以允许我们在引擎中实现MERL数据库里的各种材质效果。正因为这个原因和它的易用性,我们就在寒霜中使用了这个模型。它在漫反射项中会考虑到材质的粗糙度,并在掠角(grazing angle)产生了一些后向反射。

等式五

3.1.3 Energy Conservation能量守恒

在能量守恒中,很重要的一点是保证输入不要大过输出的能量。此外允许我们正确处理掠角的行为,对于这里的掠角来说,高光项比漫反射项更容易被散射。在寒霜中我们通过保证半球方向反射率的值低于整体BRDF的1(漫反射项+高光项),因为该半球上的总反射率有恒定的照明值,可以确保半球方向反射率低于给定的入射方向。这种方法使得计算更加简便,确保能量守恒。

等式六

由于高光项和漫反射项之间存在非直接对应的关系,就使得进行正确的推导过程比较艰难。(比如附录C中高光项和漫反射项都基于微面元模型的案例)。Disney 漫反射模型的一个重要缺陷就是它无法遵循能量守恒[4]。图9a展示了Disney漫反射模型的半球方向反射的数据。由于它最终返回的反射值高于1,所以很显然这个BRDF并不符合能量守恒的原则。

图9:Disney漫反射BRDF在各种视角下和粗糙度下的半球方向反射率。左:原有的反射值,高于1。 中:经过归一化的新反射值 。右:经过归一化后高光项和漫反射项的合

我们对它进行了简单的修改,在保证原有反射特性的情况下补偿了缺失的能量。代码1展示了重新归一化后的Disney方法。图9c展示了由高光微面元模型fr和Disney漫反射模型fd组成的完整半球方向反射f。虽然没有完全等于一,但也足够接近了。图10对比了原有的Disney漫反射项和重归一化后的版本。

1 float Fr_DisneyDiffuse ( float NdotV , float NdotL , float LdotH ,
2                          float linearRoughness )
3 {4      float energyBias = lerp (0 , 0.5 , linearRoughness );
5      float energyFactor = lerp (1.0 , 1.0 / 1.51 , linearRoughness );
6      float fd90 = energyBias + 2.0 * LdotH * LdotH * linearRoughness ;
7      float3 f0 = float3 (1.0 f , 1.0 f , 1.0 f);
8      float lightScatter = F_Schlick ( f0 , fd90 , NdotL ) .r;
9      float viewScatter = F_Schlick (f0 , fd90 , NdotV ).r;
10
11     return lightScatter * viewScatter * energyFactor ;
12 }

3.1.4 Shape characteristics 形状特点

基于微面元的高光BRDF的部分对最终效果有强烈影响的特性通常会被人们忽略,它们集中表现为下面两个部分:

  • Half-angle parametrization(半角参数化)

这里的参数化指代的是在BRDF形状中从法向入射角(normal incident angles)的各项同性到掠角(grazing angles)的各向异性非线性的转换过程。更多内容详见4.9

  • Off-specular(非镜面反射)

通常我们会认为BRDF lobe[5]以反射的观察方向(view direction)为中心。然而由于<n.1>和阴影遮罩(shadow-masking)G项的影响,BRDF lobe会在粗糙度增加的时候更偏向与法线方向,见图11。这个偏移的过程就叫做非镜面反射(Off-specular peak),它对于表现粗糙表面的物体时有重要作用。

图10: (a)Disney和兰伯特漫反射项的对比。 (b)原有的Disney漫反射项和前文提到的重归一化后的Disney漫反射项
图11:几种不同的观察方向下的叶状BRDF案例,可以明显看出主要的方向和镜像的观察方向R并不一致,而是单独的方向M 第一行a = 0.4, 第二行a = 0.8

Off-specular (非镜面反射)会在高粗糙度的表面产生巨大的差异。为了将这个因素考虑在内,我们在进行区域光(area light)和基于图像的光照(image-based light)计算时尝试对这个主要的方向进行数学建模,详见4.7的区域光部分和4.9的基于图像光照。

3.1.5 Frostbite standard model 寒霜中的标准模型

综上所述,寒霜的标准材质模型和在其他游戏引擎中使用的材质很相似[Kar13; NP13; Bur12]。它由以下几个部分组成:

  • Specular term fr :基于Smith correlated visibility方法和GGX NDF的微面元高光模型(见等式2)
  • Diffuse term fd :基于重归一化后的Disney漫反射模型

当最后计算光线交互(light integration)的时候对这两个部分的模型进行主方向上的矫正(Off-specular peak非镜面反射峰值处理)。被开放出来用于调整这些数学模型的参数会在下一个部分提及。寒霜同样支持一些特殊的材质模型,例如Clear Coat(清漆)和Subsurface Scattering(次表面散射)。但本篇文章的内容仅着重于标准材质的阐述。

1 float3 F_Schlick (in float3 f0 , in float f90 , in float u )
2 {3 return f0 + ( f90 - f0 ) * pow (1. f - u , 5. f);
4 }
5
6 float V_SmithGGXCorrelated ( float NdotL , float NdotV , float alphaG )
7 {8 // Original formulation of G_SmithGGX Correlated
9 // lambda_v = ( -1 + sqrt ( alphaG2 * (1 - NdotL2 ) / NdotL2 + 1)) * 0.5 f;
10 // lambda_l = ( -1 + sqrt ( alphaG2 * (1 - NdotV2 ) / NdotV2 + 1)) * 0.5 f;
11 // G_SmithGGXCorrelated = 1 / (1 + lambda_v + lambda_l );
12 // V_SmithGGXCorrelated = G_SmithGGXCorrelated / (4.0 f * NdotL * NdotV );
13
14 // This is the optimize version
15 float alphaG2 = alphaG * alphaG ;
16 // Caution : the " NdotL *" and " NdotV *" are explicitely inversed , this is not a mistake .
17 float Lambda_GGXV = NdotL * sqrt (( - NdotV * alphaG2 + NdotV ) * NdotV + alphaG2 );
18 float Lambda_GGXL = NdotV * sqrt (( - NdotL * alphaG2 + NdotL ) * NdotL + alphaG2 );
19
20 return 0.5 f / ( Lambda_GGXV + Lambda_GGXL );
21 }
22
23 float D_GGX ( float NdotH , float m )
24 {25 // Divide by PI is apply later
26 float m2 = m * m ;
27 float f = ( NdotH * m2 - NdotH ) * NdotH + 1;
28 return m2 / (f * f) ;
29 }
30
31 // This code is an example of call of previous functions
32 float NdotV = abs( dot (N , V )) + 1e -5 f; // avoid artifact
33 float3 H = normalize (V + L);
34 float LdotH = saturate ( dot (L , H ));
35 float NdotH = saturate ( dot (N , H ));
36 float NdotL = saturate ( dot (N , L ));
37
38 // Specular BRDF
39 float3 F = F_Schlick (f0 , f90 , LdotH );
40 float Vis = V_SmithGGXCorrelated ( NdotV , NdotL , roughness );
41 float D = D_GGX ( NdotH , roughness );
42 float Fr = D * F * Vis / PI ;
43
44 // Diffuse BRDF
45 float Fd = Fr_DisneyDiffuse ( NdotV , NdotL , LdotH , linearRoughness ) / PI ;  

3.2 Material system材质系统

3.2.1 Material材质

大家熟知的许多游戏实际上都是使用寒霜制作的,从体育游戏到竞速游戏,从第一人称到开放世界。为了满足这些不同种类游戏的要求,引擎本身的灯光和材质的支持就需要有更多的灵活性。进一步说,在我们转换到PBR流程时一个很重要的约束就是需要确保之前非PBR的老管线中的光照模型也能转换过来,而不是直接抛弃。光照的渲染方式也需要是可控的,如常见的:延迟渲染(Deferred)、前向渲染(Forward)、混合渲染(Hybrid)。这些会在4.11中详细说明。

在寒霜中,一个材质被定义为:

  • 一个光照渲染路径(A lighting path):延迟(deferred)、前向(forward)、混合渲染。
  • 一个控制参数(A set of input parameters):漫反射(diffuse)、平滑度(smoothness)、厚度(thickness)等…
  • 一个材质的算法模型(A material model):粗糙表面材质(rough surface),透光材质(translucency),皮肤材质(Subsurface Scattered),头发材质(Anisotropic)等… 同样这里面也会有非PBR的算法模型。这一部分主要是shader代码。
  • 一个GBuffer的排布(A GBuffer Layout):这一点主要是支持延迟渲染。Buffer的数量会作为变量进行储存。

游戏开发团队可以根据给定的渲染路径选择可以使用的材质模型。游戏中的每个材质都有对应的材质ID进行储存。在引擎中包含所有常见属性的基础材质(我们称为标准材质Standard)会涵盖其他特殊材质公用的控制参数(例如粗糙度roughness)。一般来说,早延迟渲染路径中,根据Burley的算法模型[Bur12],我们选用Disney模型作为漫反射的通用模型。同时我们也支持其他两种基础材质:two-color材质和old材质。

Disney通用材质:我们的Disney材质中包含如下的控制参数:

  • Normal:标准法线
  • BaseColor:根据Burley的演讲内容,该参数定义非金属材质和带有法线上入射角(f0)的菲涅尔反射金属材质的漫反射辐射率(diffuse albedo)。对任意金属材质来说反射率低会定义额外的高光遮蔽值(micro-specular occlusion)
  • Smoothness:定义了物体的粗糙度(roughness)。我们选择使用平滑度(smoothness)而不是粗糙度(roughness)来命名的原因在于它们在参数范围上能让美术人员更直观的进行调整,且它们已经在之前的非PBR工作流中习惯了这一参数。根据Burley的演讲这里的平滑度被重映射到感性的线性平滑值(1-alinear)。
  • MetalMask:定义了物体表面的金属度/传导性(如:导体/绝缘体),这一点也出现在Burley的演讲中。为了让参数更直观,易于美术人员理解,我们将其命名为金属度遮罩。
  • Reflectance:将法线入射角方向(f0)的菲涅尔反射率定义为对美术人员友好的非金属材质范围。该属性值域偏低的部分定义了非金属材质的微表面高光遮蔽项。

值得一提的是材质中的平滑度值域的重映射算法,我们选取了几个不同的重映射算法,并和美术人员一起测试其可行性。图12展示了几种不同的算法和对应的结果。和Burley在演讲中提到的相同,我们选取了艺术家们最满意的squaring算法。

材质中的反射值(Reflectance)使用了下列的重映射算法:

该算法目的是为了将f0的值域映射到可以包含高菲涅尔值(如宝石类材质)的范围中,并具有将RGB 128重新映射到普通电介质(Dielectric)4%反射率的约束值。在宝石类材质中,f0包含的菲涅尔近似值囊括了从8%的红宝石到17%的钻石。为了在算法中取近似值,我们将这个值限制在16%。测试数据和普通值的对比详见图13。在实际运用中,由于实时渲染的限制,对于1%-2%的变化几乎无法察觉。但高于4%的增长就比较明显了。

对于非金属(反射Reflectance)对象和金属(BaseColor)对象在法线入射角上的菲涅尔反射率(f0),我们使用低于2%(水的反射率)的值来控制微表面反射(详见4,10)。这意味着由于我们特殊的编码方式,非金属物体需要使用不同范围的微表面高光遮蔽值。

图 12:平滑度重映射算法对比。其中 曲线符合Burley提出的重映射算法[Bur12]。深蓝色的曲线 符合Crytek的Ryse提出的重映射算法[Sch14],但没有体现在可视化的图像中,但 曲线是最接近这个算法结果的。
图13: 图表中展示了反射率的重映射算法,以及对应的参考材质参数

迪士尼材质使用了3.1中提到的标准材质模型,相关联的G-Buffer内容详见表2。它包含以下的约束内容。

  • 材质中所有的基础参数(法线,基础色,平滑度,金属遮罩,反射率)需要能够支持与延迟渲染中Decal贴图的混合。不可混合的参数,如材质ID(Material ID)被存储在透明通道中。我们也避免了会影响混合质量[6][MOU7] 的因素,压缩和编码机制。
  • MSAA的支持也避免了对基础色(BaseColor)属性色彩纯度的二次采样[MP12]。
  • 常用的材质属性需要被集中在同一个Buffer中
  • 每个材质中的材质ID(Material ID)属性需要被储存在同一位置。
  • 由于优化需要,意味着除了深度buffer外,标准材质只能占用四个buffer
表2:Disney延迟渲染基础模型的GBuffer分布

我们可以 通过材质ID(Material ID)分析材质中的各种数据。比如在延迟渲染中,皮肤材质的材质ID就储存了扩散剖面的信息(Diffusion Profile)。而各向异性材质中则是储存了各向异性的强度。AO则是常见的环境光遮蔽项,它不受材质类型的限制,始终存在GBuffer中,详见4.10 。光线属性(Radiosity)作为一个光照缓存,是用来储存在GBuffer创建时计算出的漫反射间接光信息。法线在GBuffer里被分为了两个部分,为了进行法线混合,使用了有损的编码方式(具体算法会在之后提到)。

多层材质:在表现混合材质的高光时,Disney材质的参数(单一颜色,金属度遮罩,可缩放的反射值)不足以达到完美的效果。比如金属材质和非金属材质表面上的金属氧化物。因此我们在shader library中添加了带有f0和漫反射颜色的多层材质,对应的GBuffer分布见表三。f0项和反射项(Reflectance)相同,支持较低范围内的微表面遮蔽(micro-occlusion)效果。对此,引擎中需要保证两种参数化间能够相互转换。从Disney材质到多层级材质间的转换变得没有那么重要,因为它们在GBuffer处理的光照计算过程中就已经有这个过程了。相反,从多层级材质到Disney的转换因为需要非线性的优化过程会占用更多的资源。这种情况只会在材质需要从单引擎的模式转换到其它,过程详见Appendix D。

表3: 多层级延迟渲染的基础材质GBuffer分布

传统基础材质:在[Cof10]中描述的旧管线中非PBR引擎的基础材质。为了将旧管线中的非PBR材质更简单的转换到PBR管线中,并保证基本的美术效果,我们加入了新的自动转换工具。这个过程在给shader输入参数前完成。但这个转换流程得到的效果质量相对较低。我们暂时没有找到能保证美术质量前提下的转换方式。

图14展示了不同材质参数见的转换过程,以及对应依赖的光照模型和算法。由于性能要求,区域光area light(4.7)和基于图像的光照依赖于与整合前的材质模型。这说明光照和材质模型在引擎中是密不可分的。在PBR流程中唯一需要区别对待的光照和材质的情况只存在于资源生产中:美术人员无法获取任何shader中的光照信息。但在这种情况下,这样的对立并不存在,因为添加新的材质意味着需要编写新的光照计算代码。

3.2.2 Render loop渲染流程

上一节解释了材质的定义,这节会进一步解释材质是如何被渲染出来的。使用前向路径渲染的物体:先根据光照模型编写对应的代码,接受被调整的参数数据,最后将物体完整的渲染出来。但延迟渲染的方式就需要更多的步骤了,为了更有效率的渲染材质,下列因素需要被考虑到:

  • 材质模型尽量使用动态分支进行微小的调整,并尽量使用公共库里的光照函数,避免在stencil buffer里产生多余的光照Pass
  • 材质尽量和基础材质保持参数统一,依赖动态分支来储存不同的参数。差别较大的材质需使用不同的GBuffer通道,同样的,使用stencil buffer在光照Pass中识别他们。
  • 我们通过执行fix-up pass,对不同GBuffer分布的材质共享同一个光照Pass
图14: 寒霜中的材质渲染原理图。输入参数列表(MaterialRootData)会被转换为用来计算材质模型方法的光照评估结构(Material Data)。

光照方法包含所有类型的光源:精准光源,区域光,和基于图像的光照。如果一个材质使用了延迟渲染路径,它会被打包储存到GBuffer中,在需要计算时转换出来。如果是前向渲染路径,会直接进行转换过程。如果不同的材质间可以被打包为同一个光照评估结构,那么就可以使用同一个着色器代码进行渲染

对于在几何阶段消耗较大的物体,我们一般会减少它的GBuffer创建消耗,但仍使用同一套光照pass。比较常用的是植物模型中,只选取前两个创建的GBuffer进行计算,剩下的使用在代码3提到的fix-up pass 经过多pass计算后生成最终的GBuffer,这个会根据硬件承受能力的不同决定读写速度。

1 void psMain (
2 in float4 pos : SV_Position ,
3 in float2 texCoord : TEXCOORD0 ,
4 out float4 outGBuffer2 : SV_Target0 ,
5 out float4 outGBuffer3 : SV_Target1 )
6 {7 float4 gbuffer0 = FETCH_TEXTURE ( g_gbufferTexture0 , ( texCoord .xy , 0) ;
8 float4 gbuffer1 = FETCH_TEXTURE ( g_gbufferTexture1 , ( texCoord .xy , 0) ;
9 float3 worldNormal = normalize ( unpackNormal ( gbuffer0 .rg , gbuffer1 .a ));
10
11 // Read value for radiosity from a global diffuse probe
12 float3 indirectLight = calcShL2Lighting ( worldNormal , ...) ;
13
14 // Fix smoothness , metalMask and reflectance with a global common value
15 // ambient occlusion set to 1
16 outGBuffer2 = float4 ( g_smoothness , 0, g_reflectance , 1) ;
17 outGBuffer3 = packLightingRGBA ( indirectLight );
18 }  

因此渲染流程如下文所示:

// GBuffer creation
ForEach different stencil bit doRender GBuffer pass for deferred material with n number of buffersDo branching in shaders if neededRender GBuffer pass for deferred material with (n + 1) number of buffersDo branching in shaders if needed// Fix-up pass
ForEach deferred material requiring sharing the deferred shading passRender GBuffer _x-up pass// Decals
Render deferred decals affecting common parameters// Deferred shading
ForEach individual deferred shading pass required doRender deferred shadingDo branching in shaders if needed// Forward rendering and lighting
ForEach ForwardMaterialModel doRender forward lighting

贴花Decal会在下一章中讲到。在实际开发过程中,因为材质参数和光照函数的耦合性,我们无法对所有的参数进行自定义。MaterialID为我们提供了一种简单的自定义材质的方式,但这是建立在代码复用和动态分支的基础上。比如常见的清漆材质(Clear Coat)就需要对光线采样两次。该系统使得从非PBR引擎到当前使用的管线中的转换操作变得十分方便。

3.3 PBR and Decals 物理渲染中的贴花

贴花可以被看作比较灵活的多层级材质,使得我们可以在模型表面创造出丰富的细节和纹理。因此在PBR中拥有一个物理准确的贴花就变得重要起来。这里的“准确”是指,即使是在多层贴花混合的情况下贴花也能够在整体计算光照前和原有的材质属性正确混合。在寒霜中为了达到上述效果,我们主要是用延迟路径来渲染贴花(延迟贴花deferred decals[6]),但是在硬件和性能的约束下想要处理好它们几乎是不可能的。考虑到基于物理渲染的材质准确性,我们没有找到正确混合贴花的解决方案,但为了文章的完整性,下面列举出了主要的难点和我们在寒霜中实际用到的方法。

  • Correctness(准确性):材质和Decal贴花混合的准确性是非常重要的,这里的准确是指在混合之后得到的新材质参数也需要符合物理准确。例如,对于具有标准解码方式的法线(normal ∗0.5+ 0.5 or normal.x, normal.y)只有进行替换(如线性插值)的方法才能正确恢复法线。有些方法已经被验证为会产生错误结果,例如简单的相加(additive)。这对程序化混合来说是一个很好的案例,按支持的平台相对较少。在寒霜中我们避免对少部分材质属性的压缩,而更依赖于对alpha混合简单的线性插值的结果。
  • Interaction(操作性): 为了得到正确得混合结果,贴花材质和目标模型材质应该使用相同得光照模型(因为他们有同样的材质参数)。因为它需要给每个贴花加上对呀的材质ID,并对每一个贴花材质执行一遍stencil pass,所以从产品结果和性能的角度来讲,着并不是一个很合理的渲染方式。我们根据游戏中选择的材质参数来限制贴花的参数,其中包含法线(normal)、固有色(BaseColor)、光滑度(smoothness)。其他的参数如金属遮罩,反射强度只在选用Disney光照模型的时候添加。担任仅靠这几种参数来控制显然是不够的。影响其他默认材质ID的贴花会产生不必要的效果。材质数据和材质ID不是能够相互混合的数据,它们只会被替换。一种方法是使用单独的透明通道作为混合因素,让中间值为0。另一种方式是禁止贴花影响其他的材质,材质ID为0 。
  • Indirect Lighting(间接光):模型表面需要在光照计算前处理好贴花对它的影响。在寒霜中,间接漫反射(Indirect Diffuse)在产生GBuffer的pass被计算出来,避免被后续计算中的其它材质因素所影响,仅保留材质中的固有色。一种方法是在deferred pass中处理漫反射阶段所有的间接光,例如在场景中生成的light probe体积纹理。另一种方式是用预处理的贴花pass,在UE4中被提出[UE4],将贴花数据储存在GBuffer创建之前的buffer中。这样以来被渲染的物体需要接收两次贴花,由于这种方法会有隐藏的性能开销,所以我们选择保留这部分瑕疵。
  • Emissive(自发光):由于在寒霜中GBuffer的储存空间有限,为了保证性能,大多数情况下材质的自发光属性都被整合在辐照度的缓存中,详见4.8。这里的辐照度缓存会在之后参与到材质固有色的计算中。那些修改了自发光属性的贴花会对自发光的颜色产生影响。在寒霜中我们接受这类由于贴花和自发光冲突所产生的瑕疵效果。
  • Highlight shape preservation and specular aliasing(高光形状的保留和重叠):任何对于物体法线信息的修改都意味着像素覆盖区域下的NDF发生了改变,它会将在贴花执行之前保留的任何形状(通过Toskvig或LEAN映射进行处理)进行偏移,详见5.3。一种解决方案是在贴花处理完后作为后处理执行法线的滤波pass进行矫正。
  • Forward rendered surfaces(前向渲染的物体表面):延迟贴花不支持任何透明或是前向渲染的物体。常见的解决方案是依赖于将前向渲染的贴花和光照结果进行混合。支持贴花参数和前向渲染物体的混合是可行的,但会对美术方向的调整有很大限制(限制混合模式, 限制贴图数组的大小等等),我们在光照计算的过程中也会发现这样的问题。所以在这里可以使用光照计算中已有的解决方案来解决延迟/前向渲染路径中的贴花问题。

文中提到的几个非常有意思的论文链接:

https://blog.selfshadow.com/publications/blending-in-detail/​blog.selfshadow.comhttp://selfshadow.com/publications/s2012-shading-course/​selfshadow.comhttp://www.pauldebevec.com/Research/HDR/.​www.pauldebevec.comReflectanceModel​graphics.pixar.com

参考

  1. ^寒霜(Frostbite)是EA的一款自研游戏引擎,了解更多请移步至:http://www.frostbite.com
  2. ^我们参考了很多现有的渲染材质库,但大多都不符合物理准确的要求,Mitsuba和Maxwell是我们经过对比后倾向的选择。
  3. ^一般来说有两种方式对漫反射和高光项进行数学建模。一种是作为想同的层级,另一种则相反。
  4. ^这是有意为之,可以参见Burley[Bur12]。该想法是希望让美术人员在调整粗糙度数值的时候能得到统一的漫反射颜色。
  5. ^实际上就是Specular lobe可以见图5、6
  6. ^包含体积贴花(volume decals)[Per11]和传统的几何贴片(Geometric decals)

批量 材质 调整_寒霜引擎的PBR实践3.0(一)材质篇相关推荐

  1. 寒霜引擎(镜之边缘:催化剂)中的屏幕空间反射

    http://tieba.baidu.com/p/3986803871 寒霜的SSR方法用到一个比较巧妙的优化方法,储存射线检测时被击中的点给临近像素复用,这样可以快速地在重要性采样时获得采样数据,从 ...

  2. 批量 材质 调整_游戏图形批量渲染及优化:Unity静态合批技术

    作者:枸杞忧天 (本文首发于公众号"偶尔学学Unity",文章仅为作者观点,不代表GWB立场) 最近在准备公司的技术分享,主题是入门批量渲染,想着反正也总结了,不如充几篇博客吧,也 ...

  3. 寒霜引擎中strand-based(基于线)的头发渲染

    头发在游戏中渲染的简要历史 89,kajiya-kay的头发光照模型 相当长时间中在用,也应属于刚好适合当前(2019)手游的光照模型,现在逐渐退出历史舞台. siggraph03,年marschne ...

  4. solidworks渲染材质库_如何添加亲的solidworks材料库超全GB材质库

    有一个比较全的材料库对于设计来说是很有用的,给零件添加材料后可以估算零件的重量,可以把材料链接到明细表,可以用来做有限元分析. 今天介绍给大家的这个GB材料的材质库,里面的材料很全,当然不可能把有的材 ...

  5. 我的世界java服务器怎么加材质包_怎么在网易我的世界服务器中加入材质包

    五月是天o:PE版怎么加材质包呢? 发布于 2020-02-05 11:17:16 111254度数:你只需要在菜單,資源包裏面打開資源包文件夾,之後你把資源包放進去 发布于 2020-01-21 2 ...

  6. 我的世界手机版javaui材质包_我的世界国际版1.17.0手机版下载-我的世界国际版1.17.0手机版下载安装...

    我的世界国际版手机版是一款轻松消遣的益智娱乐游戏.游戏的世界是开放的,而且有着独特新颖的世界结构.其内更是有着各种各样的基础道具,你可以利用这些基础道具改造世界的哦,你能改造成什么模样呢? 我的世界国 ...

  7. 寒霜2引擎的光照系统确实不是盖的

    曾经以为孤岛危机的画面最牛逼的.结果当我看到战地3时,就彻底震精了!这还是游戏嘛?简直就是电影!它强大的光影系统马上照亮了你的十二氪金狗眼.叛逆连队2的寒霜引擎已经给了我不少的惊喜,寒霜2直接秒掉了我 ...

  8. [转]《战地3》寒霜2引擎渲染流程图文详解

    一直一来受制于技术.预言和环境,中国国内玩家.开发者对于国外先进游戏引擎的渲染流程知之甚少,虽然没有技术封锁缺更似自我封锁,在GDC上很少看到中国开发者的身影,无法学习到先进的开发经验. 首先来回味一 ...

  9. [转]战地3寒霜2引擎详解:物件光照效果技术特性

    在GDC2012上DICE将讲演<战地3>寒霜2引擎的升级版技术效果,不过在此之前请先收下零zXr0带来的迟到的礼物:DICE之野望:战地3寒霜2引擎技术特性效果详解. DICE工作室正计 ...

最新文章

  1. 超级实用的 MySQL 常用优化指南!
  2. Dart Metadata 使用
  3. 学习笔记Hadoop(六)—— Hadoop集群的安装与部署(3)—— 配置ssh无密码登录
  4. 计算机硬件系统的ppt,计算机硬件系统.ppt
  5. 阿里云ECS服务器磁盘空间异常,或者爆满
  6. redis将散裂中某个值自增_Redis总结
  7. 设计模式(14)-Flyweight Pattern
  8. Linux Kernel中irq handler, softirq handler 和 tasklet
  9. python加载dll文件_python引用DLL文件的方法
  10. logistic回归分析优点_SPSS统计分析全解析Logistic回归(逻辑回归)
  11. CentOS 7下载及安装教程
  12. 软件开发,网站建设,性价比高的PLC仿真软件。
  13. python 开发金山打字通辅助脚本
  14. Can't open /dev/sda3 exclusively. Mounted filesystem?解决办法
  15. php 微信多客服系统,如何使用微信公众平台开发模式实现多客服
  16. 串口工具Kermit
  17. Android 系统第三方应用系统修改权限及在应用上层显示权限默认打开
  18. 【特征检测】BRISK特征提取算法
  19. Newton's Method 牛顿法求极值.
  20. 可运行动态路由的Linux,使用Quagga实现Linux动态路由

热门文章

  1. 线上MySQL某个历史数据表的分区笔记
  2. 【BZOJ 1222】 [HNOI2001] 产品加工(DP)
  3. 物联网搜集大量数据协助制定业务策略 成为银行业竞争利器
  4. Vue 2.x 实战之后台管理系统开发(二)
  5. UISegmentedControl UISlider
  6. 纯CSS打造圆角Table效果
  7. 思科Catalyst1900交换机上速配VLAN
  8. 基于C# 百度AI和科大汛飞语音合成SDK
  9. Requst Servervariables
  10. 接口测试---mock变量自定义变量的使用