[Games104笔记]3/21 基础架构1 『引擎架构分层,整体Pipeline』

Posted 泥烟

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[Games104笔记]3/21 基础架构1 『引擎架构分层,整体Pipeline』相关的知识,希望对你有一定的参考价值。

笔记结合了游戏引擎架构 Game Engine Architecture by Jason Gregory 第二版

仅为个人学习整理,


目录

平台层

核心层

资源层

功能层

工具层



工具层

功能层

资源层

核心层 core

平台层 platform


功能调用基本上是自上而下(上层调用下层)


"如同所有软件系统,游戏引擎也是以软件层(software layer)构建的。通常上层依赖下层,下层不依赖上层。当下层依赖上层时,称为循环依赖(circular dependency)。在任何软件系统中,循环依赖都要极力避免,不然会导致系统间复杂的耦合(coupling),也会使软件难以测试,并妨碍代码重用。对于大型软件系统,如游戏引擎,此问题尤其重要。"

平台层

上层的架构庞大而复杂, 而用户的使用环境/设备多种多样(PC/MAC...   键鼠/手柄/体感...)

因此平台层需要保证可移植性


核心层

 游戏引擎以及其他大规模复杂C++应用软件,都需要一些有用的实用软件, 这类软件称为核心系统(core system)。

常见功能:

 

 游戏引擎对于底层的效率非常高, STL并不足以满足, 设计者往往会写一套适配的数据结构


资源层

 unity资源工作流程:

Unity - Manual: Asset Workflow (unity3d.com)https://docs.unity3d.com/Manual/AssetWorkflow.html


功能层

tick入手,

UE:tick / Unity:update

多线程将成为趋势 

unity的循环流程

 


工具层

 DCC

"DCC应用软件所使用的数据格式,鲜有适合直接用于游戏中的,原因有二。
1. DCC 软件在内存中的数据模型,通常比游戏所需的复杂得多。例如,Maya的场景节点,以有向无环图(directed acyclic graph, DAG)存储,包含复杂的互相连接的网络。Maya还存储了该文件的所有编辑历史记录。Maya场景中每个物体的位置、方向、比例,都以完整的三维变换表示,此变换又由平移(translation)、旋转(rotation)、缩放(scale)、切变(shear)所组成。游戏引擎通常只需这些信息的一小部分就能在游戏中渲染模型。


2.在游戏中读取DCC 软件格式的文件,其速度通常过慢。而有些格式更是不公开的专有格式。
因此,用DCC 软件制作的数据,通常要导出为容易读取的标准格式或自定义格式,以便在游戏中使用。


        当数据自DCC 软件导出后,有时必须经过再处理,才能放在游戏引擎里使用。若工作室要为游戏开发多个平台,这些中间文件必须按平台做不同处理。例如,三维网格(3D mesh)数据可能导出为某中间文件格式,如XML 或简单的二进制格式;之后,可能会合并相同材质的网格,或把太大的网格分割成引擎允许的大小;最后,为方便每个平台读取,用最适合的方式组织网格数据,并包装成内存影像。
        从 DCC 到游戏引擎的管道,有时候被称为资产调节管道(asset conditioning pipeline)。每个引擎都有某种形式的资产调节管道。"

GAMES104 笔记 -引擎架构分层和整体pipeline

目录

现代游戏引擎

什么是游戏引擎

引擎开发的难点

游戏引擎分层

资源层

Importing

关联资产Composite asset

Runtime Asset Manager

功能层

Tick

多核

核心层

高性能计算

数据结构与容器

内存管理

平台层

文件路径

硬件渲染接口

硬件CPU架构

工具层


现代游戏引擎

目前市面上的游戏引擎可分为三种:

  • 商业引擎(虚幻,unity,Cry)
  • 自研引擎
  • 开源引擎

什么是游戏引擎

  • 构建虚拟世界的基础技术
  • 人类想象力或创意的生产力工具
  • 复杂性的艺术

  1. rendering,我们需要先把角色和场景给渲染出来
  2. animation,我们需要赋予动画给角色执行不同的操作
  3. physic,我们需要判断其是否发生物理碰撞等物理信息
  4. control,需要通过设备输入来执行角色的操作
  5. Internet,需要进行网络同步

引擎开发的难点

  • 游戏世界的细节和画面质量受到硬件的影响,比如算力,带宽的延迟,存储空间等硬件的限制。
  • 网络延迟与同步
  • Real-time:实时,任何算法若无法在1/30s内完成计算,则视为无效。
  • 游戏引擎不仅需要面对程序员,还需要面向游戏内容的制作者,比如提供良好的可视化工具链给artist和designer使用进行二次开发。
  • 版本迭代兼容性,就像一架飞机在飞行,我们需要在其飞行期间更换零件并且不妨碍飞机的正常运作。

游戏引擎分层

  • 工具层(TOOL LAYER)-UE/UNITY

  • 功能层(Function Layer)

工具层只能实现一些资源的编辑,场景渲染,物体是可移动的,绑定animation,NPC互动,物理方面

  • 资源层(Resource Layer)

而游戏不仅仅需要代码,我们需要大量的数据和文件,主要是美术,音频和动画。因此游戏引擎中有一层用来加载和管理这些数据和文件,使得工作流与游戏高效运行

  • 核心层(Core Layer)

容器的创建,内存分配,或者是多线程的管理等

