腾讯GDC演讲:游戏研发提速40倍!如何程序化重建秦朝大都市?

【GameLook专稿,未经授权不得转载!】

GameLook报道/随着开放世界和SOC游戏在业内热度提升,创造庞大且逼真的游戏世界、尤其是有居民和各种功能的城市,成为了许多团队需要面临的挑战。然而,与现代化城市都建立在平地上不同,中国古代城市往往依山傍水而建,且建筑风格和布局也大不相同。

因此,打造中国古代大都市几乎没有可用的现成解决方案,而“手搓”一个庞大的城市几乎是不可能完成的任务,哪怕是对于3A大厂而言。

GDC 2025大会上,腾讯程序化解决方案部门的Yuqing Chen和Guo Yu做了题为“程序化方式:重建秦朝大都市”的演讲,详细介绍了他们过去一年用程序化解决方案打造秦朝咸阳城项目的经历和经验。

据Yuqing Chen在演讲时表示,该项目如果要手工制作,大概需要336人-月,但在腾讯游戏自研管线、框架和工具集的加持下,直接将研发时间缩短到了9人-月,提速超过37倍。

以下是Gamelook听译的完整演讲内容:

Yuqing Chen:

我的名字叫Yuqing Chen,很高兴今天能和我的同事Guo Yu一起分享我们去年的作品。这个项目的目标是通过程序化流程创造一座大都市。

介绍一些与我有关的信息,我是2020年加入腾讯的,负责创作程序化相关的解决方案、工具集或内容。在开始之前,我们先展示一些片段:

视频展示了使用程序化工具建造一个大型中国古代城市的关键阶段,从道路划分和地块分割到庭院生成与建筑人口,不管是普通的邻居宅院还是贵族庭院与秦朝皇宫,所有都是使用(虚幻引擎)PCG工具模块化生成的。

通过结合不同POI(兴趣点)区域的设计要求,运用了微调以确保每个区域都有其独特的特征。

整个设计包含以下工具:

建筑工具:通过特定语法和多样化模块生成复杂的建筑。

城墙工具:用spines快速创作院墙、城墙、楼阁墙体。

绳索工具:在两边创作悬架曲线以生成绳索和装饰物。

行人工具:手动创作路线和散射以生成带有不同行为的NPC。

河流工具:使用splines生成河流,并为各种河岸地形和生物群落应用模版。

接下来,是这些工具在咸阳城生成中的运用:

用农田和生物群落生成工具,短时间内就可以布置大规模的田地,穿过咸阳的渭河是通过河流工具实现的。

城市布局工具生成了平民区,遵循秦代的建筑规则,也就是“闾里”。

咸阳的三个主要市场(西市、东市)使用建筑工具创作的,结合了行人、绳索和织物生成工具,手动调整强调了每个市场的不同。

从本地市场到豪华区域,每一个区域都是与众不同的,基于古代庭院结构,如三边和L型庭院,建筑工具多样化地生成了富人区。

建筑工具使用“庭在前居住区在后”和“中轴线对称”等原则建造了露天平台和宫殿。

我们今天要分享的有4个部分,第一个是介绍部分,主要是项目背景、我们之前做过什么,以及为什么我们想要打造这样一个Demo。第二部分是我们工具集的架构,我们通过这个项目想要实现的一些目标,还有我们做的一些设计选择。第三部分是部署细节,比如布局、建筑、POI区域以及一个简短的总结。

这是宣传片的剪辑,你们可能有人已经看过了,我想展示的是之前做过的作品中的自然环境。

可以看到,我们过去几年在打造一个开放世界类型的手游,目标是有64平方公里的可玩区域,其中60%是自然区域,40%将是居民区,如小镇或大都市。

这是我们之前做过的一个中型城市,它包含大概2000个建筑,我们用了手动方式制作这个城市,我们用了21%的月数完成制作,然后又用了2%的月数进行迭代。

现在我们要打造的是大概之前16倍规模的城市,所以,如果我们用之前手动方式去做,这次预计要336人-月,基本而言是不可能实现的。

那么,我们该如何完成这个目标?带着这些问题,我们在寻求一些行业解决方案来帮助我们。育碧之前做过很多次PCG相关的演讲,所以其实有很多解决方案,其中Houdini方案对于自然环境非常好用。

