3、开放世界制作脉络
地表生成概念:
分类:
对大地形物体材质进行分类划分:
对不同材质分类进行区域划分混合:
对不同分型进行混合合并
地表生成线性流程:
WorldMachine:
1. 地图不同地貌区域划片(森林,草原,山脉,草原,山丘,沙丘,沙漠,沼泽,海洋,湖泊)。
2. 基础图形绘制大致基础地形走势,要抽象为高度趋势,不要进行细节刻画。多使用Clamp工具来调节整体高度(如果你使用其他的地形编辑软件可以用笔刷刷,要简便一些)。
3. 使用曲线工具或形状工具绘制山脉位置,通过调节节点高度和增加随机(UseBreakup)等属性来调节形状。调节时依然尽可能进行抽象,只控制大体形态,多使用Clamp工具来调节整体高度。
4. 使用形状工具绘制湖泊或其它特殊用途区域对基础地形进行叠加。
5. 使用河流工具绘制河流走向,并可增加自动水系节点来进行自动生成。
6. 对地形进行一系列腐蚀与沉积操作。
7. 拼合不同地貌区域。
8. 使用曲线工具绘制道路,并使用工具自动贴合地表,调节高度曲线来对路面和路基进行造型。(这一步可以在houdini中生成)
9. 对整体地图的材质进行分类和归纳,移动平台需要注意Layer的混合,同一个区域最多混合4层。(也可通过其他方法超过4层混合)
10. 导出高度图,高度图尺寸和高度必须是游戏引擎所规定的比例。
11. 导出整体颜色图。
12. 使用各种选择工具,混合各种MASK得到归纳后材质分类的MASK。
13. 导出地图各个区域的MASK和点云生成所需要的斜率,方向,侵蚀,沉积等MASK。
Houdini:
1. 导入高度图文件。
2. 使用制作好的节点生成道路、河流。
3. 导出HDA基础地形到UE4中。
UE4 / Unity:
1. 导入HDA文件,拖入场景cook地形。
2. 为地形文件创建地表材质,把之前生成好的整体颜色图赋予材质,我们要对UV进行一个缩放,比如8X8KM为8129。
3. 根据不同的地貌种类创建不同材质的MaterialFunction,设置好LayerInfo(注意Weight-Blend(normal), No Weight-Blend的关系)。
4. 复制创建好的地表材质的路径(二次迭代)。
5. 把地形材质赋予地形,使用地形工具导入LayerMask并预览效果。
6. 在引擎中开启地表分层预览(先切换到地表编辑菜单,然后在游戏编辑窗口点击左上角Lit/Landscape/Visualizers/LayerUsage)。如果是移动平台要看看每个Component中的层数是否超过4层的限制。如果超过了4层则需要回到WorldMachine中调节LayerMask,更复杂的混合要在Shader中实现。
Houdini:
1. 在基础地形的HDA中,创建unreal_material节点。
2. 把UE4中复制的材质路径粘贴到unreal_material节点上。
3. 重新导出HDA文件,这样我们在UE4中重新COOK HDA的时候就不需要重新编译许多shader(二次迭代)。
UE4 / Unity:
1. 重新导入新的HDA文件,并recook。这时会自动加载我们创建好的地表材质。
2. 对地表的一些细微区域,使用地表编辑器的笔刷进行调整。
3. 把地表贴图导出到WorldMachine中重新运算腐蚀等效果。(二次迭代) 物体生成概念: 根据游戏世界观来对游戏世界中的一定范围内的植物或建筑进行合理规划,并符合客观规律。其中包括但不限于经纬度,海拔,地质构造,气候等因素。 物体生成线性流程: Houdini: 植物生成:
1. 创建一个node准备点云生成需要的基础数据。首先导入基础地形,然后导入我们需要的地形软件中导出的不同的MASK数据。也可在Houdini的maskbyfeature节点中计算MASK数据并进行混合运算,但是混合层数的比较多后会影响预览速度,所以推荐尽量使用WM等地形创建软件输出。
2. 通过使用heightfield_copylayer节点进行多种MASK预览,一边预览一边使用volumewrangle节点对MASK进行编辑。最终把各种植物所需要的MASK基础数据准备好。
3. 创建一个新的node来准备点云文件。由于大世界地图非常大,导致点云数量级庞大,为了预览方便,我们需要使用tilesplit节点对地形进行切割。
4. 然后我们根据需要生成的点云类型新建几个biome node,每个biome node一类物体,对切割好的tile中进行各种类别的点云生成。
5. 我们需要进入每一个biome node中创建“地表物体计算”节点来生成点云。这个节点是基于《FarCry》和《幽灵行动》等游戏的技术分享来推导实现的功能,其生成方法是通过提取各种MASK的区域进行权重混合计算,并通过互斥算法来实现点云之间的聚落形式,生态竞争关系,具体的细节操作方法的在此不表。
6. 点云生成时我们可以通过把简模赋予点云进行预览。
7. 这里要注意的是,点云生成时实际上单个的美术元素已经准备好了,这非常主要,我们需要把准备好的美术资源在UE4中的命名填写到“地表物体计算”节点中才可以正常读取。
8. 最终通过python代码把物体的 FoliageTypeName/位置信息/缩放信息/旋转信息 写入到csv文件等数据格式。
建筑生成:
1. 导入大量建筑复用模块和挂件。
2. 通过节点来根据形状和需求来拼合建筑模块。
3. 导出建筑。
UE4 / Unity:
大型开放世界项目中,引擎程序员会提供UE4读取csv、json等数据交换格式的插件。我们可以通过插件一次性导入所有植被或物体。
2. 这些生成好的物体可以使用UE4的植物系统进行二次操作,也可以输出为csv等数据格式被Houdini读取。 二次迭代:
当美术或者策划地形有局部的修改的话,大面积的生成还是非常耗时的,很难所见即所得的去修改点云信息。
在UE4或其他游戏引擎中可以使用笔刷对点云生成的文件进行修改。
修改后的文件点云信息出现了变化,需要把这些引擎中的点云信息反导为csv文件。
然后使用Houdini对csv文件进行读取,读取的点云文件作为基础信息生成新的点云,这里的重新生成是分了Tile的。
同理,当修改了道路,河流,地形时,同样需要二次迭代,但是这些信息是导出不了csv文件的。这就需要使用PDG或其他方法集成Houdini的功能到游戏引擎中。
4、开放世界的景观设计与合理性
下面几张图是我实验PCG流程时候,使用虚幻商城资源生成的结果,完全PCG没有任何人工干预生成的效果。还有很多地方需要手动优化,这些手动优化需要很多概念上(地理,生物,美学)的分析过程,而上面操作部分的这些流程我觉得重要性不如我后面要叙述的概念性的内容。
上面的流程如果你已经熟练掌握“道”,成功成为了一个合格的“软件使用者”。
那么流程有了,如何让生成的东西保持美观并且和其他人的作品形成差距呢?
你必须掌握自己的一套理论和审美的框架(“术”),这是我觉得最重要的地方。
过程化内容生成出来的东西的美观程度直接受到这方面概念上的影响,这是我觉得最主要的部分,所以着重讲解一下。由于工作内容敏感度问题,我拿UE4公开的一个官方DEMO《放风筝的男孩》进行讲解。
通过对这个DEMO进行剖析,可以使我们意识到如何使画面更协调和生动有趣。
我分析时没有参考任何文档,他们的植物或许是用虚幻默认的植物生成器生成的,如有雷同纯属巧合。
首先最重要的一步就是必须定义好环境。这一步的定义如果模棱两可会导致很大一部分内容填充前功尽弃或工作上的反复。
查找了很多风景的资料图后,我觉得这个场景一定程度上参考了现实中位于罗马尼亚的Retezat国家公园(下图),具有很大的相似性。
在正式制作之前,首先要对这个场景的地质和生物构成进行了深入的分析,哪些些地方怎么生成怎么制作,哪些地方由于镜头画面需要加入一些奇特的景观。 首先这个Retezat国家公园的景观多样性就非常好,并且很美观,我相信项目区一定对这些美观元素进行了归纳。
这个研究过程使我会在其他任何环境的生成之前,先用这个步骤深入的分析,再进行流程化软件操作。分析透彻,想清楚后,再进行的制作。
这个地形的不同区域划分为以下几种:
1. 山顶区域:由于高度图限制,高度差比较大的地方精度会很低,所以需要插入模型。
2. 悬崖区域:陡坡由于高度图限制,高度差比较大的地方精度会很低,所以需要插入模型。
3. 碎石区域:主要靠点云生成和一定的手摆物体。
画面丰富程度提升(这部分涉及到一部分景观的美学知识):
虚拟湖泊(使用Material制作的伪湖泊效果):
方法:这个地图的基础地貌分为大面积生成和手动景观摆放两种。 基础地形(Terrain & PCloud):
手摆区域:
虽然这是一个大型的在合理规则基础上,带有一定随机性生成出的环境。因为我们的目的是让游戏体验变得美观而不是完全真实,所以在保证合理性的同时,为了画面变得好看,许多部分还是增加了一些的景观设计成分。
长时间在地貌非常统一的大世界中进行活动,会使玩家对于画面产生审美疲劳。这需要专业的美术设计人员根据基础地形进行设计。
景观设计:
如下图中在大世界地形的一块地标性的岩石的风化效果,作者没有生硬的把石柱插入在地形中,在衔接部分增加了一些阶梯状岩石,并在顶部覆盖了巨型石块增加丰富程度。
下图中是表现了在大面积平原部分出现的大型裸露岩石效果,由于自然风化和地质偏移,加入一些岩石会形成崩塌。看起来非常自然。这种景别并不是完全随机生成的。
在景观设计中,经常会植入具有一定美感的植物来打破画面的单调性。比如下面这种树的用法就比较常见。为了表现高低错落还增加了一些岩石。
在美术画面设计中,经常会对画面构成进行一些对比,这样也会大大增加画面丰富程度。常见的有大小对比,形状对比,疏密对比,颜色对比等等。
在单调区域植入个别物体可以打破画面的单调性,并且更加美观。
手动摆放的具有强烈特征的景别。
山顶位置规律(这部分可直接PCG生成,但是这个DEMO中是手动摆放的):
单纯的地表模型非常简单,特别是山顶容易产生光秃秃的效果,除了雪山外的表现力都比较差。
由于高度图的垂直精度问题,对于垂直结构比较多的地方,需要加入模型对画面进行辅助。
这时我们需要获取山体的山顶部分的MASK,用来生成点云对山顶进行岩石模型嵌入。
下图是山顶岩石模型实例。建模时要保证多个方向旋转起来的多样性。
斜坡坐落的岩石群落:
悬崖摆放(悬崖模型体积非常大用于远景还可以):
山体坍塌与碎裂:
山体坍塌后摆放的石头群组:
场景边缘衔接:
点云生成区域(实际上在画面构成中只占有一半或者2/3的空间是全自动生成的):
通过以上分析。可以了解到,这个类似于Retezat国家公园大地形的山体的地质构造是基于岩石的,在巨石表面具有浅层土壤,然后表面长草和少量树林。巨石具有坍塌和裸露的特征。
从多样性上来看,山体和地表本身会覆盖基本的土壤和植被,但大量的地方会有大型山体岩石裸露的坐落在地形外面,这会导致靠近岩石裸露的地方会出现坍塌和悬崖的效果。地表本身除了覆盖植物以外也会在某一个区域(具有一定随机性或美观性)覆盖巨型岩石和小型岩石。这些因素应该是在地图制作之前就应该研究好的。 我们用河流生成举个例子,河流生成时需要了解一些基础的地理知识。然后把这些知识抽象归纳到算法中进行PCG生成或一定程度上的手动摆放。
水系发源区域由于非常浅表,会是岩石裸露小溪的状态。中部区域逐渐由V形过度到U形。下部区域会形成开阔的泥沙堆积区域。 在Houdini中通过曲率运算和样条线操作等一系列算法,最终使用volumevop与地形混合生成的一段河流。很多功能和节点都是现成的,网上也有很多教程,先照着模仿即可,然后总结自己的经验模型,再反推给引擎程序员或高级TA帮你完善功能。还有道路,栅栏等其它功能都是同理。熟练掌握这些工具后就需要结合你的地理学经验来制作比较高端的效果。
同样,山上的盘山道路的生成会依赖于基于斜率的自动寻路功能,还要有自动避开山体、岩石,城市道路避开建筑等物体的功能。
城市的PCG生成也是如此,并且由于人为对环境的随机干扰性太大,所以分析的要更加透彻才行。
再说回PCG工具的迭代过程,在工具处于迭代前期不好用的时候,操作麻烦是工作时的痛点。在轮子不断迭代的过程中,会由TA或TD来处理这部分复杂的操作,充当人肉轮子来操作和维修高复杂度的轮子,组装冗长的轮子流程,并且把功能反馈提供给引擎程序员。当准备好某个方面的程序化生成概念后,需要尽可能的把轮子拆解为非常简单的工程问题,复杂的问题想清楚后往往非常简单。轮子发展到最终阶段会变为易用性非常好的工具,这时就不需要TA或TD了,只是这个过程非常漫长。这个漫长的过程也是游戏工业化持续不断发展的过程。
好久前写的了,虽然有点过时了,先到这里吧。
References:
UE4 - DEMO -《放风筝的男孩》《Procedural Content Generation in Games》
https://en.wikipedia.org/wiki/Diffusion-limited_aggregation
https://cowlevel.net/article/1972042
https://www.cnblogs.com/wang985850293/p/6245716.html
https://www.youtube.com/watch?v=wyUNVSIX1Us
https://www.youtube.com/watch?v=NfizT369g60&app=desktop
https://www.youtube.com/watch?v=YW6htunobNw
https://www.sidefx.com/community/80-level-ghost-recon-wildlands/
https://www.gdcvault.com/play/1025765/https://jennifermoorehead.weebly.com/houdini-procedural-city.html
https://80.lv/articles/procedural-landscape-generation-for-game-environments/https://80.lv/articles/002sgr-generating-procedural-plant-ecosystems/
暂无关于此日志的评论。