找回密码
 立即注册
查看: 332|回复: 0

GAMES104-现代游戏引擎:04 游戏引擎中的渲染实践

[复制链接]
发表于 2022-4-18 21:30 | 显示全部楼层 |阅读模式
一、渲染概述

1.1 游戏渲染 & 计算机图形学

渲染是游戏引擎的基础,而渲染的理论基础是计算机图形学。但计算机图形学与游戏渲染存在一些区别:

  • 计算机图形学面对的问题是明确单一的。
  • 计算机图形学更多关注算法的正确性。
  • 计算机图形学没有严格的性能需求。
游戏渲染面对的挑战:

  • 游戏融合了大量渲染效果,复杂度很高
  • 游戏需要面对硬件处理问题
  • 游戏在不同的场景下需要有稳定的帧率
  • 游戏CPU端大量的计算需要分配给GamePlay
1.2 渲染课程大纲



1.3 不涉及的内容



二、渲染对象

2.1 GPU流水线




GAMES101-GPU绘制流程

现代游戏渲染是通过CPU+GPU合作处理模式。CPU准备好数据渲染数据后将其提交到GPU,GPU设置好渲染状态后开始处理CPU所提交的数据。
GPU拿到顶点数据集后,对这些顶点进行空间坐标转换(MVP)投射到屏幕中,并组装成三角面。现代的显示器通常是栅格化的,因此需要将三角面映射到屏幕中的像素,最终对这些像素进行着色处理。
2.2 GPU计算类型




投影 & 光栅化



着色计算类型

投影与光栅化涉及矩阵运算,Shading涉及常量访问、数学计算以及纹理采样。
2.3 纹理采样

为了避免纹理采样时的锯齿问题,通常会对纹理进行差值处理。当纹理小于采样区域时,可通过双线性插值的方式进行处理;当纹理区域大于采样区域时,可通过Mipmap、各向异性过滤、EWA过滤等方式处理。



双线性插值



Mipmap三线性插值(8次采样、7次插值)

简单纹理采样也需要消耗大量的计算,因此我们就有必要解GPU的工作方式,让游戏更顺畅得运行。
三、硬件架构

3.1 SIMD & SIMT

现在CPU中已经广泛使用了SIMD(Single Instruction Multiple Threads)单指令多数据的处理方式,通常为矢量数据。例如一个32bit位宽的4维向量vec4,一条指令最快就在一个cycle执行完。那SIMT,最快要用4个cycles来完成。
而GPU在多核中使用SIMT指令来实现类似SIMD功能,并且支持分支跳转。在SIMT的架构上,会把vec4分解开,然后一个cycle处理完一个数据。所以最快需要4个cycle。


因此我们在设计Shading代码时,要尽可能使用相同代码处理,让每个核访问自己的数据。
3.2 现代GPU架构(Fermi)

Fermi是第一个完整的GPU计算架构。GPU中分为很多组内核,一组内核称为GPC(Graphics Progressing Cluster)。GPC中存在很多小的内核,这些内核是指令的直接执行者。Texture Unit进行纹理采样,CUDA Core用于多核之间的数据交换



Fermi架构

3.3 CPU Data To GPU

CPU和GPU可以看做是独立的机器,两个机器之间的数据传递成本很高。现代CPU的架构是冯诺依曼架构:数据与计算分离,这种架构的问题就是计算式需要准备好数据。
因此在设计代码时,尽量保证数据的单向传输(CPU -> GPU),避免计算同步问题。
CPU查找数据时,首先从Cache中查找,再从内存中查找,而Cache访问速度是内存访问的100倍。因此我们在处理数据时,尽可能使用连续数据。
主机GPU架构


手机GPU架构


四、Renderable

4.1 Renderable Data

游戏中我们能够看到的对象都有其逻辑对象,但逻辑对象是如何绘制出来的呢?通常游戏引擎会提供Renderable组件,用以将单位数据绘制为图像。例如Unity中的Renderer、SkinMeshRenderer组件。
Renderable组件中的数据是如何组织的呢?以一个士兵为例,首先很多网格组成对象的框架;网格的质地各不相同,这就需要材质进行处理;材质中有不同的花纹,需要提供图片数据……


Mesh原始数据
Mesh提供了单位的网格数据,网格是由一个个顶点数据组成的三角面集合。那么这里就涉及到两个问题:顶点数据是怎么样的?这些顶点数据如何组成三角面?


顶点数据涉及坐标、颜色、法线、切线……(不一定都有)有了顶点数据之后,最暴力的表示方法就是,每个三角面都有自生的原始数据,这样的话N个三角面就有N*3个顶点数据。但我们仔细观察就会发现,这样的数据中有很多是重复的的(相邻三角面两个顶点数据相同)
在OpenGL中定义Mesh时就有VBO与VAO的概念,顶点数据为原始数据,通过index索引来组成三角面。
除了通过index引用的方式表示,还有Triangle Strip的表示方式:顶点列表中,连续三个顶点表示一个三角面,这样就省去了index数据,并且对缓存友好。
Material