我们学习了这些,并打造自己的管线创造不同的自然环境。可以看到这些图片,它们是我们正在打造的游戏世界中的不同位置。

但是居民区对我们来说仍然是个问题,因此我们检查了一些程序化城市生成解决方案,如《蜘蛛侠》系列和《黑客帝国觉醒》的技术demo。它们非常令人印象深刻,如果还没看过,我建议你去看一下。

但问题在于,我们要打造的是一个中国古代城市,具体说是秦朝城市。

以上是我们要打造城市的一些参考图片,可以看到,它们的布局不规则,这与现代城市建在平地区域不同。中国的古代城市,尤其是秦朝的城市,通常是绕着山脉建造的,因此它们在垂直方向有多重结构。

经过这些思考之后,我们发现打造这种城市没有一个特别好的解决方案,我们必须自己打造一个方案,这也是我们创造古代城市的原因。

我们通过这个项目希望实现的目标有几个:首先,我们想打造一个面向美术师的工作流程,我们的美术师会遵循一些被称之为质量等级的阶段,以打造高品质场景,所以当我们打造自己的PCG工作流时,需要匹配这个工作流程,而且每个阶段都有各自的要求。

第二个目标是遵循城市的布局设计。左侧的图片可以看到,我们已经有一些来自美术师和概念美术师的设计,我们必须向他们提供一些工具和功能,以便快速进行关卡设计创意原型。

与此同时,我们程序化生成的内容也需要遵循这种布局设计,就像中间和右边图片中展示的那样。我们在价值或PCG生成的位置方面有一些限制,比如一座建筑和一面墙之间不能有太窄的通道,或者太短的间隙,以免那里会发生战斗。所以,我们还需要匹配玩法设计。

第三个目标,是提升制作的效率,因为我们之前有过手动制作的悲惨经历,所以我们希望对制作流程加速。

来看看我们为此给出的答案,我们的工具集基本上分为三个不同步骤:第一步是手动摆放,这个步骤中,我们让美术师摆放不同的方块和曲线以代表不同的区域和道路,这样他们可以快速对关卡设计进行创意。

第二个部分,我们称之为互动PCG流程,这个过程中,我们会在每个区域内生成各种子箱体,这些子箱体代表的是建筑和其他PCG目标。美术师可以与这些箱体互动来调整它们的大小或位置,然后反复调试PCG结果。

第三步叫做PCG+手动步骤,这个步骤更多是高品质资产以及装饰内容的生成,这个步骤应该达到游戏交付的品质。

面向美术师的工作流另一部分是,我们用两个定制编辑器模式拓展了虚幻引擎,第一个是古代城市编辑模式,第二个是为POI区域设计的,也就是POI编辑模式。虚幻引擎和Houdini这两个应用之间还有一个数据转换工作流,通过我们的定制化PCG服务实现。

所以,通过这种方式,我们可以让美术师直接在虚幻引擎内创作内容,在这个流程中不必打开其他应用。可以从图片中看到,左边美术师画了不同的颜色,它们实际上是区域和道路,我们会将这些代理数据发送到Houdini,也就是右边部分。当数据处理完成之后,我们将数据取回引擎中获得场景。

我们的第二个目标是满足中国古代城市布局要求,所以我们回顾了中国古代的建筑风格,发现每个朝代都有各自的风格。就像我们之前提到过的秦朝“闾里”制,宋代的“街巷”制。我们还回顾了不同区域的布局,比如生活庭院、花园、宫殿或者中国传统庙宇。所以,在我们的工具研发中,我们会尊重这种独特性。

我们的第三个目标是提升制作效率,所以,我们希望美术师聚焦于POI区域,在这些区域中,可能会有大量的玩法设计。由于我们80%的内容将是程序化生成,另外20%将会是POI区域,即图片中的紫色部分,我们还专门为这个部分设计了特别的工具。

提升制作效率的另一个部分,我们想要快速在布局之间调整。所以我们为手动多区域一次调整研发了分配调整法,比如左侧图片中,多个区域可以同时调整,我们的美术师可以获得高频率反馈。

