读书笔记 PCG in Games 程序化内容生成4 分型、噪声和代理,地形生成

总起

本文主要基于Procedural Content Generation in Games第四章介绍地形生成,给游戏角色提供可以站立的地面。

关于PCG in Games之前的笔记可见:

第一章读书笔记 PCG in Games 程序化内容生成 介绍 - 知乎

第二章读书笔记 PCG in Games 程序化内容生成2 基于搜索的方法 - 知乎

第三章读书笔记 PCG in Games 程序化内容生成3 构造性方法,针对地牢式关卡 - 知乎

本章首先会介绍菱形方块分型算法和柏林噪声,接着介绍基于代理可以创造更复杂的地面,最后介绍基于搜索的算法生成地图和一些具体的游戏元素。

地形无处不在,几乎所有的3D游戏都会提供可以站立或驾驶的地面,并且这些地面都会拥有一些变化,如不同类型的植被、不同的海拔。

在飞行模拟游戏中,地形不需要严丝合缝,但需要巨大的区域覆盖;开放世界,如《上古卷轴5天际》和《GTA》系列,地形扮演了力学和美学的角色;而《光环》和《使命召唤》系列,更类似于我们之前讨论的关卡。

噪声将一些微小的改变添加到表面上(或者一些看起来像是表面的东西),例如天空盒、灰尘、水的某些方面(尽管水的模拟本身就是一个复杂的主题)、火、血浆、皮肤和皮毛的颜色等。还有我们可以将地面的一些微小变化看作噪声,这使我们了解到噪声和地形的联系。

在噪声中使用强度图,在地形中使用高度图,这两种表现形式实际是相同的,都使用二维实数矩阵进行表示,因此任何用于生成造成噪声的方法都可以用于生成地形,反之亦然。

随机地形

我们先考虑生成个完全随机的地形,如果使用高度图,生成的效果像是随机的“钉子”:没有平原、山脉、丘陵或者其他典型的陆地风景。

这种方式最大的问题是随机每一个值都是独立的,而现实世界中,每个点的高度与邻近点是相关。

我们有几种方式来解决该问题,这些方法起初是用来解决计算机图形中纹理碰到的类似问题。

插值的随机地形

使用插值噪声我们可以在更粗的格子上生成随机值,我们随机生成具有一定间距的山峰和山谷,然后填充它们之间的斜坡。

插值方法1:双线性插值(Bilinear)

一种简单的加权平均算法,如果我们选择格子的细节是高度地图分辨率的十分之一,那么高度[0,0]和高度[0,10]将是随机生成的两个值。为了填充高度[0,1],我们注意到它是从高度[0,0]到高度[0,10]的10%。因此我们使用加权平均,height[0,1]=0.9×height[0,0]+0.1×height[0,10]。一旦我们完成了x方向上的插值,就继续在y方向上插值。

这种算法有其缺点,山坡变成了完美的直线,山峰、山谷都是完美的尖点。这通常不是我们想要的,角色可能被卡住。

插值方法2:双三次插值(Bicubic)

当一座山脉从山谷升起,一个通常的方法是产生一个s曲线。首先斜率上升的比较慢,在移上山脉过程中它变得陡峭,最终它在顶部趋于平缓,形成一个圆弧形的山峰。

因此我们需要一种非线性插值:s(x) = -2×x^3 + 3×x^2。比如x = 0.1,s(0.1) = 0.028,最终height[0,1] = 0.972×height[0,0]+0.028×height[0,10]。

基于斜率的随机地形

直接随机高度图太随机了,而另一个想法是直接生成斜坡,并从中推断高度值。这种数组的随机初始化称为梯度噪声,它最初是由Ken Perlin在他1982年电影《Tron》的工作中完成的,所以有时被称为柏林噪声。

生成梯度有几个优点:

  1. 拥有了额外的平滑度;
  2. 平滑高度的变化速率,斜坡可以平滑地变浅或变陡;
  3. 梯度噪声允许我们使用基于网格的生成(这是计算和内存高效的),同时避免了基于插值方法产生的矩形网格效果;
  4. 生成效果显得更有机的方式排列。

步骤:

  1. 首先我们可以生成一个2d向量(dx, dy)代表x、y方向上的斜率;
  2. 然后我们将还原高度,找到四个相邻的点分别进行计算:dx乘以离选择点的x距离,y方向上进行同样的计算(算是一种点积);
  3. 分别获得四个邻点的高度值后,使用双线性或双三次进行插值。

分型地形

基于斜率的方法仍旧有一些不自然,它是以恒定的频率波动,没有真实地形的多样性:平原隆起山脉、山脉中有山峰和山谷、山谷又有丘陵和沟壑。

事实上,当你缩放很多自然现象时,你会看到相同种类的变化,这种自相似叫做分型,而使用这种属性生成的地形叫做分型地形。

