0%

【游戏引擎】(二)游戏引擎中的渲染系统

游戏引擎中的渲染系统和我们之前学习的实时渲染或离线渲染系统不完全相同,游戏引擎中的渲染系统除了渲染外还需要考虑更多的事情。因为渲染系统只是游戏中的一部分,不可能将设备全部的资源投入到渲染中,因此大量游戏对象的绘制资源如何组织,如何管理,如何调度是游戏引擎的渲染系统需要额外考虑的事情。此外,游戏中的渲染对实时性要求更高,因此必须充分利用有限的资源来达到最好的效果,所以需要对渲染加速算法和 GPU 的架构有一定的了解。这一节我们对游戏引擎中的渲染系统所涉及的方方面面进行大致的了解。

1 GPU 架构

GPU 是渲染系统使用的核心工具,要想使游戏引擎充分利用资源,就要对 GPU 的架构有所了解。关于现代 GPU 架构,这篇文章写的比较细致:现代渲染引擎开发-GPU架构,这里只总结重点:

  • SIMD是单指令多数据,一条指令处理多个数据,如下图:

image-20220526155458175

  • SIMT是单指令多线程,N 卡使用这种方式,即单条指令在多个核上分多个线程执行

image-20220526155551595

  • GPU 中最重要的计算单元是 CU,N 卡中为 CUDA Core,还有专门支持光追的 RT Core 和支持 AI 运算的 Tensor Core 等,多个 CU 组成一个 GPC,也叫做 Shader Engine

image-20220526160001900

  • GPU 对性能的瓶颈包括:内存瓶颈、ALU(整形运算单元)瓶颈、TMU(纹理映射单元)瓶颈、BW(带宽)瓶颈等

2 渲染资源管理

游戏中的所有对象被称为 GameObject(GO),每一个 GO 包含很多组件,比如模型、语音、动画等等,GO 之间还可以通过事件系统进行交流,并根据其他 GO 发来的消息做出响应。其中,与渲染相关的组件就称为 Renderable,Renderable 包含渲染这个 GO 所需的所有数据,包括顶点、法线、纹理坐标、材质、贴图等等。游戏引擎需要将这些数据高效地组织起来。

顶点数据的组织我们在 OpenGL 中已经了解,分为顶点数据和顶点索引,顶点索引就描述了所有图元由哪些顶点组成,因为很多图元之间会共享顶点,这样就不需要为每个图元单独存储顶点,从而避免资源浪费。

一个 GO 最重要的就是要有一个模型,模型由网格 Mesh 组成,因为模型的不同部位可能需要不同的材质,所以一个模型又分为了多个子 Mesh,称为 SubMesh,每个 SubMesh 有它对应的材质(Material),材质包含纹理(Texture)和 Shader 等,如下图:

image-20220526161157448

在实际的游戏中,许多游戏对象的 Renderable 可能是重复的,比如许多步兵 NPC,渲染它们需要的数据是完全一样的,如果为每个 GO 都存储一遍这些数据那将会是极大的浪费,因此游戏引擎将所有这些资源放入了资源池中,不同的 GO 只需要存储资源池中资源的索引即可,比如一个模型的 Mesh 对应 Mesh 池中的哪些图元,使用 Shader 池中的哪些 Shader 去渲染,这样就将资源紧凑的管理起来了:

image-20220526161435933

这种管理方式也是游戏引擎中很常见的一种管理方式,用来应对资源复用的问题,不只是在渲染系统中,其他系统中也广泛使用了这种管理方式。因此每一个 GO 只是这些资源的组合,是实例化的资源。

image-20220526161628614

此外,因为不同的 GO 会有不同的材质,即使是一个 GO 也会在不同部位使用不同的材质,如果不做任何优化的进行渲染,会有大量的材质更新操作,即卸载掉这个材质的纹理和 Shader,并加载 另一个材质的纹理和 Shader,这样也会造成性能的下降,因此一般的做法是将 SubMesh 按照材质排序,将所有材质相同的 SubMesh 放在一起,这样只需要加载一次材质就可以渲染所有使用该材质的 SubMesh:

image-20220526162146227

---- 本文结束 知识又增加了亿点点!----

文章版权声明 1、博客名称:LycTechStack
2、博客网址:https://lz328.github.io/LycTechStack.github.io/
3、本博客的文章部分内容可能来源于网络,仅供大家学习与参考,如有侵权,请联系博主进行删除处理。
4、本博客所有文章版权归博主所有,如需转载请标明出处。