欢迎光临散文网 会员登陆 & 注册

使用 WorldEdit 快速塑造空岛底部形状

2023-08-09 18:10 作者:参门  | 我要投稿

前言

  撰写本文出于 TeaCon 2023 展馆建设的实际需求。由于场地的初始状态是完美的虚空,视情况,可能需要建设浮岛使建筑有所凭依。

  我将介绍一种使用 WorldEdit 的 //generate 指令快速塑造空岛底部形状的方法。需注意:

  1. //generate 指令用于从无到有地生成结构。因此,如果您的空岛已经存在,只是尚无继续雕琢的思路,本文恐怕帮不上什么忙。

  2. 使用本文方法生成的,或可称为「刻板印象中的」空岛底部,整体上是一座倒悬的、有随机起伏的山峰,虽然不同参数设置可能对结果有巨大影响。

  3. 只有形状是本文关注的主题。使用材料、后续的修葺与装饰皆取决于您的审美。

前置知识

  //generate 指令的使用方法是://generate <图案> <表达式> //generate 可缩写为 //g

  为方便起见,本文总是使用石头(minecraft:stone)传入 <图案> 参数。

  对于选区内的每个位置,其坐标的 x, y, z 分量会传入 <表达式> 进行计算。若返回结果为真,则在该位置设置方块。

  默认情况下,每个位置的 x, y, z 并非它们在世界中的坐标,而是线性映射至 %5Cleft%5B-1%2C1%5Cright%5D%5E3 范围内的坐标,即矩形选区八个顶点的坐标可认为是 %5Cleft(%5Cpm1%2C%5Cpm1%2C%5Cpm1%5Cright) ,且原点位于选区中心。这些默认行为可以修改,但这并非本文讨论的范围。

指令模板

  本文使用如下形式的指令创建空岛底部:

  //generate minecraft:stone n = perlin(<种子>, x, 0, z, <频率>, <倍频数>, <持续度>); r = 1 - <缩放函数>; -y < <放大倍率>*n*r - 1

  以下是一个可用的例子:

  //generate minecraft:stone = perlin(435, x, 0, z, 2, 2, 0.75); r = 1 - (x^2 + z^2); -< 2*n*- 1

上述指令生成的形状


  下面将分解该指令中表达式的构造过程,并逐参数讲解。

利用柏林噪声生成随机起伏的地形

  让我们从生成一片上表面的起伏地形(类似山地)开始。WorldEdit 提供了 perlin 函数生成柏林噪声,为生成简单的随机起伏地形,可以使用:

  //generate minecraft:stone = perlin(0, x, 0, z, 1, 1, 0); y < n - 1

上述指令生成的形状

  perlin 的第一个参数是 <种子>,相同的种子总是给出起伏模式相同的地形。可多加尝试,找到最符合需求或观感的种子。由于 perlin 返回的值大部分落在 (0%2C1) 范围内,暂且在最后将 n 的值减去 1,使地形的起伏程度相对整体高度更明显。

  perlin 的第二个至第四个参数,此处使用了「x, 0, z」,指示该噪声是二维的,与 y 无关。这保证产生的地形不会包含空中连廊或者洞穴等结构。0 也可改成其他常数。

  第五个参数,称为 <频率>,决定了噪声地形的起伏有多密集。<频率> 的影响见下图。

噪声部分:上图 perlin(0, x, 0, z, 1, 1, 0);中图 perlin(0, x, 0, z, 2, 1, 0);下图 perlin(0, x, 0, z, 4, 1, 0)

  第六个参数称为 <倍频数>。通俗而言,倍频数若为 n,则意味着将会额外产生 n-1 个更高频率的小噪声(「倍频」)叠加在原始的噪声上。这些小噪声会增加地形起伏的细节,<倍频数> 越高,地形越具备更细碎的分形特征。<倍频数> 的影响见下图。

