【技术分析】探讨大世界游戏的制作流程及技术——大场景制作技术概况篇

【技术分析】探讨大世界游戏的制作流程及技术——大场景制作技术概况篇

之前我们分享过《【技术分析】探讨大世界游戏的制作流程及技术——前期流程篇》,接下来我们了解一下大世界场景制作技术有哪些,本篇旨在给大家介绍目前业界的做法,能让大家有一个宏观的知识蓝图。实际上,针对不同的游戏类型和美术风格,制作技术在细节上有着非常大的不同,业界目前也很难说有一套标准且高效的流程,所以一些细碎的技术点将会在其他篇章逐一讨论。

说到大世界,到底多大的地图尺寸才能算得上大世界呢?下面给大家列举一下目前市面上的大世界游戏地图尺寸,详细的介绍可以看这个视频:
https://www.youtube.com/watch?v=UvFdMax3wlAwww.youtube.com/watch?v=UvFdMax3wlA

  • 堡垒之夜:5.5 k㎡,~ 2 km x 3 km
  • 漫威蜘蛛侠:11 k㎡,~ 2 km x 5 km
  • 地平线 零之曙光:22 k㎡,~ 4 km x 5 km
  • 绝地求生:64 k㎡,~ 8 km x 8 km
  • 塞尔达 荒野之息:72 k㎡,~ 8 km x 9 km
  • 荒野大镖客2:75 k㎡ ~ 8 km x 9 km

最后说一下我最近在玩的《刺客信条 奥德赛》,全地图 256 k㎡(16 km x 16 km),其中陆地面积占40%左右,也就是 100 k㎡,高度峰值为 800 ~ 1000 m(个人跑图目测的估值)。



创建地形


对于创建如此庞大的地形,显然不可能直接使用3DMAX等建模软件制作的静态模型文件,一般来说引擎都会有一套地形系统(Landscape)来支持地形的生成和渲染。

引擎的地形系统根据高度图来构造地形,对于相同的顶点密度、模型数据形式的地形占用的内存是高度图的6-7倍。而且地形系统还提供强大的LOD功能,远处的地形网格顶点会被优化减少,分块渲染等等功能。

分块管理是大世界制作的核心前提。

世界由多个关卡组成,每个关卡控制各自内部的资源加载和显示,一般一个关卡包含一个Landscape地形。

按照Unreal的地形系统来说,就是一个Landscape地形由多个Component组成,Component是渲染的基本单位,也就是说地形是按照Component分布,一块一块渲染的。

合理规划好每个关卡的地形尺寸、每个地形部件数量和大小、部件的顶点数组成以及每个顶点间隔代表游戏世界多少米,对游戏性能有着重要的影响。

《孤岛惊魂5》 的标准:
一个关卡地形大小为 1024 m x 1024 m,部件大小为 64 m x 64 m,也就是说地形每64平方米为一个渲染批次,一个关卡内大概有400左右个地形批次。

0.5 m 对应高度一个像素,也就是说一个关卡地形使用的高度图、Splat图的尺寸是2048 m x 2048 m。

地形工作流


目前比较流行的工作流:World Machine->Houdini->游戏引擎

概括地形制作的工作流程,我想会是这样的:
World Machine就是一个做地的(特点是:快);到了Houdini阶段就是在World Machine的结果上继续加工,自动化完成World Machine做不到的事情(特点是:自动);最后到达游戏引擎,这里就是广大美工们默默耕耘、一点点细化场景的地方(特点是:手工、细节)。

注意:这里使用World Machine一词指代地形制作软件,其实还有很多优秀的地形制作软件比如World Creator、Terragen 3等。

分层概念:制作游戏是一个反复迭代的过程,在制作初期,我们会尝试游戏中各种各样的新想法,并可以快速地还原和重做。因此,《幽灵行动 荒野》提出了分层的概念,就是类似于PS中的图层的意思。