对于单个区域,参数控制可以生成多元结果,所以我们的美术师可以按照自己的意愿选择更好的一个。

另外,我们的PCG结果可以在生成之后手动修改,美术师可以调整区域效果,以便决定单个区域的最终外观。

工具集框架方面,可以分为两个部分,左侧的虚幻引擎界面,和右侧的PCG后端。虚幻引擎界面负责处理美术师输入数据,比如一个摆放的方块、或者描绘的区域,PCG后端负责处理程序化相关的计算。调整完成后,数据会通过我们的PCG服务传送回虚幻引擎界面。

我们的引擎界面的一个重要任务是处理输入数据,让我们的美术师画出区域和道路,为关卡设计做创意原型。道路会将区域划分为子区域,如图片中的红色和黄色箱体,它们都是子区域。这些子区域,将成为后续流程的基础。

我们的PCG后端会从引擎接收这些由美术师创作的区域数据,并以递归方式生成布局,如图所示,很多布局都是根据我们之前提到的“闾里”规则生成的,以匹配秦朝的建筑风格。

在这一步当中,细节内容,如建筑、道路、NPC或者一些装饰内容也会被生成。

对于POI区域,我们设计了一个专门的工具集。我们的美术师可以用这些POI工具集快速创作多种元素,如绳索、标志、各种各样的物品或者城外的水田,这里我们在两个建筑之间创作了悬架曲线。

下一步法的PCG后端和USD部分,我会交给同事Guo Yu做更多的解释。

Guo Yu:

我是Guo Yu,自从2020年开始就在腾讯工作,我写了很多代码、也画了很多图形。很荣幸能在这里介绍我们的PCG框架,我们将其称之为Flow,这个框架是前面Yuqing所说的一切的基础。例如城市布局的生成、建筑的安排都是由Flow支持的。

一些独特的功能让Flow脱颖而出,首先,它使用了USD作为标准,这不仅可以与其他数字内容创作工具无缝集成,还给了我们无与伦比的表达力。其次,它是建立在Omniverse上的云服务,这可以让我们更容易与团队成员合作,还能让我们能够扩大所需要的计算资源。

第三,它在布局算法方面拥抱Houdini。Houdini依然是程序化内容生成最强大的工具,而且它与我们的云端框架无缝协同。最后,它利用了分布式平行计算,可以让我们快速、高效地生成大规模内容。希望这些可以回答为什么我们不使用另一种PCG框架的问题。

那么,Flow看起来是怎样的?

表面上看,它带有蓝图一样的路径图形界面,可以让流程一步步工作,我相信这看起来非常直接,而且大部分人都很熟悉。

表面之下,整体上它通过3个步骤运行。首先,它从虚幻引擎收集数据,将数据转化为USD格式,并将文件上传到一个服务器。然后,在服务器上,我们处理输入的USD文件,运用参数和算法并生成一个USD输出文件。最后,我们取走USD输出,将其转回虚幻引擎。

这可能听起来极其简单,但其实它非常强大。因为,当你需要从虚幻引擎调用一些外部工具的时候,始终需要以一种或者另一种方式来回转换数据。我们认为USD对此是个理想选择,为什么?不妨看看它自己的介绍:

USD是一个为合作创造3D场景设计的高性能可拓展的软件平台,USD可以允许数字内容创作工具之间丰富的交换,这难道不是很方便吗?此外,它已经被无数的电影作品测试和验证过。

USD的能力已经在业内被广泛运用,此外,我们选择USD还因为它的高性能和高拓展性。

性能方面,USD是为快速和效率设计的,能够轻松处理大量数据,因此来回转换的效率较高。USD具有存储修改内容到单独文件的能力,就像是打了一个补丁,这进一步减少了更多的沟通成本,与PCG框架结合起来很完美。

众所周知,USD诞生于电影行业的皮克斯,很多功能都是围绕他们的需求研发的。另一方面,我们是游戏开发者,还有些方面是USD没有覆盖的,例如在虚幻引擎中,我们有场景、树叶、蓝图等等。

幸运的是,USD是极其灵活的,我们可以跳过尽可能多的属性,可以定制自己的规划,可以表达资产组件、actor和它们资产之间的复杂关系,这对于建立一个虚幻引擎场景是至关重要的。