Texture


Shader:GPU代码 & 文本资源


4.2 GPU绘制流程




空间变换



根据数据与Shader渲染

上述的为一般渲染处理流程,但对于一个复杂对象来说,部件的材质各不相同。GPU作为一个状态机,只会保留最后Material所提交的状态进行渲染,那么就不能得到正确的效果。因此就需要引入SubMesh的概念:



Submesh结构

对于存在多个材质的对象,我们会对网格进行切分(通过offset、count确定index)为submesh,对应各自的材质,一个完整的复杂对象渲染就处理完成了。
但如果我们需要绘制大量这样的复杂单位,如果每个单位都独立存储一份完整的渲染数据,这样的开销太过巨大。这些单位的材质、Mesh、纹理都有相同部分,因此较好的数据组织方式是对渲染资源数据创建资源池。当我们在游戏中创建不同的士兵,可以看做资源在场景中的实例化。


渲染的整体分为三个步骤:(1)CPU提交渲染数据;(2)GPU设置渲染状态;(3)GPU渲染
对于相同材质的对象来说,每次都处理三个流程是极为耗时的,我们可以为材质相同的对象跳过步骤(2)。这也是现代图形渲染API的设计思路:根据材质进行submesh渲染。Unity中的SRP Batcher类似于这一概念。


除了简化渲染状态设置,我们还可以对数据的提交进行优化:对于完全相同的物体,只是在场景中的位置不同。就可以将这一类对象的渲染数据一起提交到GPU,减少数据提交次数。Unity中的GPU Instance类似于这一概念


五、Culling

在知道了如何绘制场景对象后,另一个问题就来了:我们要绘制哪些物体?最暴力的方法是所有对象都绘制一遍,但显然在大世界的游戏中是不行的。
5.1 Bound

通常我们会根据Camera的可视范围(视锥体、长方体)作为单位是否可见的判断依据,但单位的形状千奇百怪,如何能够将这些Mesh与可视范围进行检测呢?这就需要对物体范围进行简化:包围盒(Bound),规则物体的相交是相对便于计算的。


包围盒的有很多类型:Sphere、AABB、OBB……


5.2 Sence Manage

Bound简化了单个物体的可视判断计算,但如果场景中对象数量十分庞大(10W),所有对象都进行Culling也是难以接受的。因此需要对场景中的对象进行划分,预先剔除摄像机覆盖范围外的对象。



BVH适用于开阔动态场景



通过门连接的室内场景PVS处理更加高效

5.3 GPU Culling & Old Z

GPU的批处理速度远远快于CPU,若Culling仍然十分耗时,就可以考虑将这部分并行化计算放到GPU中。
在绘制对象时,靠前的物体会挡住靠后的物体,进行这一判断就需要Early-Z(z-Buffer)。通常在进行真正绘制之前,Camera会对空间对象生成一张深度图(z-Buffer)。在之后绘制对象时,就可以判断像素的深度是否符合要求,以此来判断是否进行绘制。
六、其它

6.1 纹理压缩

我们日常使用的图片压缩格式(如PNG、JPEG等),有很好的压缩或显示效果,但通常无法满足游戏引擎的需求:快速随机访问像素。
在游戏引擎中通常采用block思想:将纹理划分为多个小块,然后进行压缩。以DXTC格式举例,对于每个划分的小块,取得其中最亮和最暗的像素点,其余部分通过差值系数的记录数据。


6.2 建模工具

多边形建模


雕刻


实体扫描


程序化建模





建模方式对比

6.3  Cluster-Based Mesh Pipline

游戏和影视有很大的重合部分,但由于游戏的实时渲染以及硬件存储要求,通常一个模型的面片数不会超过1W,而影视级的模型通常是千万级的。想要在游戏中实现影视级效果,那就得上点手段了。
2015年《刺客信条:大革命》提出了Mesh Cluster Rendering概念。其核心思想是将模型分成多个Cluster(32\64面片),根据这些Cluster与摄像机的远近来展示不同的细节。这要处理的好处在于:

  • 现在GPU可以根据实时数据,动态生成几何细节(曲面细分Tessellation)
  • 以相同的Cluster结构来并行处理时,能够有效利用GPU
  • 可以对模型进行Cluster剔除





Mesh Shader处理流程



Cluster裁剪

总结


  • 游戏引擎设计深度依赖于硬件架构
  • 游戏引擎渲染的核心问题是如何组织Mesh、Material、Texture渲染数据
  • 游戏引擎渲染在绘制对象时,要尽可能减少处理内容
  • 现代GPU的处理效率越来越高,可以将CPU中并行计算转移到GPU中

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Unity开发者联盟 ( 粤ICP备20003399号 )

GMT+8, 2025-5-6 12:48 , Processed in 0.138314 second(s), 26 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表