游戏渲染中光和材质的数学魔法
June 25, 2023About 15 min
游戏渲染中光和材质的数学魔法
游戏引擎的渲染-Lighting Materials and Shaders

- 渲染简单来看就是让光照生效

- 概述渲染结果的方程式

- 我们把渲染看成从Observer观察物体表面上的任意一个点X, X可以是二维的或者三维的。
- 首先约定Observer的观察角度为Wo(o表示Omega, Ω 欧米茄).
- 当观察点X存在自发光, Observer会在Wo的角度上接收到来自于X发射的光线,这个对应方程式的前段。
- 当观察点X被其他光源照射时,把从球面上所有可能的入射角射出的光对X产生的影响做一个积分,这个对应方程式的后段.
- 入射光的强度影响由入射角度θ决定
- 由一个BRDF的双向反射方程描述最后的结果

- 现实中的光照模型是非常复杂的,比如上图的光会产生多次变换叠加影响
渲染的三大挑战

- 光的可见性(阴影 shadow)计算的开销非常大
- 光源本身具有一定的复杂度,不同的光源带来的计算复杂度也不同

Info
Radiance: 辐射度(辐射能量),往外反射出的能量。
Irradiance: incoming Radiance,入射能量。
bounce: 这里是指光的弹射
- 获取球面空间上Irradiance的分布—获取光源入射能量 是具有挑战性的.

- 球面积分公式非常复杂,要快速算出光和材质之间的卷积结果很麻烦.
- 总结一下就是如何完成 shadering。

- 光线多次bouncing后会对一个点产生叠加影响
- 场景中实际存在无穷多的光源
- 在做光照渲染评估时,经常会用hack算法的结果去检查相对于真实渲染结果的逼近度-→ 右边小图

- 光的传播具有无限变化,但是计算的算力是有限的
简单的传统光照模型-Starting from simple

- 为了简化计算,首先只保留一个主光源(dominant light)
- 球面上其他光源用ambient light去表示,可以简单认为把这些光源的平均值视作环境光
- 需要注意是 早期的硬件就完全支持了所有光的效果

- 如图所示,假如物体表面非常光滑,观察到的结果是物体可以对环境进行反射。
- Hack:
- 使用环境贴图—用6个面的cube保存
- 根据Observer的观察角度和物体的表面法线在Cube里找到对应贴图的点。
- 近似描述了环境中高频的内容--specular(镜面)

- 这个算法的特点就是通过特例化去求解方程
Blinn-Phong 光照模型

- 通过漫反射 + 反射 + 高光的方式去解释光照结果
- 特点是利用光可叠加的原理

- 问题1:
- 叠加光线存在能量溢出(不能保守),离线渲染(比如光追)时会进一步放大这个误差。
- energy conservative→建议翻译成能量保守,因为入射光反射出去的强度只会小于等于原始强度
- 问题2:
- 怎么渲染都像塑料,很难渲染一些真实世界的材质.
Shadow 阴影

- 解决的是渲染中Observer所看到的场景中每个点到光是否可见

- 从光的视角渲染一张你的场景,获取可见深度,用来标识到光的距离。
相机渲染的时候,每个点通过反向投影,投影到光源视角的projection,可以得到一个距离。
如果这个距离大于最近的遮挡物距离的话,说明在Shadow中,反之亦然。 - games101 有更详细的描述

- 问题1:
- 从光的视角渲染和相机视角渲染的采样率不一样,前者会更低。
这样会导致出现jagged edges(边缘锯齿), Aliasing(混叠),自遮挡的问题。
- 从光的视角渲染和相机视角渲染的采样率不一样,前者会更低。
- 问题2:
- 光源靠近地平线时, 光源和场景中物体角度很低,导致阴影变得很长很扭曲无法准确反应场景中对象的形状。


- 上面提到方案虽然还有缺陷但是已经能做出比较好的渲染效果。
- 从59改的变迁来看,有些方案虽然过时但比较贴合一些低端的机器。
三A游戏的渲染质量 First Wave of AAA Quality
Pre-computed Global IIIumination
简单来讲直接光照和间接光照都存在的情况被称为全局光照

- 通过添加间接光的处理,全局光照能增加真实感。

- 全局光照的结果实际是在球内空间的采样,数据量非常大
- 通过蒙托卡罗积分去计算开销也非常大

- 傅里叶变换可以把一个无穷的信号转换成不同频率信号(正弦余弦波)的累加
- 右边的图形变化是增加新的频率信号后,与原信号的比较

- 照片通过傅里叶变换从空间域保存到频域
- 时域图:
- 是一张波形图,展示了波的周期性变化
- 时域的x轴是时间,y轴是信号值。
- 频域图:
- 在频域中,x轴通常是频率,而y轴可以代表多种不同的信息。 比如每5秒跳2次, 5代表X轴的频率,2次代表Y轴上的强度、
一种常见的方式是使用幅度谱,y轴代表信号在对应频率上的幅度。
另一种方式是使用功率谱,y轴代表信号在对应频率上的功率。
- 在频域中,x轴通常是频率,而y轴可以代表多种不同的信息。 比如每5秒跳2次, 5代表X轴的频率,2次代表Y轴上的强度、
- 将纹理转换为灰度图像:
纹理通常是彩色图像,而频域转换需要处理的是灰度图像。 - 对灰度图像进行二维傅里叶变换(2D FFT):二维傅里叶变换将灰度图像从时域转换为频域,得到灰度图像在不同频率上的分量。
具体而言,傅里叶变换会将图像分解为一系列的正弦和余弦函数,每个函数的频率和振幅都不同。 - 对傅里叶变换后的结果进行滤波:滤波是为了去除一些不需要的频率分量或弱化一些频率分量。
比如,在纹理合成中,我们可能想要弱化高频分量,以便生成更加自然的纹理。 - 对滤波后的结果进行反变换:反变换将频域图像转换回时域图像,得到一张新的纹理图像。
- https://www.zhihu.com/question/279808864