这是我们所做的,我们增加了树叶支持,以便能够支持树叶的性质和类型;增加了场景支持以便我们能从获得场景高度层、边缘层、权重图、水分配系数等等。

对于静态网格,我们可以获得各种LOD变体,可以用USD能力对碰撞形状进行具体化,如球体和方块。我们还可以控制资产的存储位置让蓝图使用,还有所有的meta数据等等。

所以,有了这些功能,我们可以用USD呈现一个完整的虚幻引擎场景,以这种方式,通过USD我们可以在Houdini内完全控制虚幻引擎场景。

这是我们使用USD的一个案例,我们在一个USD属性里放了大量的文本数据,它可以最大达到数十MB,我确信这不是USD设计的初衷。但通过这种方式,我们可以确保结果在虚幻引擎中是可以再编辑的,以便适应我们的需求,USD可以毫无问题地处理这种事情。

接下来,我们说说把Houdini放在云端的好处。实际上,这是我们打造Flow框架的最初动机。

首先是可达性,在云端运行Houdini可以避免用户在本地机器上安装它,所以美术师和策划这样的用户可以低成本使用。其次,中心化HDA,现在所有人都可以使用最新版本的HDA,不再有版本不匹配、不再有依赖性错误,非常好。对于性能和增量更新,我们之前已经提到过。

最后是HDA保护,出于某种意义,你想要让用户使用HDA但又不接触源代码,或许收费是最安全的方式。

最后,Distributed Cooking。

这是我们为HMCT项目做的一些东西,很大提升了性能。有了我们现在的工具,它变得容易多了。由于Houdini已经在云端运行,USD文件也已经存储在云端,只剩下分散任务和收集结果的问题。

在这个图片中,一名用户提交一个任务,同时就会有人工对其进行工作,但由于我抹掉了用户名,所以图片可能看起来有点糊。不论如何,以这种方式,一个大型城市可以几分钟内生成。接下来交给同事Yuqing。

古代城市的布局

Yuqing Chen:

这部分,我们会谈到中国古代城市的布局。基本来说,我们的布局可以分为两种类型,第一种是定居点式建筑,如平民区或富人区;我们还有大规模建筑,如官府或皇宫。

我还想进一步介绍一下我们之前提到过的“闾里”制,由于秦朝是中国历史上一个比较早的朝代,已经过去2200多年了。它在当时是一个非常军事化的国家,所以政府以极其严格的律法管理人民,居住区也反映了这一点。

可以看到,左侧图片就是“闾里”制的概念艺术版本,(《尚书》)周礼中有这么一句话:五户一邻,五邻一里。所以这就是闾里制的基础,以便于政府管理。

从布局上看,闾里制很像西洋跳跳棋,可以看到右上方和左下方的图片,看起来像是分散的箱体。所以,为了便于我们的工具研发,我们为最初的闾里布局增加了一些变体,以打破这种高度重复的节奏。

例如我们的平民区,我们的TA会在Houdini当中打造算法和HDAs,以递归方式生成这些布局。例如我们有一个输入方块,是由我们的美术师在引擎中创作的,我们将其分为不同的闾里单位,每个闾里单位又会再次分为子庭院,如第一步到第三步展示的那样。

建筑和墙体会生成到每个庭院,更多装饰内容也会被生成,像第五步中的生物群落区域、装饰物或者NPC。

这里我们可以检查一下结果,这是引擎中的最终效果。我们还增加了第三人称视角。

富人区的研发也遵循同样的规则,但有了更多的空闲空间或者更大的建筑以及更整洁的布局。

这里也有一个引擎效果的展示:

对于官府建筑的布局,它始终占据更大的区域,且建筑方面有更大的反差。

从这些图片,可以看到总有一个更大的建筑在中心位置,周围有更多子建筑。

至于我们为此研发的工具,我们的工具始终会将这个区域切分成至少一个主庭院,然后其中有一个较大的主建筑,如第三和第四步,我们还从算法方面保障这里始终有足够的空间摆放主建筑。

这里可以看到结果:

为了让官府区域布局有更大的多样性,我们专门为此研发了一个编辑方法,我们称其为共线编辑(Collinear editing)模式。

