npm 包 perlin 使用教程

阅读时长 8 分钟读完
  • 文章作者:AI编写
  • 发布时间:2021 年 11 月 1 日

介绍

perlin 是一个可以生成 Perlin 噪声的 npm 包。Perlin 噪声是一种用于生成连续的自然随机图案的算法,被广泛应用于生成自然风景、天空、水波等效果,也可以用于游戏场景的地形、草丛、树木等的生成。本教程将详细介绍 perlin 的使用方式和代码示例,并对其实现原理进行一定的解析,帮助读者深入了解 Perlin 噪声的生成过程。

安装使用

可以通过 npm 安装 perlin:

或者通过 yarn 安装:

在代码中导入 perlin 并使用:

-- -------------------- ---- -------
------ - ----- - ---- ---------

-------- --------------- -- -
  --- ------- - ---
  --- --------- - ----

  ------- - - -- - - ----- ---- -
    --- - - ------- - ----- -- -- - ----------
    ----------------
  -

  ------ --------
-

函数参数

Perlin 噪声的生成函数为 noise,它接受三个参数:

  • x, y, z:输入的三个数值,对应于三维空间中的一点的坐标。如果省略 yz,则生成二维的噪声。

函数返回的是一个范围在 0 到 1 之间的数值,表示这个坐标点的噪声值。

随机性的实现思路

Perlin 噪声的实现过程基于一多维插值函数(interpolation)和一些列随机梯度向量。其实现步骤如下:

  1. 先将输入的坐标点通过一定的方式映射到一个格子中。

  2. 对每个格子,生成一个向量,表示这个点上的随机梯度向量。

  3. 对于输入的坐标点,先找到它所在的网格顶点,然后计算这个顶点到输入点的距离,从而确定插值中所用的“位置参数”。

  4. 将输入点周围的四个顶点与它所在的可以形成“单元”的四个点进行插值运算,得到一个范围在 0 到 1 之间的值。

  5. 将这些值按照规定的方式结合在一起,得到最终的 Perlin 噪声值。

下面我们将对这些步骤逐一进行解释。

映射到格子

我们需要将输入的坐标点映射到一个“格”(cell)中,这个格子的大小是根据打算生成的场景而定的,通常是一个整数。

例如,如果我们打算生成一个 100x100 的地形场景,那么我们可以将每个点映射为 $(i, j)$ 的二元组,其中 i 和 j 分别是该点所处的格子的坐标。这时候,输入的坐标点 $(x, y)$ 应当被映射为 $(i, j)$,其中:

cellSize 就是格子的大小,一般是一个整数。这样做的好处是可以显著地提高计算速度。

随机梯度向量

对于每个顶点,需要生成一个随机梯度向量。这个向量实际上是用一个随机生成器生成的,Perlin 噪声使用的是 1D/2D/3D 梯形噪声(improved Perlin noise)的变种之一。我们这里不对梯形噪声的生成过程作详细介绍。唯一需要指出的是,这些向量必须随机分布,并且方向、模长(长度)都应该随机。这里给出一个 JavaScript 代码,用来生成一个在半径为 radius 的球体上随机分布的向量。

-- -------------------- ---- -------
-------- ---------------------------- -
  --- -- -- --
  -- -
    - - -------------- - - - ---
    - - -------------- - - - ---
    - - -------------- - - - ---
  - ----- -- - - - - - - - - - - - - -- - - - - - - - - - - - - ---------

  --- ---- - ------ - ----------- - - - - - - - - - ---

  ------ - - - ----- - - ----- - - ---- --
-

插值运算

假定我们已经生成了每个顶点上的随机梯度向量,则对于任意一个输入的坐标点 $(x, y)$,我们需要找到在它周围的四个顶点以及与它相邻的四个顶点(如下图),并计算这些点之间的插值。

假定 $(x_i, y_j)$ 是输入的坐标点,$(xi_L, y_j)$、$(xi_R, y_j)$、$(Xi, y_j)$、$(xi, y_j)$ 是周围的四个与之相邻的顶点,水平方向的距离分别为 $dx_L, dx_R, dx_i, dx$。

那么,我们可以采用线性、平方或者立方(cubic)插值来计算 $(x_i, y_j)$ 在这个“单元”内的值。为了简化起见,我们这里只使用线性插值:

-- -------------------- ---- -------
-------- -------------- -- -- -
  ------ -- - -- - - - - - --
-

-------- ---------------- ---- --- --- --- -- -
  ----- - - --- - --- - --- - ----
  ----- - - --- - --- - --
  ----- - - -- - ---
  ----- - - ---
  ------ - - - - - - - - - - - - - - - - - - --
-

-------- ------- ---- --- -- -- -
  ----- -- - - - ---
  ----- -- - - - ---

  ----- ------ - ---------- ----
  ----- ------ - --------- - -- ----
  ----- ------ - ---------- -- - ---
  ----- ------ - --------- - -- -- - ---
  ----- ------ - ---------- -- - -- ---
  ----- ------ - --------- - -- -- - -- ---
  ----- ------ - ---------- --- ---
  ----- ------ - --------- - -- --- ---
  ----- ------ - ---------- -- - -- ---
  ----- ------ - --------- - -- -- - -- ---
  ----- ------ - ---------- --- -- ---
  ----- ------ - --------- - -- --- -- ---
  ----- ------ - ---------- -- - -- -- ---
  ----- ------ - --------- - -- -- - -- -- ---
  ----- ------ - ---------- --- -- ---
  ----- ------ - --------- - -- --- -- ---
  ----- ------- - ---------- -- - -- -- ---
  ----- ------- - --------- - -- -- - -- -- ---

  ----- -- - ------------------- ------- ----
  ----- -- - ------------------- ------- ----
  ----- -- - ------------------- ------- ----
  ----- -- - ------------------- ------- ----
  ----- -- - --------------- --- ----
  ----- -- - --------------- --- ----
  ----- ----- - --------------- --- ---------------------------- -----
  ------ -----------------
    ------- ------- ------- -------
    ---------------------------- ---
  - - -- - ------ - -----------------
    ------- ------- ------- -------
    ---------------------------- ---
  ---
-

我们输入了一个“单元”内四个顶点的值,和输入点 $(x_i, y_j)$ 到左上角顶点 $(xi_L, y_j)$ 的距离,这个函数会返回按照线性插值计算出的结果。

总结

本文对 Perlin 噪声的生成过程进行了简单的介绍,并且给出了一个使用 npm 包 perlin 的代码样例,这个代码可以用来生成一维或者二维的自然风景、天空、水波等效果,还可以用于游戏场景的地形、草丛、树木等的生成。由于光是一个简单的代码引擎不足以帮助开发者理解 Perlin 噪声算法的工作原理,因此我们在本教程中也介绍了有关 Perlin 噪声算法的一些基础理论。我们希望这些介绍能够有所帮助,启发您实现更好的游戏场景或自然景观。

来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/5eeda79ccebd9a1b02fbaadb

纠错
反馈