对于这个分层的概念,个人认为其实只是制作过程中形成的一种流程概念,实际开发中并不会局限于这些条条框框,不过了解一下还是很有好处的。

  • Base层:World Machine制作的原始资源(高度图和Weight Map等)我们定义为Base层。World
    Machine提供了一套完整专业的工具集,用它来构建世界原型进行快速验证是个不错的选择。

  • Macro层:在World Machine解算的基础上,通过笔刷等手段手工地对地形的宏观结构进行调整,这一层的调整内容为Macro层。如果编辑结果不令人满意,则可以轻松擦除Macro图层内容,以返回到高度图的原始状态。软件方面使用World Creator是个不错的选择。

    Macro翻译为“宏观”的意思。

  • DCC层:然后进入Houdini环节,通过各种程序化工具细化我们的地形,例如生成道路网、河道和村落分布等,这些输出内容我们定义为DCC层。在此阶段,我们还会完成其他重要的工作:例如根据坡度、高度、粗糙度和World Machine的其他遮罩(如Flow Map和Smoothness)来定义地形的材质分布;或根据坡度、高度、地表材质、密度和向阳面等规则来生成生物群落的分布;或自动化生成峭壁,这些稍后讨论。

  • Micro层:最后,这三层导入到引擎中。我们完成了大规模宏观视角下的工作后,自然也需要对微观细节进行手工调整,这一阶段的修改,定义为Micro层。

    Micro翻译为“微观”的意思。



World Machine阶段


通常选择World Machine工作流开始创建地形。

从NASA等网站导入展示地形数据Height map,配合分型噪点功能,然后进行应用侵蚀建模细化地形。

World Machine除了输出Height map,还能分层导出多种有用信息。权重图Splat Map(也叫Weight Map)是初步纹理化的依据,此外还能导出高精度全局地图Visa Map。

权重图(也称为Splat Map或者Weight Map)是一组一个或多个RGBA位图,其通道充当归一化的权重,用于控制世界上任何给定位置的纹理绘制。

Houdini阶段


World Machine帮助我们快速创建这个大世界的雏形结构,并且拥有简单的纹理外表。

有了World Machine生成的高度图、Splat Map等资源,我们就可以在Houdini中重构地形。利用Houdini强大的自定义程序功能,我们可以制定任意的规则去程序化地完善我们的地形,并模拟复杂的自然规律细化群落分布,地表材质等等。

主要做的内容包括:

  1. 进一步细化地形,自动化完成路网、河流、村落和城市的分布。输出高度图、Splat Map和路点信息。
  2. 按照自然物理规则模拟生物群落分布情况。输出分布密度图、Splat Map和点云信息等。
  3. 根据地形自动化生成峭壁、河流等网格模型。输出静态模型。

Houdini导出的数据内容将直接跟引擎编辑器对接,常见的数据类型为:位图,点云信息,模型。

游戏引擎阶段


资源进入游戏引擎阶段,场景编辑开始分工协作,每个人负责各自的区块,所以引擎必须要提供一套合理的多人协作方案,以及需要制定诸多制作规范避免出错。

在这一阶段最重要的问题是,Houdini自动化的内容与人为修改的内容如何同步的问题。《幽灵行动 荒野》项目组提出的方案是让引擎修改的信息回流到Houdini,然后让Houdini重新计算其自动化信息再同步到引擎。对于这一点,个人意见是,没有这种硬实力的公司或团队最好不要这样做。个人认为最好的解决方案是,Houdini一旦输出到引擎,就已经定死了,之后的所有修改都要靠人为调整(除非是大规模的迭代,需要重新返回Houdini演算)。

然而在这阶段仍然可以开发一些自动化的工具来协助提高编辑速度,比如:道路/河流/桥梁编辑工具、物件组合生成器、物件自动对齐地形和群落生成器等等。

渲染分析


前面讨论了地形制作的流程,下面简要地分析地形渲染的相关技术,还是以《刺客信条 奥德赛》的截帧画面来例子。

画面由GPA截取所得,初步分析:画面上看到的东西分为四类:地形、人物、岩壁模型、植被。

主角脚下附近的地形网格明显被曲面细分过,细分区域集中在道路上,可知仅有道路材质具有曲面细分功能。主角站立面积大约占地形正常网格一个单位,推测地形精度为0.5m。

同屏内地形材质数量4-5个:泥石、草皮、泥土、石质。水坑的实现考虑为贴花。

岩壁模型被大量运用在地形斜坡上。



地形材质


要实现如此庞大且多样的地形地貌,且要满足近处高质量的细节要求,Tilling材质混合是唯一的选择。通过Substance、Quixel等获得高精度的四方连续材质的PBR贴图,然后通过多张权重图将不同类型的材质混合在一起,从而构造出丰富的地形地貌,这些权重图称为Splat Map。

然而,手动绘制如此庞大的地形混合权重图是不可能的,幸运的是,我们在World Machine/Houdini制作地形的时候,可以通过算法来生成这些地形材质的分布,并获得各种规则生成的Mask,最终合成导出为我们想要的Splat Map。

