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

本期为GAMES104《现代游戏引擎:从入门到实践》视频公开课文字实录第7期。本课程由GAMES(图形学与混合现实研讨会)发起,游戏引擎技术专家王希携手游戏引擎一线开发者共同研发。

课程共计22个课时,将介绍现代游戏引擎所涉及的系统架构,技术点,引擎系统相关的知识。为配合学习实践,课程组在 GitHub 上开源了小引擎Piccolo,上线1个月即获得了2900+star, 累计下载量已超过20000+。

以下内容为公开课视频转文字版本,为阅读通顺,有删减

01「平台层」

上节课简单介绍了游戏引擎的5+1个层次,以小明同学想做一个动起来的角色为挑战,介绍了资源层、核心层等具体内容。

这节课讲游戏引擎架构分层的最后一节 —— 平台层和工具层。

我们试想一下,小明同学已经把游戏从上到下全部写完了,他想去找小美同学得瑟一下,但发现小美用的是Mac,可用Windows开发的游戏怎么在Mac上跑起来呢?

我们发现在不同的平台上,甚至连文件路径的格式都不一样:一个是“/”,一个是“\\”。这种情况下,我不可能把引擎的代码从头到尾重写一遍。所以平台层就会变得非常重要。

平台层的本质是在上面写核心代码/功能/逻辑,可以无视平台的差别。平台层也叫做平台无关,就是把平台的差异性全部掩盖掉,这一层是现代游戏引擎非常核心的东西。

刚才讲的文件路径其实是比较简单的,真正让大家头疼的是什么?举个例子:想做一款游戏,在PC上面对的可能是DirectX,DirectX有DirectX 11、DirectX 12;在Mac上面对的是Metal;在Android上面对的可能是OpenGL ES,那在Vulkan上写图形学feature的人碰到了是不是很崩溃?

在现代游戏引擎中,非常重要的一层叫做RHI——Render Hardware Interface。

它重新定义了一层Graphics API把这些硬件的SDK差别封装起来。

这是一小段RHI的代码,大家发现其实这些函数又被重新定义了一遍,而且全部是虚函数。虚函数是一个比较高能的概念,学过C++的同学都知道,它是要你去实现的,就是说要把它编译成PC/Metal/移动端上的。

平台层比大家想象的要难写很多,举个简单的例子,比如DirectX 11、DirectX 12都是微软的,但它们的设计理念是完全不一样的,如果你把DirectX 11的代码编译成DirectX 12的,你的游戏不会跑得越来越快,反而会跑得非常慢。你必须利用DirectX 12的特性去做很多底层的优化,这非常难,但在上面写游戏功能层的同学可能意识不到这点。

所以,平台层是很容易被大家忽略的一层,但它是引擎水平高下的一个很重要的分水岭。

平台差别不只在看得见的graphics,更丧心病狂的是不同的平台连CPU架构都不一样。

在PS3里面,传统的CPU除了叫PPU之外,还有几个小的协助CPU叫SPU,SPU速度是很快的,但它访问的内存是可以直接写到显存里面的,简单来说就是在做各种绘制的时候,有很多数据预处理准备,包括一些独立的AI逻辑运算,你可以把它们放到协处理器上。

这是索尼爸爸的一片好心,但做游戏引擎架构的同学,头发瞬间就掉光了,为什么?因为在上面写AI/逻辑/资源准备的人,是需要知道算法具体跑在哪个核上的。

大家想象一下,如果按照PS3这样写了,那编译一个Xbox版本怎么办?再编译一个PC版本、Mac版本怎么办?核可能是Intel或者ARM的,也可能是大核或者小核,那哪个算法放到哪个核才算合理呢?

这是在游戏引擎平台层非常痛苦的一件事情,同学们千万不要小瞧平台层,平台层做得好坏其实对引擎效率的影响非常大。

