02 - 光照、材质和着色器

本文继续介绍了一些游戏渲染相关的基础知识,包括渲染方程,全局光照,PBR,着色器等内容。

PS:这篇笔记结构看起来还是有点乱,待我学完GAMES202相关内容后进一步修改。

光照部分

渲染方程

1986年Kajiya提出了渲染方程,图形学领域的命运齿轮就此转动。

如图,渲染方程主要有以下几部分:

  • 自发光项Le:该点自己发出的光。
  • 反射项(积分部分):半球区域周围的光在该点反射的光。其中fr是BRDF。

光的种类

渲染方程看起来简单,但动手做起来却很难,因为现实世界里有着各种各样的光。如上图,有直接光、环境光、反射光、折射光和Caustics现象等。

渲染方程带来的挑战

利用好渲染方程去渲染那么多种类的光,给人们带来的许多挑战。

光的可见性

典型的例子之一就是阴影

阴影给我们一种层次感,没有它就无法正确辨别物体间的空间关系。

除此之外,还有 光源 带来的问题:

光源的复杂性也是挑战之一,如点光源、面光源等。

计算复杂性

渲染方程中有个球面积分项,很难算,如何快速准确的算出光线与材质的积分结果也是一个问题。

所有物体都是光源

光有直接光和间接光,间接光是由直接光通过弹射产生的,典例为康纳尔盒。如何高效实现全局光照(Global Illumination,GI)这又给我们的算法/计算带来了挑战。

基础光照

接下来说说基础光照是怎么组成的。别想那么多复杂的东西,先从最简单的开始。

环境光

首先引入 环境光(ambient)这一概念,它综合了周边环境给着色点贡献的光,就是一个常量。

然后为了让物体表面看起来更真实(可以反射周边的环境),引入 环境贴图(Environment Map)这一概念。

这些东西其实是符合渲染方程的,我们简单地模拟了一个半球的环境:

Blinn-Phong光照模型

接下来引入Blinn-Phong模型,它除了有环境光外,又有了漫反射项(Diffuse)高光项(Specular),使物体看起来更好。该模型十分经典,上手简单,用于教学和早期游戏渲染。

但该模型有一些问题:

  • 能量不守恒,因为这个模型不是基于物理的(例如环境光居然是个常数,没有物理定义)。
  • 不真实,渲染的物体都有股塑料感。

阴影

然后引入阴影,阴影就是物体挡住光线,被人看见的部分。人们在这个领域上实现了很多算法,如shadow volume等。

但在游戏引擎行业,只用Shadow map

在GAMES101中有提到过,详见我之前的文章。但Shadow Map还是有一些问题的,例如光源视角和相机视角的采样率不一样,会产生假象(artifact)。

综上,这就是渲染引擎的基础光照解决方案,基本解决了上边提出的三个挑战。

基于预计算的全局光照

对于3A游戏行业的工程师来说,他们对基础光照模型还是不满意,要精益求精。这里说说5~10年前3A游戏的流行技术:基于预计算的全局光照(Pre-computed Global Illumination)

这是典型的空间换时间思路,认为场景中有90%的物体是静止的,这样就可以提前进行计算,加速他们的渲染。

全局光照

全局光照,就是直接光加上间接光:

全局光照使得画面更真实,玩家体验更好。

间接光

类比上边的环境贴图,我们也能将间接光做成一个材质球:

信息压缩

间接光数据量庞大,得先把这些数据给压缩一下,傅里叶变换就是一个很好的法儿。为了让计算更加方便,这里引入球谐函数(Spherical Harmonics)

球谐函数可以用多项式的形式近似(展开几阶,通常是1)表示出某一信号,利于傅里叶变换的卷积操作。

接下来,利用球谐函数对Irradiance进行压缩,可以发现它虽然很糊,但基本描述了光是从哪儿来的,且数据是连续的:

由于要存储4个RGB值,需要12个SH(球谐函数)参数,且它们的权重也不一样:

全局光照的表示

Light Map

用空间换时间,把整个场景的光照烘培到一张2D图上,被烘培的图被称作atlas

Lightmap的主要环节如下:

几何简化

省略过多模型细节,将它们进行分块简化操作,以便更好地烘培。

Lighting

然后开始正式烘培,消耗很长时间,得到成果:

上材质

最后将模型的材质上上去,得到的成果如下:

使用Lightmap的优缺点如下:

  • 优点:
    • 运行时高效率
    • 对全局光照细节处理到位,艺术家很喜欢
  • 缺点:
    • 预计算时间(烘培时间)很长
    • 只能解决静态场景/静态光

Light Probe

由于每个采样点是一个半球,那就索性在空间上铺满一堆半球作为探针(Probe),对它们进行采样。当有物体接近它们时,再做出改变。大多数Probe只是用于全局光照,因此也被称为Light Probe。

Probe的生成