分型地形可以使用多种方式表示,一些使用分型数学,而另一些通过更简单的方式产生类似的效果。

比如1/f噪声,如果单一噪声算法为noise(f),我们定义1/f噪声为noise(f) + (1/2)*noise(2*f) + (1/4)*noise(4*f) + ...

Musgrave等人写了一本书专门介绍这个主题,他们将其分为五类技术方法,它们都可以被视为分数布朗运动(fBm)。

游戏中最常用的是菱形方块算法(Diamond-square)

  1. 菱形步骤,找到4个角对应的正方形中心点,设置高度为4个角的平均值并加上一个随机值;
  2. 方块步骤,找到4条边的中点,设置高度为周围3个点的平均值并加上一个随机值;
  3. 重复以上过程,直到达到最大的迭代次数。

最终结果是fBm产生地形的近似。

基于代理的风景创建

前面讨论的方法满足PCG算法所期望性质的大部分,但它们不太可控,使用代理的优势主要在于,在保持PCG方法所理想特性的同时,它们提供了更大程度的控制。

Lechner等人创建的基于代理的城市生成。城市被分为了好几个区域,比如广场、工业区、商业区、住宅区。不同的代理承担不同的工作:

  1. 拓展者寻找城市中未连接的区域;
  2. 连接者增加了高速公路和道路之间的直接连接;
  3. 其他额外类型的代理,用于建设主干道和小街道等任务。

Doran和Parberry聚焦于可控性不够的问题,并给分型方法提供更多的控制。

设计师拥有多种方式去影响地形的生成:

1. 控制代理的数量;

2. 控制代理的生命周期。

代理影响环境的主要任务:

  1. 海岸线,使用多个代理生成地形的轮廓和形状;
  2. 地形,使用更多的代理设置山脉细节、创造海滩和塑造低地;
  3. 侵蚀,根据之前地形生成河流,河流的数量来源于代理的数量。

主要的五种代理:

  1. 海岸代理,将海平面下的地形抬高到海平面上;
  2. 平滑代理,消除地形高低的快速变化;
  3. 海滩代理,沿着海岸线移动在靠近水域的地方创造沙质区域;
  4. 山脉、山丘代理,随机移动遇到V型楔形点时抬高形成一个山脊,随机转弯使路径曲折,并周期性的形成山麓;
  5. 河流代理,随机两个点一个在海岸线另一个在山脊上,从海岸线出发沿着斜率向山脉移动,到达山脉后向下挖掘河流。

基于搜索的地形生成

以上两类生成地形和噪声方法有一定的好处,但在一定程度上缺乏可控性,而基于搜索的方法可以指定约束条件或理想属性,比如区域中高度变化不超过某个最大值,或者一个地形上的两个点应该很容易到达彼此等。

地形的遗传规划(GTP)

表型是一个高度图,基因型是遗传规划中的表达式树。

比如使用前缀表示一个表达式:(+3(*5 2))(中缀表达:3+5*2)。表达式树以+为根节点,3和*为子节点,+和*是算术函数,常量被称为终端。进化搜索通过添加和交换函数、终端,以及重组不同树的部分来进行。

GTP:

  1. 函数集通常包括算术函数和三角函数,以及指数函数和对数函数;
  2. 终端集包括x和y位置、标准噪声函数(如柏林噪声)和获取离地图中心距离的函数。

GTP进行基因型到表型的映射时,迭代通过输入x、y参数获取高度图,这种表示还允许无限的可伸缩性(或缩放),因为增加分辨率或扩展地图仅仅意味着使用新坐标作为输入查询程序。

在最初的实验中,使用了交互式评价,由用户在展示的地图中选择用于生成下一代的地图;后续探索了各种直接评价函数,如易用性、避免完全平坦,下图显示随着GTP演变的景观例子:

 

简单的RTS地图生成

Togelius等人为实时战略游戏生成一个平滑变化高度的地图。

表型包括高度图、资源位置和基地起始位置;基地和资源位置直接表示为极坐标;后续添加了一些山丘,用简单的高斯分布表示。

定义了三种不同的评价函数,其中两点与基地和资源的放置有关以创造一款公平的游戏,而第三点则与地图的拓扑不对称有关。考虑到三个适应度函数存在部分冲突,采用多目标进化算法对三个适应度函数同时进行优化。

 

总结

地形的两种表示方式:高度图和斜率图。

高度图中使用插值技术能够很好的平缓地形;斜率图中使用分型方法,包括各种类型的噪声,菱形方块算法是游戏中常用的算法。

对于更复杂的环境,可以使用基于代理的方法;如果存在约束,则基于搜索的方法可能会有用。

参考

《Procedural Content Generation in Games》

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值