所以小明同学如果想在小美面前展示他做的那个动画角色,首先得解决平台层。不过从目前来讲,小明大概能把文件路径搞对,他这个游戏就能跑起来了。但如果你要做一个非常复杂的游戏,比如像使命召唤这种,那么平台层是要非常用心地去设计的。

讲到这里,游戏引擎的runtime部分基本上就讲完了。

02「工具层」

游戏引擎可以理解成两大块:一块是实时的,还有一大块就是刚才讲的工具层。

工具层为什么放到最后讲?因为它不是runtime的,工具层对引擎到底意味着什么?

回到小明同学的例子,小明想做一款游戏,但是一开始角色、动画美术资源都是找小伙伴们要的,假设功能已经做好了,想请小张来帮他做自己想做的角色,这时候小明发现需要设计一整套工具才能让小张在他的世界里添东西。

工具层实际上就是允许别人以Level Editor(地图编辑器)为中心形成的一系列编辑器,比如我们很熟悉的蓝图编辑器。

还有材质编辑器,在里面去调角色细节的材质。那为什么在游戏引擎里面单独做个材质编辑器呢?因为比如一个在3DMax里的东西,在Maya里看到的效果和在游戏引擎里看到的效果是不一样的。

游戏引擎的材质编辑器会保证你在预览里看到的效果和在真实游戏里看到的效果是一模一样的,这对艺术家非常重要。

工具这一层,在我看来就是真正的生产力工具,你的创造力实际上就是靠工具这一层释放出来的。

一般来讲都是用C++去写引擎,因为它要追求最高的效率,它是实时的。但工具这层,它的开发方式非常灵活,如果你喜欢C++,可以用Qt去做整个界面,因为它以开发效率优先,不是以运行效率优先。你也可以选择C#,甚至可以用H5去做一个工具,都是没问题的。

工具这一层,每个引擎的选择都不太一样,最核心不变的一点就是工具层实际上是允许别人去创造游戏的内容。工具层也是引擎中最核心的一个体系,虽然在五层的分化中,工具层只占了一小层,但实际上工具层的代码量很多时候比其他层大,它维护起来的复杂度也会更高。

我们除了开发各种各样的编辑器之外,还有DCC——Digital Content Creation,通俗来说就是别人开发的资产生产工具,比如大名鼎鼎的3DMax、Maya、Photoshop、Fmod以及Houdini,很多大片效果都是Houdini做的。这些工具生成的大量数字资产和我们自己编辑生成的数字资产通过一条管线全部变成游戏统一的asset,那这条管线叫什么呢?

叫做Asset Conditioning Pipeline,这个名字听着高大上,简单来讲就是各种各样的导出器和导入器,比如在3DMax、Maya里面,我们把资产导出去,然后再导入我们自己的Asset,最后进入到游戏引擎里面。

所以,我们自己开发的编辑器再加上这个资产的导入器和导出器,共同构成了工具层。工具层有个很神奇的特性就是我们自己可能开发了10几种不同的编辑器,然后还用了7、8种别人的编辑器,这几十种工具会形成一个链,在这个链中间,数据必须要彼此通畅,彼此能够说话。这件事情比大家想象的要难很多,因为数据之间要实现互导,必须要有一个统一的数据格式。所以现在很多厂商在提一些通用的数据格式,比如说著名的FBX、USD格式。

在游戏中,一般来讲,游戏引擎会自己定义一套格式。所以这一套工具就构成了一个完整的游戏生态体系。

大家看到了,小明同学如果是一个引擎程序员,为了做一个简简单单可以动起来的角色,他也要做这么多东西。

所以,现代游戏引擎是一个复杂的艺术。当我们在模拟整个matrix,对世界进行模拟,其复杂度是非常高的。

我们通过一层一层,每一层只关注自己的事情,而不用再关注过多的东西,那么越往下的这个层次就要提供基础服务。