噪声部分:上图 perlin(0, x, 0, z, 1, 1, 0.5);中图 perlin(0, x, 0, z, 1, 2, 0.5);下图 perlin(0, x, 0, z, 1, 4, 0.5)

  最后一个参数称为 <持续度>,仅在 <倍频数> 大于1时有实际效果,一般设置为 (0%2C1%5D 范围内的数。<持续度> 决定后续倍频对起伏程度的影响如何随着频率增大而衰减,1 为完全不衰减。若 <倍频数> 较大而倍频几乎不衰减,则会在原地形上产生大量尖刺及竖井,大部分情况下有碍观瞻。<持续度> 的影响见下图。

噪声部分:上图 perlin(0, x, 0, z, 1, 2, 0.25);中图 perlin(0, x, 0, z, 1, 2, 0.5);下图 perlin(0, x, 0, z, 1, 2, 1)


  除柏林噪声外,WorldEdit 提供的 ridgedmulti 函数也可用于此步骤。 噪声更适合用于制造类似山脊的结构。下图是例子。

噪声部分:ridgedmulti(0, x, 0, z, 1, 1)

柔化及切削出空岛底部的形状

  目前为止,通过噪声函数生成的起伏地形仍然保持着与选区相同的形状(矩形),但矩形在很多时候过于僵硬,不一定能满足展馆建设的要求。为得到「刻板印象中的」空岛底部形状,需要将其切削,并使边缘区域均匀变薄、起伏柔化。

  为达成此目的,需寻找一个自变量只包含 x 和 z 的 <缩放函数> r,乘以当前的噪声 n,让噪声的值在靠近中心的位置为1左右、边缘不需要的位置迅速下降至0以下。您还记得默认情况下 y 的实际取值范围是 %5B-1%2C1%5D 吗?这样一来,若最后一个表达式是 < r *- 1 ,就可以让这些边缘区域实现被裁剪的效果。n = 0 的位置则成为空岛的边缘。

  与原点的水平距离函数  f(x%2Cz)%3D%5Csqrt%7Bx%5E2%2Bz%5E2%7D 可以满足要求,它将形状限制在一个锥体内部,边缘是圆,如下图所示。

n = perlin(100, x, 0, z, 1, 2, 0.5); r = 1 - sqrt(x^2 + z^2); y < n*r - 1

  如果锥体太过尖锐,可以试试离原点的水平距离平方  f(x%2Cz)%3Dx%5E2%2Bz%5E2,它将形状限制在一个抛物面内,边缘同样是圆,如下图所示。

n = perlin(100, x, 0, z, 1, 2, 0.5); r = 1 - (x^2 + z^2); y < n*r - 1

  接下来是我个人在建设 Caupona 展馆时使用的 <缩放函数>,衡量的是离原点的水平 L%5E3 范数,即 f(x%2Cz)%3D%5Csqrt%5B3%5D%7B%7Cx%7C%5E3%2B%7Cz%7C%5E3%7D 。它的边缘类似一个圆角矩形——只是类似。

n = perlin(100, x, 0, z, 1, 2, 0.5); r = 1 - (abs(x)^3 + abs(z)^3) ^ (1 / 3); y < n*r - 1‍

  复杂一些的函数也没有问题。下图使用的是 f(x%2Cz)%3D%5Cbegin%7Bcases%7D%5Csin%5Csqrt%7B%5Cpi%20x%5E2%2B%5Cpi%20z%5E2%7D%26x%5E2%2Bz%5E2%3C1%2C%5C%5C1%26%5Cmbox%7B%E5%88%AB%E5%A4%84.%7D%5Cend%7Bcases%7D 。

n = perlin(100, x, 0, z, 1, 2, 0.5); r = (x^2 + z^2 < 1 ? sin(sqrt(pi * x^2 + pi * z^2)) : 1); y < n*r - 1‍


  实际上,只要您能构造出来,总能用不同的 <缩放函数> 将地形切割并塑造成不同的形状。

翻转地形

  您会注意到,「刻板印象中的」空岛底部——带有随机起伏的锥形——已经大致成型了。当然,根据选用的噪声及 <缩放函数>,不一定是锥形。无论如何,最后一步就只是将其翻转过来,这只需要将最后一个表达式的 < n*- 1 改为 -< n*- 1 即可实现。

  如果希望起伏的程度更大,则可以修改成 -< <放大倍率>*n*- 1 的形式。需注意的是,乘以较大的 <放大倍率> 可能使右侧超过 -y 的取值范围,导致地形被裁剪。

n = perlin(30, x, 0, z, 1, 2, 0.5); r = 1 - (x^2 + z^2); -y < 2*n*r - 1

后续雕刻及修葺

  单一材料组成的空岛底部自然不美观,需要您进一步修葺及雕刻,以及替换一些材料。设置合适蒙版的刷子在这项工作中很有用,不过这就不是本文所关注的了。

  如果您看到了这里,预祝展馆建设顺利。

关于本文

  本文的文字部分依 CC0 协议进入公有领域。不过,图片主要来自 Minecraft 游戏截图,并使用 Wolfram Mathematica 生成了数个函数图像。在特定场合使用这些图片是否会构成对有关方面的侵权,有待使用者核实。

作者所属 TeaCon 2023 参赛队伍:IEEM Trivium Society(IEEM 交衢会)


使用 WorldEdit 快速塑造空岛底部形状的评论 (共 条)

分享到微博请遵守国家法律