由于我们的布局是在Houdini中生成的,所以在完成之前,我们的美术师看不到结果。这个方法将为Houdini的第一批Cooking数据生成控制器,我们的美术师可以基于视觉效果进行修改,而不是输入参数不断尝试。可以看到,我们可以通过拖拽布局边界的方式直接调整官府布局。

基本来说,这种编辑模式的灵感来源于室内设计DCC,他们经常使用这个,这是一个几何体算法的运营方式,当美术师修改了一个布局,就会立即被检测到,这可以帮他们快速调整现有布局。

我们使用这个方法创作皇宫,这里可以看到结果:

第一步是从Houdini里生成布局,我们讲这些数据发送到随后的步骤中,就像之前那样,创作更多的建筑和装饰内容。

这里是最终结果:

如果还记得,你会知道,我们还需要为每个庭院填满内容,所以我们有四个类别需要生成:建筑、内部道路,如花园这样的装饰内容和NPC。

庭院内的建筑还有不同类型,如墙体、后院建筑、子建筑、或主建筑,我会在随后的建筑编辑器环节介绍它。

对于装饰内容,如内部花园,我们设计了一个特别的方式通过Houdini的计算利用虚幻引擎的PCG框架。

例如,一个内部花园会根据不同区域发生变化,比如富人区和平民区的花园是不一样的,所以花园的某些部分需要由美术师预定义,如某些区域可用或不可用的树木品种。

一些参数需要完全随机,如树木的位置或者花园形状。为了处理这种要求,我们研发了一种名为Local PCG的流程,可以让我们的美术师进行视觉化编辑,在虚幻引擎中创意原型。

这之后,我们将这个预制的东西通过其名字发送到Houdini,如Waze或者一些关键参数,比如决定是否开启树木生成。

我们会让Houdini的HDA来决定这个花园的形状和分布,如左侧所示,我们将预制发送到不同区域,那些小小绿色区域就是它的生成结果。

随后,当我们将数据取回引擎的时候,会有一个后期处理将预制根据Houdini的输出实例化。通过这种方法,我们的美术师可以视觉化对其创意原型,PCG元素,并控制这部分的关键外观。与此同时,我们避开了输入和输出时较重的点云数据,因为这很笨重且很耗时。

内部排列和NPC也是通过这个方法创作的,可以看到左侧每个角落的预设,结果完全是由Houdini决定的,这就是细节内容部分。

古建筑

接下来说古建筑部分,之前说过,我们依然要填充每个区域的建筑形状和类型,虚幻引擎中的静态网格资产无法被轻易改变大小或者tiling,所以我们研发并定制了建筑格式来解决这个问题,当然,是通过定制化建筑编辑器。

建筑外观方面,由于秦朝是中国历史上较早的朝代,我们能够得到的参照物有限,所以我们花了大量的时间查阅历史博物馆中的文件,以及一些电影和电视影响,甚至是一些古墓出图的图片。比如右上方的图片,实际上就是出土的图片,这个小建筑是古人用来装去世之人灵魂的。我们通过这种方式试图定义秦朝的建筑外观。

建筑的结构部分,中式建筑始终都有比较复杂的结构和屋顶形状。所以,当我们试图创作工具来帮助我们美术师快速创作建筑的时候,我们需要做一些简化。

经过一些工作,我们发现有两个主要方面可以被工具研发处理:结构和模块。

模块指的是,我们可以讲一个建筑分为不同不分,如墙壁、窗户、门、屋顶等等,所以我们按照其类型、大小和枢心对每个模块进行标准化。当移入引擎的时候,它们会被自动分类。

所以,当美术师创作一个建筑,编辑器可以为它们找到必要资源。

建筑的结构是一系列的紧凑方块,它们被生成以代表建筑的不同部分,就像右侧图片所展示的那样。这样我们就可以像堆积木一样用不同箱体组成一个建筑。

问题是,不同的箱体有不同尺寸,每一个表面可能都需要不同的tiling组合,这时候就需要使用建筑语法。建筑语法部分,我们的灵感来自于《黑客帝国觉醒》的技术demo,我们使用语法来定义古建筑的外观。