早期工程中,Light Probe是人为摆放的,但效率低,容易出错。现代工程中,人们大多使用程序自动化生成的方法。

Reflection Probe

Probe大多数是搞漫反射的,因此采用信息压缩方式,对低频不影响。而有时候我们需要Probe做一些高频反射,且精度高,这就得特制一种Reflection Probe了:

使用Probe的优缺点如下:

  • 优点:
    • 运行时效率高
    • 静态物体和动态物体都能被处理,可以在运行时更新
    • 可以处理漫反射Diffuse(用Light Probe)和高光Specular(用Reflection Probe)
  • 缺点:
    • 计算量大
    • 对全局光照的细节处理不到位

因此,将Light Map和Light Probe这两种技术结合起来,便能很好的表示预计算的全局光照了。

经典阴影方法

Cascade shadow

在经典3A游戏中,阴影的主流解法就是使用Cascade Shadow。游戏世界越做越开阔,远处的山有影子,近处的枪也有影子,它们的精度各不相同。而如果只用shadow map的话解决不了这个问题,于是分级的Cascade Shadow便被提出来了。

Cascade Shadow以视锥体为标准,做出分级的shadow map(从近到远精度越来越低)。

插值问题

这个方法还存在一个插值问题,就是由于分级导致阴影精度骤降的问题。

通过在Shader里偷鸡可以解决。

优缺点

软阴影绘制

Percentage Closer Filter

大名鼎鼎的PCF算法:

Percentage Closer Soft Shadow

PCSS,基于PCF算法,人们更常用这个,是游戏引擎里的标配。

Variance Soft Shadow Map

VSSM算法,看下图知道比PCSS算法效率高,人们也喜欢用这个。


材质部分

微表面理论与BRDF

微表面理论描述了法线在微表面上的分布情况,详见GAMES101.

渲染方程中的fr就是BRDF,Fr有两项:

  • Lambert漫反射模型
  • CookTorrance反射模型

CookTorrance反射模型

CookTorrance反射模型里有著名的三项:

  1. D项:

    即法线分布方程,描述法线分布的程度(聚集/发散)或随机度。现在大家都用GGX着色模型(绿色部分),它高频部分很尖,低频部分很缓,很现实。

  2. G项:

    描述了微表面凹凸不平表面的内遮挡程度,有多少光在反射时被微表面挡住反射不出来。

  3. F项:

    菲涅尔项,例如产生水中倒影的效果。

物理测量的BRDF

与其对BRDF进行调参,仿真某物体的表面,不如直接进行物理测量,这样得到的效果更真实:

迪士尼BRDF信条

业界大牛迪士尼提出了有关BRDF的信条:

  1. 每一个参数都得符合艺术家的直觉,不要太抽象了
  2. 参数要尽可能少
  3. 参数值的范围最好是0~1,特殊情况(如调多了才能出现的效果)可以被豁免
  4. 所有参数组合都应是稳健和合理的

这些思想同样适用于游戏引擎的制作,游戏引擎不是对自然的模拟器,而是面向设计师的应用工具

PBR模型

Specular Glossiness模型

简称SG模型,使用RGB参数,很直观:

该模型有一点小问题,就是它太灵活了,例如Specular的RGB通道,调的不好会导致其他项炸掉。

Metallic Roughness模型

简称MR模型,仅使用一个RGB参数base_color,剩下的两个参数为粗糙值和金属度。金属度的高低会影响菲涅尔项。

MR虽然符合直觉,但不好区分金属和非金属材质。

两者的对比如下:

此外,它俩还能进行转换操作。

Image-Based Lighting(IBL)

IBL提供了一张Cube的展开图,记录了整个环境光照对材质的运算结果,有细节感和凹凸感。

Diffuse部分

Specular部分

分成两个小部分,发光项和BRDF项:

对于发光项,根据粗糙度\(\alpha\)不同,将预计算好的结果存到一张map中:

对于BRDF项,根据粗糙度和角度不同,将预计算结果存到LUT图中:

将它们综合起来,就能得到IBL渲染效果:


3A游戏的渲染

掌握好这些技术,就能写一个5~10年前3A游戏的渲染引擎了,能写好的话出来找工作就不成问题了(我要努力啊qwq)。


Shader管理

Shader管理对于大厂来说是个问题,主要有以下因素:

  • 艺术家创建了一堆shader,量很大
  • 在不同条件下的shader内容也不同,碎片shader比较多

Uber Shader

因此可以将这些shader写到一起,用宏定义分开。这叫做Uber Shader

跨平台编译

Shader在不同平台有着不同版本,编译起来比较麻烦。


前沿技术

显卡和图形API的快速发展使得渲染行业涌出了许多新兴技术:

实时光线追踪

实时全局光照

更复杂的材质模型

Virtual Shadow Map

参考资料

  • GAMES104 (boomingtech.com)