【游戏引擎入门到实践】六.渲染方程进一步优化的解决方案

718 阅读32分钟

5-10年前(笔记写于2023年1月)游戏行业使用的技术

一.光照

0.背景

因为硬件发展。游戏场景中90%的物体都不会移动,而太阳的角度也是固定的。因此可通过空间换时间的思路,预先计算出更精确的光照信息;

1.全局光照GI(Global Illumination)

1.背景

(1)全局光照的重要性

更真实,更有层次感,而不是平面感。

(2)来自四面八方的光照,将其分解为直接光照和间接光照。

GI:Global Illumination 全局光照 = Direct Illumination 直接光照 + indirect Illumination 间接光照;

半球面空间的采样,需要大量积分运算。

(3)目前成熟的方案,比如Lumen用光线追踪处理直接光,用辐射度算法处理间接光。

2.简单粗暴的方法进行计算、采样

(1)比如蒙特卡罗方法

在球面上撒无数个采样点,依次计算每个采样点的光照信息,以进行近似。

在绘制时,对于屏幕上的每个像素点,当对其进行着色时,都需要对这个球状的光照贴图进行采样,然后再进行累加。这实际上是一个卷积运算,计算量十分巨大。

(2)更优的解决方法~傅里叶变换;

2.傅里叶变换

1.概念

将一个连续信号分解成多个不同频率的周期信号的累加;

2.应用到全局光照

全局光照信息可以看作是空间上的一个连续信号,通过傅里叶变换将其变换成频域中的多个不同频率信号的累加。然后截取前几项(越往后的项影响越小),就完成了对空间中的信号的近似表达。

3.优点

(1)可以高效地压缩数据

(2)可以降低卷积运算的复杂度。

3.球面调和函数/球谐函数~ Spherical Harmonics

1.背景

(1)根据傅里叶变换得到了著名的球面调和函数 (Spherical Harmonics,也叫做球谐函数)

将球面调和函数引入图形学领域的是微软研究院的Peter-Pike Sloan(下文简称P.P.Sloan)。

(2)他提出,对辐射亮度的传输进行预计算,以实现低频光照环境下的软阴影、互反射和焦散效果。为此,P.P.Sloan引入了球面调和函数。

2.数学知识

(1)球面调和函数是球面上的一组正交基,类似于一维圆上的傅里叶级数。

(2)因为球谐函数的基函数是相互正交的,因此定义在球面上的任意标量函数都可以通过积分计算出,其在对应基函数上的投影系数。

(3)而通过这些系数,就可以重建出对应的近似函数。

(4)更有意思的一个属性是,球面调和函数的二阶导永远是零,这表示这个函数永远是光滑的。

(5)总结核心思想:在球面上的两个函数的卷积,可简化成将两个函数分别投影到球面调和函数上,然后对投影得到的结果进行卷积。

3.对光照信号重建

(1)可使用简单的多项式乘法和加法 (即若干阶球面调和函数的**线性组合* * ,将这个信号大致表达出来;

(2)在游戏中,一般使用二阶到三阶球面调和函数就已经足够

(3)如果只需要表示低频信号,使用一阶球面调和函数即可。

(4)思路:

1)场景中每个点设置一个探针 (Probe),记录该点的Irradiance,将每个点的Irradiance信息展开。

2)然后使用球面调和函数对其进行压缩。

3)然后在程序中对Irradiance进行重建,

4)如果只使用二阶球面调和函数,会发现,虽然重建后的画面很模糊,但已经基本反映出了光照的方向信息,而且整个数据都很连续。

5)如果我们想知道任意一个方向上的光强,只需要一次线性的向量运算即可。

4.二阶球面调和函数的四个参数

每个的权重不一样,重点介绍下面两个

(1)L0

相当于对整个环境的光场做了一次加权平均。

而现代游戏基本上是HDR模式的,所以对球面调和函数的系数的压缩采取了HDR压缩方法,这里可以选择BC6H纹理进行存储,H代表高分辨率,我们只需要使用Alpha通道即可。

(2)L1

对于L1阶的系数来说,则可以使用LDR压缩方法。即使用高精度的BC7算法进行压缩,整个球面上的光照表达也只需要32个比特位。这相当于我们使用了一个和带有Alpha颜色的存储空间相同大小的空间,就能够存储每个点上的光场信息。