核心层像是一个工具箱,遇到什么问题就给一套对应的工具让你去处理,需要处理内存管理时核心层给你提供内存管理的工具,需要处理容器分配时核心层给你提供容器分配的工具,需要进行数学运算时核心层提供数学模块的工具。

游戏相关的逻辑管理是建立在核心层的基础上的,因此coer layer是最核心的一层。

  • 平台层(Platform Layer)

不同硬件对应的平台也不同(PS\\PC\\Switch\\IOS\\Android\\VR……),不同硬件的输入方式、渲染接口、功能特性各不相同,引擎有一层需要对不同平台进行处理。

  1. 至此我们有了平台层,解决了不同平台特性的问题
  2. 然后我们建立所有功能处理的内核,核心层
  3. 再建立资源层对资源进行加载和管理
  4. 接着我们建立功能层来进行与游戏相关的操作
  5. 最后我们建立工具层将功能层进行的与游戏相关的操作可视化为编辑器出来供使用者们使用

为什么要进行分层

  • 通过封装分层让每一层只关注自己的事情来减低复杂度,也就是解耦合;
  • 底层提供基础服务;
  • 顶层不需要知道底层的具体实现;
  • 顶层部分迭代频繁,底层相对稳定;
  • 一般只允许顶层调用底层;

资源层

Importing

Resource的文件格式是不同的,以类似maya,max这些格式的文件来说,它们是适合在自己的软件Maya,3DMax打开,如果用引擎来加载这些数据的话是很低效的。贴图可以是 png,或者 jpg 等,他们有自己的压缩算法,如果直接在 GPU 中使用会很费性能,可以将其统一转成 dds 格式进行使用。

因此我们需要将这些resource转换成引擎的高效数据,这一步叫做importing,而转换后的高效数据我们称其为asset。

关联资产Composite asset

现代引擎最核心的观念是数据之间的关联(reference)

现代游戏引擎中我们希望对每一个资产都设置GUID(唯一识别号),从而避免资产位置改变而导致路径找不到的问题(路径无关性)。

Runtime Asset Manager

现在我们已经加载了角色的resource并import成了引擎的asset,接下来我们需要对这些asset进行实时管理,不能让他一直加载到内存里呀,因此资源层还需要处理运行时的资源加载与卸载。

在Runtime Manager中这些asset各自拥有各自的指向关联在一起。

对于资源的管理需要对以下几个方面进行平衡

  • 硬件性能:可以申请多少内存
  • 资源回收:回收资源时的耗时
  • 资源加载:加载耗时 - 同步异步处理

功能层

Tick

 

执行一次tick,就是将游戏里的所有模块逐步执行一遍。在现代计算机强大的计算能力基础之上,每隔1/30秒执行一次tick,将游戏的逻辑和绘制跑一遍。

通常Tick分为两个功能:逻辑Tick与渲染Tick。

 

在游戏中,我们先将游戏场景模拟出来(ticklogic),再进行渲染(tickrender)。

TickLogic一般做的是:

  1. 读取输入输出
  2. 计算世界物理信息
  3. 移动camera,角色和物体
  4. 碰撞检测等
  5. 以及各种游戏玩法的事都属于逻辑,比如角色A打到了角色B,因为不管看没看见,A都打到了B并造成了伤害

多核

现代计算机CPU为多核处理,因此引擎根据这一特性进行多线程计算。比如Logic和Render我们分配到不同的线程中执行,甚至再多开一个线程来执行加载。

 

核心层

高性能计算

在普通的ticklogic和tickrendering里只需要简单的线性代数计算,但是我们仍需要重新写数学库,这是因为游戏引擎是一个实时的东西,因此我们需要高效的计算。

 

  • SIMD:并行化计算,一个ALU处理多个运算。

数据结构与容器

原生语言通常会有自带的数据结构,但其中的实现通常不够高效,并且难以拓展。因此游戏引擎经常会自己实现一些底层数据结构,使得几乎没有内存碎片,而且访问效率高。

 

内存管理

游戏引擎的内存管理十分接近操作系统。游戏引擎的内存性能瓶颈:

  • 内存池(分配器)
  • Cache Miss
  • 内存对齐

内存管理的目的是为了让计算机更快速的处理:

  1. 把数据放在一起
  2. 尽可能按顺序访问数据
  3. 尽量一起读写数据

平台层

平台层存在的意义是为了让你可以无视平台的区别,把平台的差异度掩盖掉。

文件路径

不同平台的文件路径格式不一样。

 

硬件渲染接口

对于图形API来说,有OpenGL,DirectX,Vulkan等,需要一个RHI(Render Hardware Interface)封装各个平台的SDK的区别

硬件CPU架构

工具层

工具层的意义是为了让别人使用以地图编辑器为主从而形成的一系列编辑器来帮游戏添加或修改内容。

编辑器能及时的实时在我们的游戏引擎中调整效果,保证我们在引擎编辑中看到的效果和实际游戏运行起来的效果一致,提升开发效率;

工具层的代码量占的比例很多。

以上是关于[Games104笔记]3/21 基础架构1 『引擎架构分层,整体Pipeline』的主要内容,如果未能解决你的问题,请参考以下文章

GAMES104实录 | 引擎架构分层(中)

GAMES104Lecture2-游戏引擎五层架构

《GAMES104-现代游戏引擎:从入门到实践》-05 学习笔记

我的渲染技术进阶之旅Games104游戏引擎思维导图2.0上线!

我的渲染技术进阶之旅Games104游戏引擎思维导图2.0上线!

GAMES104 作业2-ColorGrading