远方地形如果依然使用Tilling材质混合的方法,会出现明显的重复感,所以我们预先烘焙出一份“宏观俯瞰图”(Global Color Map)用作远景渲染。

地形材质方案

地形混合技术:三件事情
(1)当前像素用到哪些贴图
(2)每一层贴图的权重是多少
(3)混合的算法

方案一是Unreal的地形材质采用经典的方案。一张权重图Weight Map包含四个通道只能混合四种材质,超出四种材质就要新建一张Weight Map。而一种材质包含Albedo、Normal、Roughness/Metallic三张贴图,四层材质就要13个纹理Samples,可见Shader的计算是非常昂贵的。使用此方法渲染地形,必须要对地形的材质有很好的规划和控制。


我们已经很熟悉的权重贴图

方案二是一些自研引擎常常会采用ID Map的方法。在绘制地形的时候,引擎会自动筛选出当前区块内权重最高的4种材质,并将它们的Index和权重储存到ID Map中。Shader再解码ID Map信息,就可以获得对应的材质和权重。

方案三是Runtime虚拟贴图技术。简而言之就是通过预先将地形的材质混合(在Computer Shader中计算)并缓存到一张巨大的实时纹理上,Shader采样时只需要从这张大纹理中拿到属于自己的那“一块”即可,拿到的结果已是最终的混合结果。原来要采样多张图然后混合,现在相当于是单层材质,Shader的性能也得到极大地提升。

贴花

贴花能有效增强场景材质的多样性,但存在Overdraw重叠绘制的开销。

Runtime虚拟纹理技术的另外一个收益就是能极大地降低贴花的性能消耗,因此能突破限制被大量运用到场景中。

水滩、碎石、公路划痕等贴花类型被广泛使用并以程序化的方式放置。

《孤岛惊魂5》进一步提升了这种贴花技术,让它具备曲面细分的功能。

有趣的是,这种局部的曲面细分方式比起直接对摄像机近处的地形进行曲面细分性能要高,效果和可调节性更好。

地形与静态网格的融合

地形与地上的物件不可避免会产生衔接问题,主要是纹理、法线和几何三方面的匹配。

常见的处理办法有:三平面映射、Pixel Depth Offset、距离场混合等。但是这些方案都各有利弊,而虚拟纹理技术是目前解决这个问题的最佳选择。对于这个问题,会另开篇幅详细介绍。

峭壁渲染

到目前为止,我们讨论到的所有地形材质效果都基于世界空间xz平面的,前面提到的地形纹理都是自上而下的“投影”下来的。我们还没考虑到地形的垂直面(斜坡)要如何处理。

这意味着当我们有陡峭的坡度时(见图1中红区区域),纹理会产生拉升变形(见图2山坡区域)。


图1


图2

要解决此问题,一种经典的方法是采用三平面纹理映射,得出的效果(图3)。


图3

但这种方法会产生的渲染消耗是普通地形的三倍,《孤岛惊魂5》为了优化此耗时使用各种Trick(取巧手段),过程略微复杂,不在本文讨论范围内。