5.计算漫反射或镜面反射

使用球面调和函数表示光场信息时,在计算漫反射或镜面反射项时,都可以将其转换为两个向量之间的点积或者卷积。

6.补充知识~LDR、HDR、ToneMapping、HDR与Bloom、ACES曲线

zhuanlan.zhihu.com/p/510815658

Dynamic Range(动态范围)=最高亮度/最低亮度

1.LDR = Low Dynamic Range
  • 8位精度,8位 = 2^8= 256(0~255)
  • 单通道0-1
  • 常用LDR图片存储的格式有jpg/png等
  • 常用DCC工具中的拾色器、一般的图片、电脑屏幕都是LDR。例如拾色器中0-255(256)
2.HDR= High Dynamic Range
  • 远高于8位精度
  • 单通道可以超过1
  • 常用HDR图片存储的格式有hdr/tif/exr/raw等(其中很多是相机常用格式)
  • HDRI、真实世界
3.ToneMapping:

(1)将超高的动态范围(HDR)转换到我们日常显示的屏幕上的低动态范围(LDR)的过程。色调的一种映射关系。

(2)ACES曲线

1)ACES,Academy Color Encording System,美国电影艺术与科学学院(AMPAS)制定的颜色编码系统。动态范围更广,渲染更逼真。

2)ACES曲线,是最流行、最被广泛使用的ToneMapping映射曲线。

3)对比度提高,能很好的保留暗部和亮部的细节。

4.Unity中的HDR设置

(1)相机的HDR(2)lightMap的HDR(3)拾色器的HDR设置。等

5.HDR与Bloom,Bloom的实现过程

(1)渲染出原图

(2)计算超过某个阈值的高光像素

(3)对高光的像素进行高斯模糊

(4)然后叠加光晕、成图

4.光照贴图(Lightmap)

1.背景

(1)是一种空间换时间的策略。

(2)Lightmap最早并不是为了实现全局光照而发明出来的;有个游戏开发中,当时硬件无法实时计算阴影,所以引入了光照贴图对阴影进行预计算。后来阴影技术发展了,这个做法就淘汰了。

2.烘焙

(1)后来考虑如何实现实时光照效果时,又受到了Lightmap的启发。通过球面调和函数,就可以将整个场景的光照信息烘培到一张图上。

(2)通过上述方式烘焙出来的贴图称为Atlas,翻译成中文叫做航海图或者图集,即将很多几何体平铺到一张图上。

(3)烘焙前的注意事项

1)需要对世界的几何信息进行简化

因为过程中有一步称为参数化 (Paramitization),会将三维空间中复杂的几何体投影到二维空间。

如果几何信息太复杂,参数化就会很复杂。

2)对于同样的面积或体积,所分配的纹理的精度要基本相同。

3.光照计算

(1)高配置的电脑组成的集群来进行计算的,也叫做“Light Farm”

(2)烘培过程一般需要半个小时到一个小时左右,会让3A游戏的开发效率急剧下降。

(3)效果非常好。

烘焙的全局光照效果,再叠加上直接光照,基本上可以实现光线的反弹,AO环境光遮蔽,以及相邻建筑物之间的软阴影。这时再加上主光源,整个的光照环境就非常饱满。再配合上材质的效果,你会发现这种感觉非常真实。

4.光照贴图的优势

(1)虽然光照贴图的烘培速度特别慢,但运行时的效率非常高,因此运行时的成本很低。

(2)光照贴图是离线烘焙的,在将整个空间进行分解之后,可以产生很多细节而微妙的效果。艺术家们非常喜欢这种效果。

5.光照贴图的缺点

(1)非常长的烘焙时间;

(2)只能处理静态物体和静态光;当物体发生了移动,或者光源发生了变化,之前烘培的内容就无法继续使用了。

1)研究员研究,实时更新光照贴图,但是技术难度很大。

2)其他技巧,从物体周围去采样一个点处的光照贴图,然后可以猜测环境光的数值,从而给物体一个光照值。

