GDC翻译:Far Cry 5 的程序化世界生成(第三部分:7-生态工具(Biome Tool))

本文深入探讨了生态工具在游戏世界生成中的应用,包括如何利用地形数据、生物生存能力、年龄、密度等因素,实现自然生态的细腻分布。通过主生态与子生态的设定,结合地形变形、纹理混合等技术,创造出丰富多样的生态环境。此外,还介绍了如何处理实体对地形的影响,如地形变形和纹理输出,以增强环境的真实感。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

下面来看生态工具(Biome Tool)。这个工具的目标是用生物内容填充整个世界。
在这里插入图片描述

容我说一下,这可能是本次演讲中最大的部分了,有太多的特性需要涵盖。主要是因为自然界有很多微妙之处 ,我们也想复现出很多现象。
在这里插入图片描述

输入:地形的非生物数据

所以,在生态工具中我们第一步是从高度图生成地形,很简单。
在这里插入图片描述
然后从地形拓扑中,我们生成非生物数据,基本上就是地形的物理特征:
在这里插入图片描述
其他的比如海拔、经纬度,还有风的方向图。
需要注意的是,这里的地形属性会成为大多数生态工具的支柱。

输入:其他2D数据

然后,我们导入了其他 DUNIA 为我们提取到硬盘上的数据:
在这里插入图片描述

我们有用户画的 Biome Painter 数据。还有之前程序化工具生成的所有数据,比如活水、路、围栏、电线杆、崖壁。

这样我们就准备好做些有趣的事情了。

处理主生态

首先,生态工具所作的并不是简单地在用户绘制的地方生成东西。我们有所谓的主生态子生态
在这里插入图片描述
主生态覆盖了世界大部分地区,约占 75% 至 85%。主生态将根据非生物地形数据,来自动处理子生态应位于何处。

正是工具的这一部分为我们提供了生态分布中看起来很自然的宏观细节。
在这里插入图片描述

主生态还处理其他杂事,例如用户放置电线杆的地方,需要将森林替换成草地。
在这里插入图片描述

子生态配方的结构

在上面的过程之后,我们就有了 “子生态配方”。
在这里插入图片描述

它们是处理链,每一个都包含了所有用来定义这个配方的配料,比如树、树苗、灌木、草、等等。

然后,在这些配方的节点中,当然都有用来生成实体的HDA。它们会做植被的散布,也可以修改或创建地形属性。
在这里插入图片描述
但一个关键的地方是,它定义了每个物种的生存能力

生存能力

每个物种都在为自己的地盘而战,以求生长和繁茂 。“生存能力”是通过为每个物种设置有利地形属性来定义的。累积生存能力最高的物种将战胜其他物种。
在这里插入图片描述
举个例子,我们有个物种A,它喜欢在 Occlusion 地形数据是这个范围内的地方生长,力量是 1:
在这里插入图片描述
因此物种A喜欢的范围是这样:
在这里插入图片描述
如果没有其他物种与其竞争,它的生长情况会是这样:
在这里插入图片描述

然后我们有个物种B,它喜欢在 FlowMap 地形数据是这样的范围内生长,力量是 2:
在这里插入图片描述
因此,物种B喜欢的范围是这样:
在这里插入图片描述
由于它的力量比A高,所以在 FlowMap 地形数据达到指定值的时候,物种B将会战胜物种A,最终生长成这样:(深绿色是B)
在这里插入图片描述

但要决定谁是优胜物种,还涉及到半径的判断。
在这里插入图片描述

这里,我们的物种A比物种B有更高的生存力。我们可以看到地形上表示半径的颜色,如果物种B在物种A的半径内,那它将会被移除,就像那棵红树。

通过这种方式,我们很好地避免了树与树之间的间距。然而,如果我们想要灌木丛或者草就长在这些树的下面,而不希望被移走,那该怎么做呢?对于这个问题,我们还有一个 “优先级半径”。
在这里插入图片描述

优先级半径会被计算。如果优先级相同,再计算生存力。
我们继续之前的例子。不过,我们的物种A的优先级半径要比它的生存力半径小。所有树的优先级都是10。然后我们添加了优先级是 0 的灌木丛(黄色)。灌木丛被允许生长得靠近物种A(绿树),因为物种A的优先级半径较小。但灌木丛仍旧会对物种B保持一定距离。

组合地形数据

我们已经看到了生存能力扮演了一个很重要的角色。而现在我们来看看一些自然现象。
在这里插入图片描述
左图中我们可以看到,陡坡上,没有植被在FlowMap的线中生长。右图中,可以看到山的南面几乎没有植被生长。

