以下文章来源NExT Studios ,作者引擎全开的
“生成过程内容也称程序内容生成(Procedural Content Generation=PCG),是一种自动为游戏、模拟或电影创建数字资产,它可以大大提高内容生成的效率。
NExT Studios 用虚幻引擎4开发《重生边缘》(SYNCED:Off-Planet)在这个过程中,我们在过程生成场景中做了一些尝试:除了介绍各种生成内容的想法外,我们还分享了如何加入场景制作后的过程生成工具解决新工具在实际工作中遇到的各种问题,分享一些实验性工作。
主地图《重生边缘》
主地图曝光!一开始只有三个场景艺术。作为一个中途加入者,你会遇到什么问题?如何提高过程生成工具的工作效率
主地图3x3公里,大约有 20 个 POI、16 层层表面,9000多棵树,300多种植被,20公里长的 路和6公里长的 河流。起初,除了Unreal Editor此外,我们在添加过程化生成内容时没有过程化生成的积累现有 不能覆盖prototype 关卡,同时需要兼顾关卡艺术和关卡策划的操作习惯(他们在Unreal Editor数据编辑工作,但过程化生成算法是在Houdini实现时,需要导入导出数据),每个生成元素之间有一定的数据依赖关系(例如,河流变化会影响地形的高度图和材料层,地形高度图的变化也会影响植被的分布等。......我们面临着许多挑战。
由于场景中的每个 ,我们开发了大约30个工具POI 的风格和设计非常不同,很难提取统一的理性规律,所以工具的目的是调整关卡布局时,加快修改周围环境,大部分生成内容集中在野外区域。
场景结构
如何计算表面材料层的权重分布?
把mask侵蚀美化是地形转化后的基本功能。侵蚀会改变高度图的性能,并产生表面材料层的权重分布。
地形对比前后侵蚀
地表权重图是在Houdini计算的一般原理是:根据高度图的斜率计算一般分布,然后配合雨水冲刷等效果,根据每层石头和沙子的规则,定义不同的权重图,然后导入引擎,以获得良好的混合表面效果。
混合地表效果好
如何生成垂直表面的悬崖岩石?如何在地表上呈现更丰富的细节?角色卡住mesh如何处理里面?
当时我们参考了一些行业资料,比如《孤岛惊魂5》(Far Cry 5),刺客信条(Assassin's Creed)。一开始,我们根据地形的坡度将其区域提取成mesh,然后生成UV,贴上我们想要的纹理后,用displacement map模拟岩石表面的凹凸,但近距离效果不理想。所以我们尝试了另一个方案——mesh贴片。像瓷砖一样,固定mesh重复粘贴到所需区域,这样可以用较低的面数达到更好的效果,因为它的几何细节会更多。
mesh贴片效果
产生悬崖的mesh悬崖下方和与表面过渡的地方可以用类似岩石纹理的表面材料来表达,从而产生相应的表面材料权重层。岩石和表面的过渡也需要处理:生成mesh将权重写入顶点色,然后采样地形纹理进行柔和过渡。我们可以在岩石下产生一些碎石或砂石,这样会有更详细的表现。
细节前后增加岩壁对比
在实际应用中也会遇到一些尴尬的问题,比如人物有时会卡在生成中mesh这是因为Unreal不规则mesh默认产生的碰撞体有很大的缺陷,此时我们将针对这些非闭包类别mesh产生特殊的碰撞体,然后一起导入发动机。
如何计算视觉均匀的植被分布?如何考虑植被间距?如何撒点?
参考《孤岛惊魂5》(Far Cry 5),这几乎是业内最详细的分享。我们的整体生态和植被组成是不同的。我们选择温带针叶林。具体做法是根据高度图生成各种mask,配合噪声模拟随机分布。我们可以考虑光线、风向和气候的影响,产生更多mask,通过运算得到我们想要的分布。
有了植被区,我们可以在区域内撒点:一种操作是直接在区域内随机撒点,另一种是在目标点周围随机撒点。我们可以在第二种情况下生成伴生灌木,通常我们不能一次只生成一种植被。
两种撒点方法
我们为每种植被定义了三个半径,以防止树木之间的重叠。根据这些规则,我们量化了这些点的位置,使更近的点更容易判断。如果这些点被包围,我们不能移动来消除它,我们就删除它。
通过这种不断的迭代,我们可以得到非常均匀的效果,而不是相互穿插。但在不同的树种之间(如高树和低灌木),这就是为什么我们定义外半径和内半径。对于地图上的不同区域,将会有不同的生态分布。我们可以通过全地图刷mask区分我们每个部分使用的生成规则。比如在海边,我们会以一些草沙为主,山上以森林为主。
如何形成河流?如何处理下游高于上游?如何平稳处理转折度大的河流?生成河流后,如何调整表面的纹理细节?
在《重生边缘》中,河流是一种表现效应,不影响游戏玩法,所以规划和艺术不想要太高的高差和太深的水面,所以我们想做一条很浅的溪流。我们还学习了算法中的地平线(Horizon)整个生成过程大致分为:
? 我们首先有一个大致的曲线,根据地形高度图自然滑动。相当于把绳子扔在地表上,它会自然弯曲;
? 有些地方地势较高,我们可以挖一条河,这会改变地形的高度;
? 当我们从高地向低地过渡时,我们需要形成多层次的小瀑布,因为我们不想产生太大的高差。
? 然后我们根据河流的地形分布和弯曲度,产生河流宽度的变化。
? 最后,我们在河里撒上一些碎石和水花来装饰,生成河流的流向。
河流生成过程
河流产生的其他问题:
? 支流可能与主流不同,我们需要对齐高度;
? 下游可能高于上游高度,此时需要用下游高度修正上游;
? 转折度较大和多个支流交叉的区域,我们不可能生成很多层的河面的mesh,因此,进行平滑处理,从平滑的河流形状中提取河流,然后对河流进行处理mesh进行切割和减面,这样对性能的优化很有帮助。
如何减少河流流向图的内存占用?如何编辑河流的方向和效果?
对于河流的流向图,如果使用全地图flow map如果一个纹理被覆盖,它会浪费很多UV空间。考虑到性能更高,内存占用更低,我们只需要信息写到顶点色,只需要占用两个通道。
生成河流后,地表的纹理会发生变化。我们可以铺鹅卵石,或者在河岸边缘产生湿沉淀物增加河岸性能,产生相应的植被分布增加细节等。
我们使用Unreal Landscape Spline的内置功能编辑河流的曲线,因为它更符合艺术的操作习惯。我们先拖出河流经过的区域,然后编辑每个支流的一般路径,设置每个支流的起点,然后一键生成。此时,我们可以根据地形进行自然弯曲,挖出河流,产生表面纹理,产生河流mesh,还有流向河流的数据,包括水花、石头等。
如何实现裂缝长草、土路破损、路口过渡、车轮印记等道路上的细节加分项?如何制定多层贴花的优先级?
游戏中的道路基本上是在编辑关卡规划,这对游戏玩法有一定的影响。当我们加入生成工具时,路网已经完成了大约80%或90%,所以我们选择添加一些细节加分项,而不是生成道路本身的路网。如裂缝草、道路损坏、不同道路之间的过渡、交叉口的车轮标记等。
实现的思路是使用海量贴花(在 GDC 2017 的 Ghost Recon Wildlands: Terrain Tools and Technology 有类似的共享)来实现,包括道路损坏、道路中间的车轮印刷、车道标记、水痕效果、路边落叶的灰尘效果,都是通过贴花来实现的。但裂缝中的草不是贴花,而是在生成裂缝贴花时计算裂缝草的位置。
还有一个更实用的功能,使用Unreal Landscape Spline在道路上不能很好地处理交叉口,我们生成了任何角度交叉口的贴花,它掩盖了连接处的接缝问题。
十字路口贴花
有了多层贴花,我们需要定义呈现层次的优先级,所以我们制定了同级融合,低级高级覆盖贴花规则。半透明材料的贴花数量加起来有几万个,很重overdraw,会带来非常严重的性能问题。所以我们使用了 Unreal 的Runtime Virtual Texture 优化,将地表与道路和贴花混合的结果缓存到巨大的虚拟纹理中,可以大大降低地表绘制的成本。
另外,我们计算完道路曲线后,表面的权重分布可根据道路曲线的分布进行调整。例如,我们可以在道路周围产生相应的表面过渡效应(裂缝、草、灰尘损坏、水迹、十字路口车轮标记),以及道路附件(如护栏、电线杆)等。
如何解决新工具在实际工作中遇到的各种问题,分享更多实验工作,请期待下一次推送!