但是有问题,物体周围有阴影,比如角色走到阴影附近,阴影会将角色突然变黑,而当角色走开之后,又会突然变亮。

(3)光照贴图的存储和GPU占用的消耗也很大;

因为光照贴图本身是一个空间换时间的策略。在运行时,光照贴图本身可以轻松占用几十兆到一百兆的存储空间,具体取决于场景的大小。场景越大,烘焙时间也会越长。

(4)现代游戏中,光照贴图的方法可能会被逐渐淘汰。

1)Layaair 3.0大升级,使用了这个技术来实现更细腻的GI效果。

2)cocos三月底3.7.2的版本,也支持了“高精度光照贴图”烘焙。

开启该功能,会使用 16 位颜色代替原本的 8 位颜色,并且会单独烘焙 AO 通道。

此功能可用来解决灯光强度过高时,贴图精度不够而产生色斑的问题,但是缺点是会增大光照贴图包体。

3)senseCube额外写了gltf扩展来支持光照贴图~GLTFHubsLightMapExtension。

6.光照贴图方案值得学习的两个思想

1.第一个思想: 空间换时间 ,光照贴图存储了大量的预计算结果。

2.第二个思想:对场景的参数化思想。

(1)在光照贴图中,场景被参数化成了二维纹理(将其“拍平”到二维空间上),其实也可以参数化成三维的体素 (Voxel)

(2)游戏场景是很复杂的,将场景变成一个易于管理和表达的二维纹理或三维体素结构后,就可以进行很多计算;

5.光照探针Light Probe,空间体素化的算法

1.概念

(1)在空间上撒一堆采样点,每个点上的光照信息用一个探针来表示,叫做光照探针。

(2)对于每个光照探针,采样它的整个光场,当物体或角色在场景中移动时,就可以利用物体周围的光照探针中存储的光照信息,进行插值,计算出物体上的光照信息。

(3)一个简单的空间体素化的算法。先将光照探针变成一个个的点,然后将这些点互相连接,形成很多四面体 (Tetrahedron) ,随后就可以对其进行插值。

2.如何布置采样点?

1.最早是人肉布置。

引擎研发提供工具,艺术家/美术来调整。场景一改就要重新布置。

2.自动化工具来生成和布置采样点

(1)首先对空间中的几何结构均匀地生成采样点。

(2)根据玩家的可到达区域 (包括建筑物的几何结构),向外进行延拓,相对均匀地将采样点撒出去。

3.利用球面调和函数对采样进行压缩

(1)采样密度很大,占用过大空间

(2)因为我们只需要处理光照信息,而且大部分是漫反射信息。漫反射信息非常低频,可以使用球面调和函数对其进行压缩。

4.反射探针Reflection Probe

(1)背景

场景中有一些闪闪发光的物体,可以产生高频信息。当角色行走在这种环境中,所反射的信息就会经常变化。因此,制作一种专门记录反射信息的探针;

(2)优点

数量不多,但采样精度很高,对于高频信息非常敏感。

(3)缺点

开销很大,不适合渲染量太大的场景,也不适合数量太多。

5.光照探针的实现细节

(1)会在探针位置放置一个相机。 senseCube的skybox中也是这样实现,创建CubeCamera

(2)然后分别向周围的六个位置 (上下前后左右) 观察,拍摄6张照片。

(3)将这6张图片拼成一个图,然后使用GPU的着色器对其进行处理。

(4)光照探针的更新

1)不会每帧都对其进行更新,每隔几帧或者场景中的位置信息发生巨大变化时才更新;

2)而且引擎也不会立即更新,而是会寻找一帧相对较空的时间进行更新,保证帧率稳定;

6.两种探针配合的优点

(1)反射探针和光照探针的运行时效率非常高。

(2)能够同时处理静态物体和动态物体。

(3)配合起来能实现不错的全局光照效果。

反射探针一般会和光照探针分开采样,光照探针可以处理漫反射,反射探针可以镜面高光反射。

(4)实时更新,可以在运行时对反射探针和光照探针进行更新。

7.跟光照贴图对比的缺点

7-1.缺点

(1)无法做到,光照贴图所能实现的GI细节,比如软阴影以及物体之间的交叠感;

(2)不擅长,光的渗透效果 (Color Bleeding)