语法本身由字母和符号组成,如图中有两种颜色的C字母模块,两者之间,我们还有不同的子模块,这是用语法表述一堵墙外观的方式。

我们还研发了一个图形界面让我们的美术师互动编辑这个语法,所以他们不需要想象语法的视觉效果,这极大降低了工具的使用难度。

屋顶部分,中国古代建筑的屋顶极其复杂,如左侧,有很多种不同类型的屋顶,我们这里需要做一些简化。经过研究,我们发现一些节奏是可以局部重复的,所以我们将它们分为不同类型,如图中右侧所示,例如单向、双向,或者交叉双向之类。

这里我们做了大量的粗糙节奏,当美术师建造一个建筑的时候,他们就不用再注意屋顶部分,我们研发了一个自适应逻辑,roof Logic来帮助他们。通过识别建筑,编辑器可以为其选择对的结构和屋顶模块。

这里展示的是我们如何创作一个完整建筑:

我们先做地基,然后是一层,二层,随后手动增加屋顶。随后替换一些模块,最后通过锚定系统改变尺寸。

为了更有效率地管理这些模块并复用它们,我们想到了新想法、新概念。第一个是建筑模块,它包含单个模块资产和模块语法,这个模块可以移出或移入复用。这样,当我们想要创作一个新建筑的时候,就不用每次都重新开始做。

第二个概念是建筑模板,它包含了一些有序的建筑模块,这个模板可以放到一个建筑方块上,形成更大的建筑。

就像之前提到的那样,我们有一些操作,比如合并和裁剪来帮助我们的美术师快速重塑建筑形状。

可以看到,我们试图为主结构增加两个子结构。

有些建筑可能需要部分调整大小,所以我们为此研发了一个锚定系统,通过使用这些锚定,我们可以修改建筑某些局部的大小。

我们还为它们研发了程序化功能,让美术师们可以单击几次就能创作外观不同的建筑。

POI工具集

最后一部分是POI区域,在我们的城市中,有很多区域带有独特功能,而且无法通过统一的PCG逻辑生成。所以,这部分非常耗时间,且依赖非常重的手动摆放工作,我们为此专门设计了一个工具集。

我们的美术师可以使用POI工具集帮他们增强场景和可玩性设计的多样性,比如图片中,我们使用了NPC工具、绳索工具或者曲线分散工具帮他们更快速摆放更多物品。

框架方面,我们在虚幻引擎C++中有一个TooBase class来概括一些基础功能,如初始化或退出处理。我们还有一个继承自它的base class来处理一些鼠标互动操作,如点击或拖拽。

我们还有一些继承自它的工具,如曲线分散或墙壁工具、NPC工具。每个工具都会生成一个名为生物群落代理类(proxy class),后者可以实例化到世界中。

我们使用蓝图系统来拓展生物群落代理类,并通过蓝图系统触发虚幻引擎PCG框架。所以,我们的美术师可以把这些工具拓展到不同的功能上。

我们来看看这些工具:

我们用曲线分散工具在建筑前创作一些马车,这是POI区域最常用的工具。

我们还通过之前提到的识别结构箱体生成建筑前面的标志

我们通过使用NPC工具来生成街上的行人

我们通过城墙工具创作城墙,而且可以通过拖拽的方式自动适应大小,方便美术师的使用,它还支持在城墙模块之间插入建筑。

这里我们在城市之外生成一些农田。这个工具支持不同节奏,如直线或者曲线节奏,还支持在田地里生成一些设施,如农民或者一些辅助设施。

总结

如此前所说,如果我们尝试用手动方法创作这个超大城市,就需要336人-月,每次迭代就需要32人-月,基本而言,这种方式不可能做出来。

通过使用我们的古代城市工具集,我们成功将研发时间缩短至9人-月,迭代时间缩短至0.5人-月。至于未来,我们认为虚幻引擎PCG框架可能在游戏研发的PCG部分扮演更大的角色,所以保持期待。

最后,感谢我的古代城市研发团队,我们去年非常辛苦地做这个项目,最终我们做到了,很荣幸成为其中的一员。

如若转载,请注明出处:http://www.gamelook.com.cn/2025/05/569023/

关注微信