0

我目前正在研究地形引擎,并且正在尝试一些噪音。看看几行代码就能创造出不同的结构、功能和纯粹的想象力,真是令人着迷。最近我看到了这篇文章:http ://squall-digital.com/ProceduralGeneration.html ,我对所有这些技术都非常感兴趣,但尤其是第一个引起了我的注意。程序员使噪声的增益(或持久性)与该点上的噪声斜率成正比。我目前正在努力实现这一目标,但我认为我没有走在正确的轨道上。

我目前正在使用单纯形噪声。我知道这篇文章的作者使用了 Perlin Noise,是的,我已经看到了如何计算 Perlin Noise 的导数,但显然这种实现不会起作用,因为 Perlin 和 Simplex 噪声的生成方式存在根本差异。因此,我开始以自己的方式尝试和近似给定位置上的噪声斜率。

我想出了以下“算法”:

  • 计算相邻噪声点 [(x + 1, z), (x - 1, z), (x, z + 1), (x, z - 1)]。
  • 计算它们各自的噪声值
  • 分别计算x轴和z轴上噪声值的differenceX和differenceZ
  • 从原点创建向量:(2, differenceX, 0) 和 (0, differenceZ, 2)
  • 缩放到长度为 1 的向量
  • 添加得到的单位向量的 y 分量
  • 将此 y 分量用作在给定点处近似的“斜率”。

现在我已经在代码中实现了这个(为了便于理解,我添加了“3D”向量)

private static float slope(OpenSimplex2F simplex, float x, float z, float noise) {
    float[] neighbours = getStraightNeighbours(simplex, x, z);

    float xSlope = (neighbours[1] - neighbours[0]) / (2.0f * x);
    float zSlope = (neighbours[3] - neighbours[2]) / (2.0f * z);

    float[] vecX = new float[] { 1, xSlope, 0 };
    float[] vecZ = new float[] { 0, zSlope, 1 };

    float scaleX = Maths.sqrt(1.0f + xSlope * xSlope);
    float scaleZ = Maths.sqrt(1.0f + zSlope * zSlope);

    for (int i = 0; i < 3; i++) {
        vecX[i] /= scaleX;
        vecZ[i] /= scaleZ;
    }

    float[] grad = new float[] {
            vecX[0] + vecZ[0],
            vecX[1] + vecZ[1],
            vecX[2] + vecZ[2]
    };

    return grad[1];
}

现在这让我非常失望和放心,错误的结果:结果

如果这是一种完全错误的近似斜率的好技术,有没有人可以解释我。我不是最大的数学天才,所以我已经很高兴我能弄清楚这一点并且它首先产生了结果。如果有人有与单纯形噪声的导数相关的资源(显然,这将是一个救生员),那将不胜感激!

4

0 回答 0