7-2.没有光照贴图效果好的原因

(1)因为光照探针的采样比较稀疏,一张地图最多只有几万个采样点。

(2)而光照贴图的采样密度很高,一张地图上大概会采样几百万个点。光照探针的采样率大约只是光照贴图的1%的数量级,肯定无法达到和光照贴图相同的效果。

8.cocos3.7版本,加入了光照探针和反射探针

(1)光照探针,Cube烘焙模式用来烘焙一定空间范围内的立体环境;

(2)反射探针,Planar平面实时反射模式主要用来模拟平面上的反射,如光滑地面、水面等。

(3)优化:使用 SphereProjection 球面投影 做了矫正,使得反射内容与物体接近吻合。

9.orillusion引擎的动态漫反射全局光照DDGI (Dynamic Diffuse Global Illumination)

(1)是一个基于 Probe 探针的全局光照算法。

(2)在空间中摆放许多个的 Probe探针,并进行分组,每组 Probe 打包成一个 DDGI Volume

(3)使用webgpu的Compute Shader 来计算每个Probe 的辐照度(光照信息)和 G-buffer(几何信息),这些信息从球面映射到八面体,再映射到正方形来存储。

(4)需要着色时,只需查看着色点周围的 probe 中存储的光照和几何信息来计算着色点的光照信息

(5)将 Volume 绑定到摄像机上跟随移动,Volume 内的物体会应用间接光照,即被间接光照亮。

从渲染效果等方面综合考量,官方设置的最大间接光源数量是32个。

6.基于图的光照~IBL(Image-Based Lighting) 图像光照

1.背景

(1)前面介绍的基于球面调和函数的lightmap光照贴图,它能够产生明暗的感觉,却无法产生更好的效果要求,即细节感和凹凸感。

(2)当角色在游戏中行走时,周围的环境一直在变,被光所照亮的部位也一直在变化,我们希望没有直接被光照亮的部分也具有我们想要的细节感。

(3)即~对于背光面的效果。提出了IBL来解决这个问题。也是一种基于物理的着色方案“Shading PBR with IBL”。

2.核心思想和基本概念

(1)核心思想:

对真实环境的光照做些预处理,可快速将整个环境对着色点的光照和材质通过卷积运算直接计算出来;

(2)基本概念:

1)一个点处的光照是来自于四面八方的,一般说来自于一个球面。

2)在计算机中,可用Cube Map来表达球面上的光照信息。

3)如果将Cube Map展开,会得到十字架图形。

3.依然从BRDF方程入手

可分为两个部分,一部分是漫反射项Diffuse,一部分是镜面反射项Specular。

后面PBR材质~Cook-Torrance模型,对BRDF函数的划分也是这样的,不过它主要处理反射项。

4.diffuse漫反射项

1.数学原理

(1)本质上就是一个余弦函数在球面上的分布,余弦积分。

余弦积分,是三角积分的一种(三角积分是含有三角函数的一种积分)

(2)对于任何一个法向的朝向点,在给定一个光照时,我们在计算出这个面、和球面上所有点的余弦波瓣积分之后,就可以提前计算出漫反射结果。这样计算出的图叫做“Diffuse Irradiance Map”。

(3)当知道一个环境上的光照信息之后,对于漫反射部分,无论表面的法线如何旋转,通过对Diffuse Irradiance Map进行采样,我们都可以得到和整个光场的卷积结果。

2.思路

(1)仍然是一种空间换时间的思想。使用一张经过预计算得到的纹理,并在运行时对其进行采样和少量的计算,就节约了每帧对屏幕上的每个像素点实时计算漫反射信息的运算量。

(2)可以将其理解成一个表格,通过查表就能够得到卷积的结果。

5.Specular高光反射项

1.核心思想

数学推导比较复杂,在这里只介绍几个核心的想法。

(1)并不是一个准确的解法,因为求解过程进行了大量假设。

(2)该方法本质上是将三个方程乘法的积分,变成了三个独立的方程的积分的乘法 (Split Sum)

(3)最核心的想法是对于粗糙度的处理。利用了硬件Cubemap中的mipmap功能,将不同粗糙度的结果(环境贴图 environment map)存储在mipmap的不同层级中。