所以,为了模拟类似的现象,我们需要能够将不同的非生物地形数据组合在一起。
通过混合各种地形属性,我们可以为物种分布创建非常特定的图案,也添加了一个变化的(fluctuating)生存力。

一个例子,这里我将 Occlusion 和一定范围的海拔相乘:
在这里插入图片描述

与此同时,我们还可以将FlowMap和另一个范围的海拔相乘:
在这里插入图片描述

然后,我们可以将前两者的结果相加:
在这里插入图片描述

另外:
在这里插入图片描述

然后:
在这里插入图片描述

最后,它将用来计算生存能力
在这里插入图片描述

尺寸

不过,生存能力还驱动了其他的东西,比如尺寸
在这里插入图片描述

如果我们退一步看,其实有很多因素会影响树的大小
在这里插入图片描述

还有其他因素也起作用,比如海拔也会影响树的尺寸。
在这里插入图片描述

那么我们该如何管理不同尺寸的资源呢?
——我们将资源尺寸选择与我们的生存能力联系起来!
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

然而,这样做我们得到了一个问题——楼梯效果:
在这里插入图片描述

缩放

为了消除这种情况,我们允许每种尺寸可以按一定比例放大或缩小,来补上尺寸之间的差距。
在这里插入图片描述

然后,作为一个扩展选项。我们也可以使用随机比例,这样能在不过多地弄乱生存能力数据的情况下,来制造更多混乱。
在这里插入图片描述

当然,两棵相同尺寸的树并不一定是一样的。我们可以有几个变种。
在这里插入图片描述

在这个例子中,我们有“死树”变种。我们用概率来改变死树的比例。

年龄

让我们再回头看看另一个现象。
在这里插入图片描述

我们怎样才能做到这一点?

首先,我们已经看到了生存能力是如何影响树尺寸的选择的。然而——
在这里插入图片描述

然后我们有多种选择来控制年龄对尺寸分布的影响。我们可以让它与生存力进行相加、相乘、或插值。
在这里插入图片描述

所以我们可以很容易调整它的影响程度,就像这样:
在这里插入图片描述

通过调整年龄的最大距离,我们可以控制森林边界的深度。

另外作为一个附带效果,我们可以使用曲线来控制年龄,以此来创建出我们想要的森林形状的轮廓。
在这里插入图片描述

密度

还有一个重要的东西我们需要控制,那就是散布的密度。

如果我们的密度一样,那么我们的小树之间可能有个很好的间距,但此时我们的大树之间会有糟糕的重叠。
在这里插入图片描述

当然,我们生成的资产也和性能有关。那些小树的GPU消耗和大树是不一样的,所以对它们进行严格的控制是很重要的。

一个简单的曲线就可以控制了。默认情况下,密度的变化是基于物种的尺寸的。
在这里插入图片描述
然而,在没有尺寸的情况下我们也有其他选择,比如用年龄或生存力来控制。

然后,我们还可以混合地形属性,比如照明或者说斜坡角度,来影响物种的密度。
在这里插入图片描述

游戏中的样例:
在这里插入图片描述

实体颜色

现在来看另一个功能。我们想要在生物群落中重现多种颜色的变化:
在这里插入图片描述

在上面的参考图片中可以看到灌木和草的颜色是变化的。

所以为了做到这一点,且不复制我们的纹理或材质,我们有对散布的instance逐个染色的操作。
在这里插入图片描述

驱动颜色的输入值可以是生存力、年龄、或任意地形数据的组合。在这个例子中,我们使用的是水的有向距离场,为的是给生长在湿地上的草进行染色。

下面就是游戏中的结果。
在这里插入图片描述

这就是草的颜色变化的来源。

旋转

散布的实体也需要有自己的旋转,默认情况下,它们的前向轴朝向地形坡面 。
在这里插入图片描述

这一点很有趣,因为它让我们可以做一些事情。比如我们可以做一个左图这样的资产,让它始终朝向水——由于坡度的关系。
在这里插入图片描述

另一个例子是斜坡上预先弯曲的树干。
在这里插入图片描述

不幸的是,我们并没有在游戏中这么做,虽然我希望我们做了,因为它很酷。但我们其实可以实现这样的系统。

我们还做了一些很酷的事情。我不确定如果我没提及的话,是否有玩家在游戏中注意到,我们在这里看到的草资产,它是朝向风的向量场的。
在这里插入图片描述

这是我们朝向的另一个选项。风图基于整体风向,但也会根据地形形状略有波动。所以虽然可能有点不好看出来,但是当吹在山上时,它会倾向于围绕它流动。
在这里插入图片描述

下面来补全我们有关旋转的选项。

在所有情况下,资产可以选择水平或与地形坡度对齐,这是个可控的百分比。
在这里插入图片描述

