我是否需要为Perlin噪音定制随机数发生器?

时间:2014-04-20 05:04:13

标签: python random pseudocode

Perlin用伪代码解释:http://freespace.virgin.net/hugo.elias/models/m_perlin.htm

本教程给我一个伪代码写的随机数生成器函数。返回(-1,1)范围内的浮点数。

function IntNoise(32-bit integer: x)             
    x = (x<<13) ^ x;
    return ( 1.0 - ( (x * (x * x * 15731 + 789221) + 1376312589) & 7fffffff) / 1073741824.0);    
end IntNoise function

因此,如果此函数返回范围(-1,1)中的数字,我不能只使用random.uniform(-1, 1)吗? 但后来我遇到了这个问题:

function Noise(x)
.
.
end function

function SmoothNoise_1D(x)
    return Noise(x)/2  +  Noise(x-1)/4  +  Noise(x+1)/4
end function

我猜Noise(x)函数为1D噪音生成随机数。

我似乎无法理解x参数是什么。 这是种子吗?而且,我不能使用random.uniform(-1, 1)

1 个答案:

答案 0 :(得分:3)

Perlin噪声中使用的噪声函数是种子随机数发生器。也就是说,每次使用相同的参数值 X 调用它时,它必须返回相同的值。您可以将 X 视为在您计算Perlin噪声的区域范围之间的给定维度中的空间中的某个位置。

如果您可以根据给定的参数重置RNG的状态,则可以使用Python随机模块,因此它始终为给定的 X 返回相同的值。

import random

rand_state = random.Random()

def Noise(x):
  rand_state.seed(x)
  return rand_state.random()

>>> Noise(1)
0.13436424411240122
>>> Noise(2)
0.9560342718892494
>>> Noise(1)
0.13436424411240122

请注意, Noise 在第一次传递 1 时返回相同的值,第二次传递相同的值。当输入 1 以外的值时,它还返回不同的值。 seed 的参数可以是Python中的任何可哈希类型。出于您的目的,任何数字类型都可以使用。

通常在创建Perlin噪声时,会对此 Noise 函数进行许多调用,因此您希望它快速。在我的机器上,执行上述功能大约需要14微秒。这只是每秒约70000个电话。可能是为 IntNoise 实现伪代码可能会带来更好的性能。事实上,以下方法:

MAX_INT = (1<<31)-1
def IntNoise(x):
    x = int(x)
    x = ((x << 13) & MAX_INT) ^ x
    x = ( x * (x * x * 15731 + 789221) + 1376312589 ) & MAX_INT
    return 1.0 - x / 1073741824.0

似乎每次调用平均约为1.6微秒,或者比上面的 Noise 快约10倍。它的返回值范围是(-1,1),但可以通过修改最后一行来更改。我无法谈论其分布的一致性,但是,一张图片胜过千言万语。下面的蓝点来自 IntNoise ,红点来自python random.uniform 函数。

Plot of IntNoise

上面的 Noise 函数可以在您的问题中使用平滑噪声算法。您在问题中链接的URL描述了平滑功能的优点。阅读完段落后,研究旁边的1D和2D平滑图片,以便更好地了解它们的用途。