c# - 修改噪声函数以具有尖锐的脊
问题描述
生成程序 3D 世界
我正在为 Unity3D 中的游戏生成程序世界。我已经成功地通过几个柏林噪声函数生成了不同高度的地形。
我根据 16x16 块中每个点的 X、Y 坐标对函数进行采样。每个块都是在不知道其邻居的情况下渲染的。
目前,世界是平稳多变的,运行良好,但我正在努力弄清楚如何实现以下内容:
悬崖一代
我正在寻找一种方法来修改我的噪声函数,以便它产生一些陡峭的“截止”,这些“截止”会产生悬崖并可能产生悬垂。
有什么技术可以使这更容易吗?
河流代
我也在寻找创造河流的最佳方式。我相信我将不得不进行第二次传递或创建一个单独的噪声函数,该函数可以在生成时创造出世界,但是当块彼此独立时,我再次在努力实现这一点。
任何指向某些算法或有关如何完成此操作的一般概念的链接将不胜感激。
解决方案
悬垂:Unity 仅捆绑 2D 噪波,但您确实需要 3D 噪波才能正确生成悬垂。您可以将使用 3D 噪声视为每次垂直坐标增加时重新计算高度图。而不是noises(x, y) + const > z ? solid : air
,它变成了noises(x, y, z) + const > z ? solid : air
。有时噪声值会比 z 增加一点点,并导致悬垂。如果 y 是您的垂直坐标,则与 y 进行比较。您可能希望为垂直坐标添加一个额外的频率修改器,这样您就可以改变悬垂的水平以获得正确的结果。
这让我想到了这一点:Unity 的“PerlinNoise”函数不是很好,因为它会生成它的同名(旧的 perlin 噪声),它可以明显地与网格对齐(顶部是 perlin)。通常,我会使用单纯形噪声,以获得更有趣的分布地形特征。我已经将这些公共域噪声生成器类放在一起,其中包括一个 3D 函数,该函数没有其他 3D“单工”函数所具有的一些相同问题。如果 Y 是您的垂直坐标,请使用 Noise3_XZBeforeY,如果 Z 是您的垂直坐标,请使用 Noise3_XYBeforeZ。请注意,输出范围是 [-1,1] 而不是 [0,1]。要直接替换 Unity 的噪声,您可以执行Noise(...)*0.5+0.5
.
每个点生成 3D 噪声,尤其是它的多个八度音阶,可能会很慢。有些游戏使用 trilerp 来降低噪音评估,但我认为这看起来不太好。更好地编写智能代码并且只计算您需要的噪声八度音程。让startingValue = const - z;
, 或 y 如果 y 是您的垂直坐标。如果您正在生成等值面(例如行进立方体),地形看起来可能与计算每个八度音程略有不同,但每个点都将保证是正确的符号(即固体或空气)。如果您正在生成块,则地形将是准确的。
河流可以像您想要的那样简单或复杂。在一个非常简单的情况下,当 2D 噪声下降到接近零时,您可以调整地形(或阈值/起始值,如果使用链接的效率技术)。请参阅噪声比较图像中的第三列。它会创建路径,但您可能会注意到它们只能分成偶数。您可以通过生成三个噪声实例来缓解这种情况,并在一个值与另一个值进行权衡时让边界接近,作为三个噪声实例中的最大值。您还可以使用 F2-F1 蜂窝噪声,由单纯形噪声扭曲。我喜欢采用 3D 蜂窝噪声,并让第三个坐标成为单纯形噪声的输出。还有很多更现实的方法来生成河流,我不会在这里讨论。我自己还没有全部研究过。
推荐阅读
- go - 运行 go build 时出错。带有日志回购
- azure - Azure Rest API 配置详细信息
- c# - OrderBy keySelector 在 TKey 上有不同的数据类型
- python - 如何避免从 PyPI 更新包?
- angular - 访问管理组件正在使用 jwtHelper 在 Angular 中实现基于角色的身份验证
- hive - 有没有办法在 Hive CREATE TABLE 语句本身中为传入数据指定日期/时间戳格式?
- java - 春季启动 && Postgresql
- instagram-api - Instagram 图形 API IG 主题标签
- php - 一种避免在会话和数据库中存储纯文本密码的方法
- php - 无法在端口可用的 XAMPP 上启动 Apache 服务器