Lecture2
- 1 经典五层架构(5+1)
- 1.1 资源层(Resource Layer)
- 1.2 功能层(Function Layer )
- Tick
- 1.3 核心层(Core Layer)
- 1.4 平台层(Platform Layer)
- RHI(Render Hardware Interface)
- 1.5 工具层(Tool Layer)
- DCC(Digital Content Creation)第三方数字生产工具
- 2 要点
1 经典五层架构(5+1)
- Tool Layer:脚本、动画、材质等编辑器
- Function Layer:物理计算、脚本、AI、动画、交互、渲染
- Resource Layer:加载管理数据、文件、模型、音频等需要的资源
- Core Layer:一个工具箱,包括内存管理、容器分配、数学运算、线程池等基本代码
- Platform Layer:平台通用性,多平台(PC、Mac)的输入、输出(VR、AR),多平台运行与发布
- 额外一层:第三方库工具
1.1 资源层(Resource Layer)
如何访问数据
离线资源导入:引擎导入资源需要做
数据转换
。因为从各种资源编辑软件中导出的资源
,包含了很多对我们的引擎而言无用的数据
,我们需要去其糟粕取其精华,将资源(Resource)
转化成资产(Assets)
,即资源引擎化
。 比如一张贴图可能是jpg或者png格式,这些贴图文件是压缩算法的产物,并且他的数据排列格式在GPU中绘制效率很低。因此不管什么样的贴图文件,我们需要先转化为dts格式
,这种格式按照16byte把贴图顺序排布,可以直接放进显存中使用资产的使用:比如要表达一个机器人角色,所用到的材质、网格、贴图、动画、音效、Shader等
资产
其实是互相关联
的。因此我们需要定义一个额外的资产:Composite Asset
来管理这些复杂的相互的Reference。如下图,它是一段代码,存放了这个角色所引用/依赖的所有资产的名字、GUID、路径等信息
GUID(Globally Unique Identifier),全局唯一标识符
运行时资产管理
- 资源层充当着一个用于加载、卸载资产的虚拟文件系统,它管理着资产的
生命周期
和引用关系。 - 随着游戏的进行,有些资产需要卸载,另一些新的资源需要加载。当一个资源已经不再需要时,辣鸡回收系统(GC-Garbage Collection)就要发挥作用。如果GC做的不好,会出现卡顿的情况
- 延迟加载:随着角色的移动来决定加载什么资源。这个在画质开得比较低的游戏中应该体验比较明显比如原神、APEX
1.2 功能层(Function Layer )
功能层是非常庞大的,有时候经常与游戏内容混淆咋一起,某些功能难以区分需要放在游戏业务层还是引擎完成。比如引擎的相机是渲染画面的,某些FPS还有要求相机有摇晃的感觉,那么摇晃感应该属于功能层由开发者们完成,而非引擎提供
Tick
如何让游戏世界充满生机?一个非常重要的概念 Tick
Tick就是我们的游戏世界中最小的时间单位。
一个Tick之内,游戏引擎会把所有的事情都做一遍(包括但不限于功能层)
,比如:读取用户输入,动一下相机、更新角色控制器的状态、动画系统计算、物理计算、渲染出画面、网络数据传输、再处理输入输出、内存垃圾回收(GC)…
一个tick其实就是一帧的时间DeltaTime,输出一帧画面 需要把所有该做的事情都做一遍 所以这个Tick在30帧的游戏里 就是 130 \Large\frac{1}{30} 301秒,以此类推
Tick分为两个部分
- 逻辑层(Logic):完成引擎各个系统的运算工作
- 渲染层(Render):将逻辑运算部分得到的数据根据相机的属性进行裁剪后,渲染成图像
最初的引擎是单线程的,未来的引擎一定是多核架构
1.3 核心层(Core Layer)
核心层涵盖引擎诸多基础模块,这里提到两个
高效率数学库
- 因为要求实时,所以代码必须
高效率
。不要求精确解,追求近似解,可以极大的提高算法的效率(渲染中许多公式的求解就是近似解) - SIMD(Single Instruction Multiple Data):单指令多个数据同时计算
- 数据结构在这里就显得尤为重要,包括容器的代码都需要重新写,因为STL提供的容器并不高效
内存管理:引擎会申请一大块内存,自行管理。原则是:批量处理
- 相同类型数据尽量放一起,这样可以减少
cache miss
的几率(CPU需要处理数据时,如果数据已经在cache中,则 cache hit,不在则cache miss)。因此选择CPU的时候cache越大越好 - 删除数据时,尽量等时机成熟一起批量删除,可以提高效率
核心层提供了整个引擎所要使用的绝大部分的函数,是影响引擎效率的非常重要的环节,需要极高的代码质量
1.4 平台层(Platform Layer)
不同的平台规则是不一样的,比如文件系统的路径,win和mac的目录中分别使用的反斜杠和斜杠,编写代码,掩盖这些不同平台的差异,就是这一层所需要做的工作。
RHI(Render Hardware Interface)
- 不同平台常用的图形接口不同。PC多使用
DirectX11
、DirectX12
,Android常用opengl
、Vulkan
- RHI重新定义了一层Graphics的api,把各个平台的接口封装起来。比如下面这些纯虚函数,就是一个个接口。以shader为例,写功能层的程序员只需要他写的shader代码传入,后面的细节他就不需要知道了。编译成GLSL还是HLSL,根据选用的平台不同,虚函数会执行不同的代码。
硬件架构的不同:平台可能硬件结构不同,比如:PS3上面的CPU叫做PPU,GPU叫做SPU。很多运算可以放在一些特殊硬件上,完全不同于GPU和CPU的架构,因此就需要为这些硬件编写不同的代码,才能很好的运行
1.5 工具层(Tool Layer)
工具层 = 自带编辑器 + 第三方数字生产工具
- 蓝图编辑器:编写游戏逻辑部分
- 材质编辑器:maya和3Ds等各种软件的材质表现是不一样的,而引擎内置的材质编辑器可以保证你在这里看到的效果与游戏中的效果是完全一样的,因此是非常有存在的必要的
- 自带编辑器的开发用什么都行(QT、H5等),但其核心理念是:
方便编辑者发挥能力
DCC(Digital Content Creation)第三方数字生产工具
- 比如Houdini、MAYA、Blender、3DS MAX等。
第三方编辑器
和自带编辑器
生产的数字资源都会经过引擎的导入/导出器(Asset Conditioning Pipline)
变成引擎需要的Assets。- 导入器:各种不同格式的资源转换成引擎需要的Asset格式
- 导出器:将Asset导出成不同格式的资源文件
2 要点
- 引擎是分层架构
- 越底层的代码越稳定,技术要求越高
- 下层决不能出现对上层的依赖
- 游戏引擎是靠tick来驱动的