2.LUT(Lookup Table)

(1)粗糙度越高,对光照的敏感度就越低,数据就越低频。因此将数据存储在mipmap的最低级中。

(2)这里的mip和纹理的mipmap不同,这里不是在两个层级之间进行插值,而是每一层mip需要单独计算。

(3)当粗糙度从0到1变化时,就可以在mipmap中进行查找。称之为LUT。

2-2.补充~mipmap

(1)计算机三维图形渲染中,贴图渲染中有一个常用的技术被称为Mipmapping

(2)为了加快渲染速度和减少图像锯齿,贴图被处理成由一系列被预先计算和优化过的图片组成的文件,这样的贴图被称为 MIP map 或者 mipmap。

(3)这个技术在三维游戏中被非常广泛的使用。“MIP”来自于拉丁语 multum in parvo 的首字母,意思是“放置很多东西的小空间”。Mipmap 需要占用一定的内存空间。

(4)使用场景

1)IBL的高光反射项的粗糙度处理。

2)纹理采样 用到。

3)虚拟纹理 用到。

3.和Cook-Torrance模型处理BRDF方程的比较

(1)LUT有两个维度,一个是粗糙度,另一个是余弦项。

(2)这时方程中的Fresnel项变成了一个线性项。这样基本上能够模拟PBR Cook-Torrance方案在环境光照下的效果。

如下:着色 = 漫反射 + 反射项。

(3)Cook-Torrance在后面pbr材质会详细讲解。

6.IBL的效果

(1)IBL对于Specular项的求解,实际上是一个近似解。但可在环境光照中看到一些高光信息。

(2)请注意,这种高光不是很闪亮的高光,而是给人一种这个地方好像有点光亮,但又不完全光亮,而且它能模模糊糊的让我觉得那边有东西的感觉。下面的右图。

(3)将漫反射项和高光项合并到一起,就是一个完整的材质在环境光照下的效果。大家可以看下图:

(4)右图的画面会让眼睛更舒服,图中物体的层次结构很清晰。

这就是IBL的神奇之处,这也是十几年前所有3A大厂义无反顾地转向IBL的原因。

二.材质

1.PBR(Physical-Based Rendering)

(1)PBR的概念很多

比如基于物理的光照(PBR Lighting)、基于物理的相机(PBR Camera)、基于物理的材质(PBR Material)等。

(2)使用基于物理的材质系统,叫 PBR Material( Physical-Based Rendering Material

2.微平面理论Microfacet Theory

1.概念

也称为微面元理论,是用一个假设来解释光学现象,即光线会在一个表面发生无数次反射。

(1)如果表面的所有微表面的法线方向比较集中,表面看起来就会闪闪发光。

(2)如果法线都朝向一个方向,就会表现出类似于镜面的效果。

(3)而如果法线分散地比较开,表面看上去就会比较粗糙。

2.粗糙度Roughness

(1)物体表面的法线分布,我们用粗糙度 *(Roughness) *来表示

3.漫反射

有一些光线会进入物体中。

(1)对于金属来说,金属的电子可以捕获这些光子,这些光子就会被吸收。

(2)而非金属没有能力捕获光子,光子会在物体中发生若干次反弹,然后从一个随机的方向射出。

相当于一束光照射到物体表面,在物体中发生了几次折射后,又散射出去。这就是漫反射效果。

3.PBR材质包含两部分效果,继续对BRDF方程分析处理

3.1漫反射项

(1)用f Lambertf Lambert 表示,是对球面上的所有漫反射能量的积分

(2)也可以简单表示为c/πc/π ,C是进入物体的能量。

3.2反射项

引入“Cook-Torrance”模型,来求解BRDF方程

4.Cook-Torrance模型的DFG

Cook-Torrance模型中有三项比较重要,分别是DFG项,每一项分别代表一种光学现象;

1.D项~法线分布函数 (Normal Distribution Function)

(1)本质上描述了表面的法线分布地更加发散还是更加聚集。

(2)常用的是GGX分布模型,数学公式看起来很复杂,在Shader中实现起来并不复杂;

(3)上式中引入了一个α项,α项代表粗糙度。

(4)左下角的微平面分布函数

1)GGX的长尾效应

