1

我查看了 libnoise 源并找到了 ValuNoise3D 函数:

double noise::ValueNoise3D (int x, int y, int z, int seed)
{
    return 1.0 - ((double)IntValueNoise3D (x, y, z, seed) / 1073741824.0);
}

int noise::IntValueNoise3D (int x, int y, int z, int seed)
{
    // All constants are primes and must remain prime in order for this noise
    // function to work correctly.
    int n = (
        X_NOISE_GEN    * x
      + Y_NOISE_GEN    * y
      + Z_NOISE_GEN    * z
      + SEED_NOISE_GEN * seed)
      & 0x7fffffff;

    n = (n >> 13) ^ n;
    return (n * (n * n * 60493 + 19990303) + 1376312589) & 0x7fffffff;
}

但是当我看到这个的时候,这对我来说是一种魔力。这实际上是如何工作的?我的意思是为什么写这篇文章的人取的是那些素数而不是其他素数?为什么会有这样的方程?他是如何决定使用这些方程式而不是其他方程式的?只是……这怎么理解?

4

2 回答 2

2

随机性是一门艺术。有很多事情可以让伪随机数“看起来不错”。对于很多 3d 函数来说,让它“看起来不错”的最重要的事情是具有适当的频率分布。任何确保良好频率分布模 2^32 的东西都会产生非常好看的数字。乘以大素数会产生良好的频率分布,因为它们与 2^32 不共享任何因子。

于 2013-09-15T06:53:58.370 回答
2

libnoise网站很好地解释了这个噪声函数背后的数学原理。特别是关于素数:

这些大整数是素数。这些整数可以被修改,只要它们仍然是素数;非质数可能会在输出中引入可识别的模式。

noise::IntValueNoise3D实际上分两步操作:第一步将 (x, y, z) 坐标转换为单个整数,第二步将该整数通过整数噪声函数生成噪声值,大致介于 -1073741824 和 1073741824 之间。noise::ValueNoise3D只需转换将该整数转换为 -1 和 1 之间的浮点值。

至于为什么要noise::IntValueNoise3D执行所有这些复杂的操作,它基本上归结为这样一个事实,即这个特定的操作序列产生了一个很好的、嘈杂的结果,没有明显的模式可见。这不是唯一可以使用的操作序列;任何产生足够嘈杂的结果的东西都会起作用。

于 2013-09-15T06:37:53.470 回答