这其实特别像我们的真实世界,举个例子,生活在一个大城市里面,大家有没有想过,为什么每天电灯一打开就有电?写一个地址,东西就能寄给别人?其实一个现代城市,它也是一个生态体系,它也是分层的。

比如基础的水电、排污这些都是城市最基础的设施,这像不像Platform和Core Layer干的事情? 再往上,有城市的物流资源调度,每天我们吃进去的东西,我们扔出去的垃圾,这些资源在调度,所以城市垃圾场不会爆掉,这就是资源系统。再往上,在这个城市里,生活经商、做各种各样的业务、创造财富,这就是功能层。

城市生活也是一层层的,这是现代系统科学的一个很重要的概念:封装。这个世界如果没有封装,只是把所有的概念散落,那是不可被理解,也是不可被管理的。

比如,这个世界一切都是由原子构成的,当把足够多的原子合到一起,它形成了一个叫篮球的东西,你不用关心篮球由多少个原子构成。一群人在一起打篮球,我们看到的是一场篮球比赛,篮球比赛就是个封装。一个复杂系统,它就是一层层的封装起来的,这也是为什么游戏引擎课很有意思,大家通过这些思考,就能理解一个复杂问题该怎么解决。

在架构中有个基础原则:越往底层的东西越不要去动它。比如说平台层,这一层基本上代码拆开之后几年是不要改的。但是上面的功能层,代码可以改来改去。工具层几乎每天都在变,今天想到了要做个什么玩法,需要一个什么工具,明天就去做了。当需求不断来的时候,不需要从上到下去动它所有的系统,只需要动它外面的上层的系统,越往上,越灵活,越往下越稳定,这其实也是分层结构一个很大的好处。当我们未来在做任何一个需求的时候,同学们首先要去想的是做的这件事情应该属于哪一层,而不是着急地把算法写出来。

很多人想做游戏引擎,经常会把很多功能堆在一起,追求某个效果做得特别好,但是真正做过系统性训练的同学就会知道,首先要去想这个功能到底属于哪一层?在资源层写什么代码?在核心层写什么代码?在功能层写什么代码?这个要一层层分得特别清楚。

再讲个小trick,各个层次之间的调用,一般只允许上面的层次调下面层次的功能,绝对不允许下面反向调上面一层的功能,这就是分层的一个核心的体系结构。

大家去研究现代引擎,做得好的一定是分层的,每一层都要很清晰。

这就是这节课的核心内容。不知道讲到这儿,同学们是不是已经对游戏引擎分层的架构有个基础的概念了?是不是像小明一样,觉得已经可以开始完整地交付一个有意思的功能了?

下节课将和大家一起讨论“如何构建游戏世界”,敬请期待。

本文编辑:Piccolo 社区编委会 张嘉瑶

如对本节课有任何问题,欢迎加入我们的社群或给我们发送邮件:

piccolo-gameengine@boomingtech.com

关于我们

Piccolo游戏引擎社区

Piccolo社区是中国开源游戏引擎分享、学习的非营利性平台,由游戏引擎行业大佬、共创官、学习者共同建立。你可以在我们的社区里交流技术、互助问答、参加活动,你也可以参与Piccolo的共建,如撰写贡献代码、撰写技术文章、参与技术挑战等。

Piccolo游戏引擎

由中国游戏引擎社区Piccolo开源的一款Mini游戏引擎。采用世界-关卡-游戏对象-组件的简洁架构,便于理解游戏引擎架构思想,它不仅能有效的帮助开发者学习游戏引擎架构知识,也能帮助一线开发者实验引擎算法与第三方库、辅助个人项目快速启动。截止目前,Github点赞已突破3600+,累计下载量已超过20000+

Piccolo GitHub地址:https://github.com/BoomingTech/Piccolo/discussions

关注我们

GAMES104课程官网

GAMES104课程视频

© 版权声明
THE END
喜欢就支持一下吧
点赞530 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片

    暂无评论内容