GGX(绿色)在高频处更突出,而在低频处会延伸的更长,不会像Phong模型或者其他模型那样快速衰减并趋近于零。这就是所谓的“长尾”效应,这一特性与真实世界中的很多表面的表现相符。

2)Phog模型高光问题

使用Phong模型,当对power参数进行调整时,会很容易得到一个十分生硬的高光边界,高光部分会显得很突兀。

而如果使用Cook-Torrance模型和GGX分布模型时,高光边缘的过渡就很柔和。

3)粗糙度(Roughness)

GGX引入了一个关键参数,粗糙度(Roughness),值越大,法线分布的随机性就越强;Roughness值越小,法线分布的随机性就越弱,物体就越接近于镜面效果。

2.G项~几何衰减项 **Geometric Attenuation Term)

1.概念

即微表面几何结构内部的 自遮挡

从光学上解释,每个表面在微观下都是凹凸不平的,当观察者从某个角度观察表面时,视线可能会被表面上的某个部分遮挡。因此当光照射到表面时,光也可能会被其他的部分遮挡。

2.计算方式

(1)Smith方程中的GGX项只计算了一个数值,即基于给定表面的法线分布所形成的粗糙度信息。然后用积分等方法算出G项的值;

(2)对于GGX材质来说,实际上只是计算了一遍对光线的遮挡比,再计算一遍对视线的遮挡比,就可以得到有多少光从入射表面在弹射到观察者眼中的过程中被遮挡。

3.D项和G项的关系

(1)比如一个光的100%的能量射向了表面,根据表面的D项~法线分布函数计算得出,大约有30%的光线被遮挡了,剩下来的能量是70%。

(2)当剩下来的光子往观察者眼中行进时,由于材质是各向同性的,这70%中的30%又被遮挡了

(3)最后剩下的能够到达人眼中的能量就是70%×70%,即49%。

(4)原理很简单,而且我们在计算法线分布方程时引入了α参数,这个参数又可以直接用在G项的计算上。所以我们只需要设置一个参数,即粗糙度(Roughness),就可以得到两项的结果。

3.F项目,Fresnel 菲涅尔

1.概念

(1)视线非常接近表面的切线方向时,表面的反射系数会急剧增加。

(2)例子,观察水面就会发现,离水面近的地方会看得更深,而离水面远的地方就会倒映出岸边的景象。

(3)计算

Fresnel项的计算也可以用微表面方程推导出来,大约是一个五次方的计算公式。图形学行业已经很多预置好的系数,自己微调就好;

4.Cook-Torrance反射方程总结

(1)只需要一个和粗糙度相关的参数α

(2)再加上一个Fresnel参数项,

就可以以物理的方式来表达一个材质。

前人的总结和沉淀,Cook-Torrance的 MERL BRDF数据库 www.merl.com/brdf/)

艺术家们在制作材质时,可以参考这些数据库来确定和调整不同材质的上述各项参数。

5.Cook-Torrance模型的问题

(1)艺术家们在调整系数时,经常会出现很多匪夷所思的效果,以及各种奇怪的Bug。

(2)直到Brent Burley引入了“Disney Principled BRDF”,即迪士尼信条。

5.迪士尼信条

1.背景

迪斯尼在做动画电影时,首先引入了PBR材质。随后提出了几个信条,将参数调整和开发流程变得更可控,和游戏引擎的设计理念高度相关。

2.内容

(1)第一条,每个参数必须要优先符合艺术家的直觉,即不能使用艺术家不懂的抽象物理概念,尽量让艺术家工作时做到“所见即所得”。

(2)第二条,参数数量应该尽可能少。十几年前,当时我们在做游戏的时候,材质参数有很多,经常在调整过程中会发生很大的问题,有时不知道在调整什么,调整之后是否有效。

(3)第三条,所有参数的取值范围最好在0到1之间。这一点明显优于Blinn-Phong模型,因为Blinn-Phong模型只是一个经验模型,其中的高光系数并没有实际的意义,只是开发过程中的手调参数,可以随便设置数值。

(4)第四条,在一些特殊情况下,参数取值也可以超过这个范围,但是必须可以产生看上去不错的结果。这样既保证了便利性,也保证了创作的弹性。