我们在所有轴向上都一个抖动,我们经常在植被上应用。
在这里插入图片描述

散布实体对地形的影响

现在,我们已经涵盖了大部分用来控制实体生成的参数了。

然而,观察自然:
在这里插入图片描述

所以为了在我们的系统中做这件事,当实体分布后,我们可以选择将一些数据从散布的实体传输回地形。我们用这个过程做四件不同的事:
在这里插入图片描述

  • 地形变形,基本上就是影响高度图。
  • 地形纹理
  • 地形数据输出,它是一个mask,可以被后续的物种使用。
  • 地形颜色,它就是一个可以用地形纹理混合的东西。

它们四个都是相互独立的。

地形变形

我们以地形变形为例。我们可以从实体位置中生成一张mask。
在这里插入图片描述

我们还可以选择将它与之前我们看到的那些地形数据相结合。例如,我可能会想要mask出所有靠近道路的地形改变,因此我就要用到道路mask。有了mask之后,我们可以设置位移为 1 ,这样就会将相应地形升高 1 米。

这是我们从用户角度看到的信息:
在这里插入图片描述

我认为这是一个非常有趣的特性,因为在当下大多数游戏中,树只是立在地形上,它们对周围的地形没有任何影响,但是在自然界中,树根会稍微抬起地面,并将土壤固定在一起,从而限制侵蚀。这会在树干周围创建这些拔高的形状。

地形纹理

现在让我们仔细看看那些树根,我们想让它们与地形无缝融合。为此,我们需要根据需求生成匹配的地形纹理。
在这里插入图片描述

同样,我们从散布的实体中生成一个mask。
在这里插入图片描述

  • 首先我们设置想要从这个mask中生成的纹理数量。
  • 从下拉菜单中选择期望的纹理,它会通过python从编辑器中取得可用的地形纹理。
  • 然后,我们的mask灰度值将会决定在哪使用哪个纹理。这里,我们设置第二个纹理将会出现在 0.5 及以上的位置。

一旦纹理ID被发送到了编辑器,我们就会得到相同的结果:
在这里插入图片描述
现在,我们的根和下面的地形很好地融合了:
在这里插入图片描述

地形数据输出

接下来,或许我们想在这些树周围添加额外的配料。

所以我们能做的就是,从树中生成一个新的地形属性。但这一次,这个mask将会被存储到地形上,为后续物种计算生存力时使用。
在这里插入图片描述

一旦我们设置好了,我们就可以转到下一个节点,比如这里的Forest_Rocks
因此,这个资源将使用之前节点生成的 ponderosa 这张mask来作为生存力。
在这里插入图片描述

最后,我们得到了这些散布在树周围的物体。因此这些物体的位置总是会与其他物种联系在一起,所以这是相当方便的。
在这里插入图片描述

如果我们返回ponderosa_Trees这个节点,我们还可以为物种输出一个年龄数据。
在这里插入图片描述

比如,它能让我们,仅在森林的边缘生成东西:
在这里插入图片描述

另外,如果你们还记得之前看到的“生态交替”现象。我们可以用它来创建生长年轻植被的效果。
在这里插入图片描述然后,我们就会继续添加更多的原料,来构建一个完整的配方:
在这里插入图片描述

在游戏中,一个一平方公里的地图上生态工具生成了超过 六十万 个实体。在FarCry5中,我们总共大约有70个这样的地图。
在这里插入图片描述

地形颜色

最后一个特性。
这是一个谷歌图片,这里有我们感兴趣的现象:
在这里插入图片描述

地形的湿度。颜色在干燥的棕色和郁郁葱葱的绿色之间变化。

正如之前所说,我们为崖壁生成了地层颜色。而在生态工具中,我们也生成了一张地形染色纹理。
在这里插入图片描述

它们会与我们的地形纹理分布混合在一起。这在给了我们更多的变化的同时,也限制了我们需要在游戏中用的地形纹理的数量。

需要指出的是,我们颜色层的中性色是平均的灰色,这让我们可以对地形纹理进行变暗或变亮。

这是游戏中镜头拉远看的效果:
在这里插入图片描述

你可以看到由生态工具生成的纹理和颜色变化。

另一个值得一提的是。所有地形纹理和程序化染色,都可以传递给草,这是因为草的着色器可以拾取地形颜色。
在这里插入图片描述

同时,它拾取的量也可以用一个mask来控制,或者草资源自身来控制。所以它可以选择100%拾取地形颜色,或者只是作为一个梯度,或是只在植物的特定部位。

导出

最后,这是导出到编辑器中的数据:
在这里插入图片描述
其中,森林mask将之后被雾工具和WorldMap工具所使用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值