首页
学习
活动
专区
圈层
工具
发布

脊线叠加生成地形,一种可规划的随机 3D 地形生成方法

当我们观察任何一片地形,总是能看到最基础的两种走势:山会凸起,河/谷会凹陷。地形本身就是一个平面叠加了许多不同的凸起和凹陷后的产物。

对于稍微微观的一块地形的地貌特征来说,山和谷的走向往往是纯粹随机的。我们常用随机的 2D 噪声图谱去模拟这种随机,赋予一个噪声图不同的处理语义,使之成为完善的地形。常见的噪声图和它对应生成的 3D 地形就能完成这种操作:

噪声图及其对应的 3D 地形

噪声的原理是用灰度标定海拔,将网格拉到对应的高度,实现地形起伏的连续变化。模糊的噪声自带高对比度边缘的平滑过渡,因此能生成连续不跳变的地势起伏。

在我的实际使用过程中发现,这种方法有个弱点:对于大尺度地形地势的总体走向和小尺度地形下的地形单体,由于噪声平滑且一次性生成的特点,比较难规划出连续的长限地形(一条贯穿大陆的连续山脉、一条漫长的河谷、西高东低的走势等);同一种方法生成的噪声图,当尺度扩大或生成次数增加时,也更容易看到其出现随机模式上的重复。

同种方法随机种子生成的多个地形

在和 Agent 讨论一整天之后,我们共同提出了一种新的方法,用于解决以上提到的小问题。

方法的核心是围绕“地形由无数凸起和凹陷叠加而成”的定义,在平面地形上放置数条有方向的线,通过线的走向来规划其周围地面的起伏。此处称这些线为脊线或地形骨架。

脊线是一串按顺序排列的点所连成的折线应用平滑后得到的结果。它带有两个决定其表现形态的基础属性:一是在二维地面上的走向(二维平面上的一条线),二是在垂直方向上的高度(注意,高度是整条脊线统一的高度,并非分别赋予生成脊线的点独立高度)。

除了这两个属性,脊线还可以添加长度、强度等多种参数进行精细控制,长度可以决定其在平面上延伸的范围,强度可以决定其对网格顶点影响的力度。

一个平面上随机取点连线

对于平面地形上的所有网格点最终落在三维空间上的具体位置,只需要设定一个方法来确定——离网格点最近的脊线在哪、离它有多远——即可用很简单的公式叠加得到一个确定的结果。我们生成的脊线在视觉上是 2D 的,但实际上存储了高度信息,网格顶点接近某条/某几条脊线时,就受那些脊线的垂直方向更剧烈的影响;反之,影响就随距离收敛、直到归零。把能影响到一个点的所有脊线的贡献直接相加(或加权计算),就可以得到连续平滑的、该点的高度。

脊线与其对应的 3D 地形,其中橙线代表正值(山脊),蓝线代表负值(山谷)

之所以说它解决了前面提到的小问题,是因为脊线本身是一个连续有方向、可控形态的实体,这相比于孤立的采样点和块状的噪声来说,更便于规划和控制单体地形的形态。同时,在绘制脊线的过程中可以添加各类控制方法(随机分布的方法、用函数生成线形等),也能简单地规划出效果很好的地形走势。这种可控的绘制线的方式也极大程度避免了噪声图一次生成带来的局部难调、模式周期性重复的问题。

此方法随机种子生成的多个地形,尺度更大

总结来说,采用这种方法生成地形的步骤如下:

获得一个用于生成地形的基础面;

生成蜿蜒游走的脊线,给脊线赋予长度、高度、强度等属性;

对于地形上每一个网格顶点,找到离它最近的脊线,将这些脊线对网格顶点位置产生的高度影响加权叠加、距离影响下的衰减叠加,获得这个点的最终高度;

把算好的高度场建立成网格,即可获得基础的地形起伏。

我们仍然可以通过叠加限制、添加方法来以噪声图实现观感极佳的地形,噪声图生成仍然是非常性能友好的地形生成选择。但当你对想要的地形有大体想法和概念时,不妨尝试本文提出的方法,也许会比噪声图抽卡更快捷地实现你想要的效果。

根据这个方案制作的地形生成器及相关代码开源在此:

https://github.com/Yosmos0427/3d-terrain-generator

* 本文为用户投稿,不代表 indienova 观点。

  • 发表于:
  • 原文链接https://page.om.qq.com/page/OSBNvnZgT-Fr2bpsbb9qT1Dw0
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

相关快讯

领券