- 通过球面调和函数能近似表达球面光照信号
- 最常用的就是一阶多项式


- 使用Irradiance Probe来保存某个区域附近的入射能量信息,数据信息很大。
- 右图是通过球面调和函数压缩这个数据的样例

- 通过12个参数就能表明球面上的颜色分布

- Lightmap把整个场景的光照烘培到一张图上

- Atlas 是将场景中的物件进行几何简化后生成



- 前面两张图展示了加入直接光源(静态光)后的效果,最后的图展示了加入材质后的最终效果
- 这也是通过lightmap去补充全局光照效果的样例

- lightmap算法可以参考的思路是空间换时间,以及把整个游戏场景参数化到一个二维Texture上去。

- 空间上分布无数的光照探针(light Probe), 对于每个Probe都采样整个光场.
- 通过物体在空间中的位置去插值附近的Probe算出它的光照
- 一个把空间体素化的算法

- 自动生成探针的方式参考
- 在实际生产中这样的工具能节省大量的手动开销时间。

- 反射探针的目的是让移动物体在环境中的反射产生变化。
- 它的特点是比光照探针采样精度高,密度低。

- 需要注意的是如果要动态更新探针,需要利用GPU开销低的时间段
基于物理的材质 Physical-based Material

- 微平面理论: 根据平面上不同的法线分布能产生不同的效果

- BRDF光照模型,最主要的是DFG参数

- DFG中的D是指法线分布方程
- 这里提到了用买耳机的理论去看待一个算法模型
- 高音要脆低音要广(对应高频和低频) → GGX模型

- DFG中的 G 是 微表面衰减,在对应的角度有多少光被挡住。
- 计算光的阻挡性和视线的阻挡性确认有多少光从入射角度过来被挡住

- DFG中的 F 是指 菲涅尔参数。
- 菲涅尔现象是当Observer视线非常靠近表面的切线方向时,表面的反射系数会急剧地增加会产生倒影的效果。

- 通过物理材质测量仪器生成的材质组


- 左边是Disney提出的BRDF的原则, 右边是材质模板。
- BRDF的原则要点:
- 物理材质的每个参数需要容易明白(符合artist的直觉)
- 要尽量使用较少的参数
- 参数要尽量在0~1之间,需要一些特殊效果时可以超出
- 所有参数的组合不会出现诡异的结果
PBR主流材质

- PBR Specular Glossiness(SG模型)
- 几乎不用设置参数, 全用图来表达,可以精准进行像素级控制。

- SG模型的shader样例
- 实现的时候要注意归一化和对Π的处理

- PBR Metallic Roughness(MR模型)
- 在 SG模型基础上进行封装,提供Metallic参数,方便区分金属

- MR转SG模型
- MR模型通过Metallic值去插值计算金属效果

- MR模型缺陷是从金属到非金属过渡会有个白边
基于图像的光照 Image-Based Lighting(IBL)

- 核心想法:如果能够对真实环境光照做一些提前预处理,可以快速把整个环境的光照对材质的卷积运算出来。






- 基于IBL算法的分析
- 六张图的阅读顺序是从左到右,从上到下

- IBL的使用样例
- 严格来讲IBL是一个光照的方法
经典阴影方案 classic shadow solution

- Cascade Shadow对阴影进行分级处理
- 在距离人眼比较近的位置,使用高精度纹理采样,远离人眼的阴影使用低精度纹理采样。
- CSM将视锥由近到远分割成若干个子视锥,之所以要分级是为了减少内存开销。

- 原理分析

- 存在缺陷,需要在不同层级之间做插值去解决边界问题

Info
shadow运算的开销很大,一般都在4MS以上

- 软阴影的效果


- 实现思想是通过距离光源的远近去计算


- 这三种解决方案整合到一起可以实现3A游戏5~10年的效果
前沿技术 Moving Wave of High Quality
硬件性能的提升让算法变化很快

- GPU实时光追----样例是反射变化

- 实时全局光照----lumen

- 高精度毛发渲染、皮肤渲染

- 虚幻5提出的虚拟阴影映射的方案,用于解决阴影计算开销大的问题
着色器管理 Shader Management

- 游戏中会存在海量的shader

- 一个场景中会应用大量不同的shader

- artist会使用的shader Graph生成各种效果

- 一个完整的shader可能包含不同的变化,通过宏定义去创建不同分支
但是GPU对分支的处理非常慢,因为不同分支执行效率不同,不能在同时结束,这样对GPU的并发使用效果不好。
-->最后分支会拆分成庞大的不同shader, 如下图:


- 写shader的时候需要考虑方便做跨平台编译
Warning
本篇内容主要是对渲染技术的一个概要,如果需要去做实现建议继续学习games101和games202.