(5)第五条,所有参数组合产生的结果应该是尽可能健壮的、看上去正确的。即这些参数的组合不论怎么调整,都不会产生非常诡异的结果。

3.注意

上述五条看似简单,当大家从事实际引擎开发时,包括渲染,甚至物理和AI模块(怪物AI等)中,如果想暴露给设计师或者艺术家符合上述要求的参数,是非常难的。但是一定要有这个意识。

4.迪士尼材质 (Disney Principle Material Parameters)

(1)优点:十分符合迪士尼信条原则,直观明确。

(2)缺点:迪士尼PBR材质参数对于有些材质属性支持的不是特别好。

比如类似于透明涂层的“clearcoat”效果,以及类似于玉器材质的“sheen”效果。也在不断改进。

6.主流的PBR模型

PBR知识量非常多,介绍两款主流PBR模型

6-1.SG模型,“Specular Glossiness”模型

1.特点

这个模型比较巧妙,几乎没有什么参数,所有的属性全部用图来表达。

2.内容
(1)漫反射纹理

上图中间图片的第一张图片是漫反射纹理,有三个通道,分别表示RGB颜色分量。

(2)Specular高光纹理

中间图片是Specular高光纹理,控制Fresnel参数。要注意,Fresnel参数的RGB系数是不一样的。对于黄金、铜这种带颜色的金属来说,它们对于不同色彩、不同角度的反应是不一样的。

(3)Glossiness光泽度纹理

最后一张图是Glossiness光泽度纹理,控制着粗糙度和光滑度。

(4)SG模型是一个全模型,它非常完整,非常经典,而且符合迪斯尼信条,即每个参数都在0到1之间。通过纹理采样,就可以得到diffuse、specular、normal和glossiness参数。然后,就可以编写Shader代码。

3.优点

(1)只需要对图片进行操作,艺术家们就可以精准地进行像素级的控制,

(2)而且无论怎么调整参数,金属看起来确实像金属,非金属看起来确实像非金属 (没有Blinn-Phong模型的塑料感)

4.缺点

太灵活,特别是对于Specular纹理的RGB通道来说,一旦艺术家设置不好,很容易导致Fresnel项数值的膨胀,而上述代码中的F0项一旦出现问题,这个材质看上去就非常奇怪。

为了解决这个问题,提出了MR模型材质。

6-2.MR材质,“Metallic-Roughness”模型

1.原理~简单粗暴
(1)Base Color纹理

首先设置一个Base Color纹理,并且不允许更改。

(2)Roughness值

然后设置一个Roughness值,Roughness值表示粗糙度,

(3)Metallic值

还需要设置一个Metallic值,直接表示叫做金属度。

本质是控制Fresnel参数。

如果金属度非常低,就代表材质是非金属。金属度越低 (非金属值越高),Base Color进入到镜面反射项的比例 (即Fresnel项) 就越低。

但如果材质是金属,Fresnel项的比例就越高。

2.优点

(1)可以认为MR材质模型是对SG材质模型的封装。

(2)一个功能强大的通用函数(SG材质),如果使用不当会引发严重的后果,因此我们可以对这个通用函数再进行一次封装(MR材质),只开放几个控制参数,而且保证所有参数都是有意义的。

(3)MR材质模型中有一个Lerp(线性插值)操作,根据metallic的值来控制金属和非金属效果。对于艺术家来说,虽然这样做的灵活度下降了,但是不容易出问题。

(4)所以对于现在的游戏行业来说,越来越多的工作室在实践中会倾向于使用MR材质模型,而不是SG材质模型。

这就是迪士尼信条的伟大之处,因为在协调一个几百人的团队制作游戏时,这种可控性非常重要。

3.缺点

(1)在非金属和金属之间过渡的时候,它容易产生一个小的白边,这个白边可能不大容易发现,但如果仔细观察是能看得见的。

(2)不过目前为止,也没有发现更好的解决方案了。

4.例子~senseCube

场景模型的各种广告位材质都是MR材质。

GGX模型,三个参数~基础颜色、粗糙度、金属度。

三.阴影.级联阴影CSM(Cascade Shadow Map)