如前文所说,Tilling材质在远处会产生明显的纹理重复感,由于峭壁是垂直面的,无法使用前面预先Bake出现的Global Color Map作为远景渲染。所以可以在Shader中对远距离的峭壁做减少Tilling的处理。(图4


图4

最后,为了增加悬崖结构的立体感,在Houdini中检测这些悬崖区域并生成峭壁包裹模型,最后将相关布点信息输出到引擎进行程序化放置。(图5、6


图5


图6


程序化/自动化 技术


前面讨论了地形制作以及渲染的相关技术及流程,下一步要继续丰富我们的地面及地面之上的内容,面对这么庞大的地形,完全靠人工编辑是很困难的。

接下来将会详细介绍三种具有代表性的程序化场景制作技术,分别围绕:植被、峭壁和道路系统展开论述。

植被

首先来说基于密度图的植被放置方法。

顾名思义就是利用一张灰度图来控制植被模型的分布。一层灰度信息只能控制一种植物的分布。

一般来说按照Height map的尺寸,一个像素代表一平方米的话,这个精度是不足以表达精确的位置点的,所以一般会提供一个密度参数给艺术家控制每个像素应该放置多少棵植物,但不会考虑植被之间的模型穿插问题

因此这种放置技术比较适用于草丛这种大面积连续的植被。

像森林这样复杂的生态系统,其生物群落的分布要考虑各种规则:种群的多样性、优势种和劣势种的结构、水资源和阳光分布因素、树木的年龄等等。

这个模拟过程通常是基于物理分布的,输出的结果要求保存大量信息。

我们在Houdini中实现这种物理模拟分布的过程,最终生成一系列的点云数据,每一个点储存着对象ID和矩阵数据(包含位置、旋转、大小)信息,最后将这些信息导入引擎实例化生成对应的植被类型并设置位置、旋转、大小。

可以看到,基于点云的放置方法能够支持复杂类型的物体放置,每一个物体的ID、位置、旋转等信息都会被当成一个“点云”数据储存起来。

除了植被之外,贴花、岩石、道具等等所有独立的模型都可以以点云的方式来实现自动化放置。

峭壁

让我们回到峭壁的制作话题,上面说到峭壁渲染的一些性能问题,以及其网格模型可以由Houdini自动化生成。下面就来讨论一下如何在《孤岛惊魂5》中自动化生成峭壁包裹层,以及在《刺客信条 奥德赛》中采用岩体堆砌的方案。

下图是《孤岛惊魂5》在Houdini中生成峭壁包裹层的流程,自动检测坡度是一个简单的操作,然后就是在斜坡区域生成相应拓扑结构的模型,不需要生成UV,贴图采用世界空间三平面映射的方式进行采样。

《刺客信条 奥德赛》采用简单粗暴的方法,可以看到斜坡区域被岩石模型恰当地填充,从而减少了地形渲染处理斜坡问题上的缺陷暴露。同样的,材质采用Tilling纹理+三平面纹理映射方法渲染。

路网

通过以上的流程,我们已经完成了大自然最基本的面貌,接下来开始考虑加入人类的踪迹:路。

先考虑我们的游戏需要怎样形式的路,如果我们需要的仅仅是泥路、石头路,那么直接在Splat Map上开辟出相关的材质区域即可。(如下图所示泥路)

但这样做无法表达出材质纹理的方向性,如果我们想要做出那种高速公路效果,就必须要使用模型,或者大规模的贴花(比如《幽灵行动》的做法)。

将分段路面模型重复利用拼接组合成网是一个很好的思路,但是无法解决路面弯曲的拼接问题。可以预先制作多种类型的拼接组件,按照一定的规则来组合,但这样做限制略大,可控性不高。

Spline Mesh是一种网格变形技术,可以用两个点控制一条样条曲线,从而使静态模型沿着曲线变形。Spline Mesh配合打点数据(程序化输出),是程序化制作公路网的一种方法。

路网的生成

道路网络是贯穿整个游戏玩法的重要内容,是指引玩家进行探索方向的第一要素。所以道路的分布应该按照设计图纸进行还原,同时要兼顾地形高低做出调整。

我们需要一套基于寻路算法的Houdini道路插件,根据用户输入的起始点计算出一条合理的路径,再进一步生成子道路网。

Houdini输出的资源分别是:

  1. 道路轨迹点数据,配合Spline Mesh构成道路Mesh。
  2. 道路的高度图,用来填平原有地形,使得Spline Mesh与地形贴合。
  3. Splat Map用来控制道路两边的材质。

另外,在这一操作中,还可以根据道路轨迹顺便生成道路贴花的摆放信息,输出为点云数据。

水域

水域(不包括海域)的形态也是多种多样的,从制作层面可以分成两类:
A:江河、湖泊
B:溪流、运河、水塘

江河湖泊在构造地形的时候就已经被雕塑出来,只要在Houdini中计算对应的水平面,生成对应的模型。模型大小按照关卡大小进行分割,比如1平方千米。

溪流可以类似运用道路的生成方式,从山顶引流到江河,根据寻路算法生成对应的Mesh。

其余小规模的水域就按人工放置平面模型来做,或者运用Spline Mesh曲线工具快速拉出一条水流。

关于大场景制作技术暂时写到这里,其实自动化和程序化部分内容并不是本人专长,都是从PPT上学习来的内容。程序化作为一种新颖的技术方向,虽然充满着挑战性,它在未来对于游戏制作技术的意义让我们拭目以待。


参考文章:

《Terrain Rendering in 'Far Cry 5'》

《Ghost Recon Wildlands': Terrain Tools and Technology》


这是侑虎科技第1160篇文章,感谢作者Kerry供稿。欢迎转发分享,未经作者授权请勿转载。如果您有任何独到的见解或者发现也欢迎联系我们,一起探讨。(QQ群:793972859)

作者主页:https://www.zhihu.com/people/cgtna

再次感谢Kerry的分享,如果您有任何独到的见解或者发现也欢迎联系我们,一起探讨。(QQ群:793972859)