1.背景

世界地图越做越开阔,而对于阴影贴图来说,贴图的精度永远是不够的。

2.思路

(1)将阴影分成几层。

(2)通过相机视锥体的方向,在近处做一个很高密度的阴影贴图,一般距离只有十米左右。

(3)然后对于后续的距离,比如30米、100米、2公里的距离,分别生成不同精度的阴影。

3.优点

(1)近处看着足够清晰,而远处看着足够稀疏,也符合光学原理。

(2)对于远处的阴影来说,即使投影到相机中,相对来说也不会很大,这符合近大远小的原则。

(3)所以远处人眼采样率的下降和远处阴影贴图采样率的下降形成了完美的匹配。

(4)这么淳朴的一个想法在游戏行业中流行了十几年,直到最近一些新的想法得到了应用。

4.问题

(1)需要在不同的层级之间需要进行插值,否则可能会出现一条硬的边界。

(2)不做任何处理,当推动相机时,会发现有一个固定的地方,在这个地方的阴影会破掉。这是因为不同层级阴影的分辨率不同所造成的。

5.解决方案

(1)主要是在着色器代码中进行一些“Hack”。

(2)cocos3.7增了 CSM 层级阴影的过渡,混合不同层级的渲染效果,使两个 CSM 阴影层级间过渡更加平滑。

6.缺点

(1)空间换时间的方法,占用了很大的存储空间。

(2)阴影渲染是游戏引擎中最昂贵的部分。而且它不会真正绘制一些出彩的部分,比如材质和光效等,它只是确保你的光的可见性是正确的。

(3)假设一帧的绘制时间预算是30毫秒,阴影部分很多时候会消耗4-5毫秒。如果场景比较复杂,阴影很少能够做到2毫秒以下的时间消耗。

(4)所以阴影渲染是非常昂贵的,尤其是Cascade Shadow。比如上面的例子,需要绘制四次。

(5)然后对场景做四次裁剪。因为在绘制最近处的阴影时,我们不希望它处理远处的很多物体,所以需要重新计算可见性,然后再计算阴影。所以在实现过程中的细节很多。

7.软阴影

7.1 PCF(Percentage Closer Filter)

PCF方法非常科学,使用了滤波的方法来处理阴影的软硬。

7.2 PCSS(Percentage Closer Soft Shadow)

(1)基于PCF,在实战中又出现了PCSS方法。

(2)PCSS方法更精妙,考虑了物体离光源的远近,然后进行一次采样,就能够渲染出阴影。

(3)PCSS在很多引擎中都属于标配,很多引擎中的阴影效果都会带一点软阴影。软阴影能够极大地缓解阴影的走样问题。

7.3VSSM 方差软阴影(Variance Soft Shadow Map)

VSSM的想法非常简单,使用数学方法计算出深度的均值和方差,然后利用切比雪夫不等式进行估算,得到阴影的软硬比例。

7.4.Threejs的阴影

(1)默认是普通的阴影贴图。

(2)级联阴影,需要扩展实现,example中的csm库

目录example/jsm/csm

csm的demo地址:threejs.org/examples/?q…

(3)软阴影,WebGLRenderer.shadowMap.type添加了软阴影效果

threejs.org/docs/?q=ren…

THREE.BasicShadowMap 没有过滤,速度最快,但质量最低,可能会有硬阴影
THREE.PCFShadowMap 默认的软阴影
THREE.PCFSoftShadowMap 上面的PCSS软阴影
THREE.VSMShadowMap 上面的VSSM 的软阴影

(4)senseCube项目,使用普通阴影贴图,软阴影用THREE.PCFSoftShadowMap。

四.总结,5-10年前3A游戏效果

1.光照

(1)一般使用光照贴图和光照探针来解决。很多引擎这两个方法都会提供,因为这两个方法分别解决了不同的问题。

(2)对于背光面即环境光照的表达,基本上以IBL方法为主。

2.材质

(1)主要就是PBR方法。

(2)PBR只需要掌握两个模型,一个是SG模型,一个是MR模型。

3.阴影

(1)使用Cascade Shadow方法。

(2)再使用PCSS或者VSSM,给阴影加上软阴影效果。