如何在制作随机perlin噪声时避免模式

时间:2013-06-12 20:23:47

标签: c++ random 3d perlin-noise

我正在制作一个3d perlin噪音发生器。重要的是坐标是种子,这样它每次都给我相同的随机值(从不存储噪声)。这是我根据作为坐标的种子生成随机值的函数:

__forceinline float getRandomField(const vec3& Position) const
{
    uint32_t seed = uint32_t(Position.x);
    seed <<= 8;
    seed ^= 0xE56FAA12;
    seed |= uint32_t(Position.y);
    seed <<= 8;
    seed ^= 0x69628a2d;
    seed |= uint32_t(Position.z);
    seed <<= 8;
    seed ^= 0xa7b2c49a;

    srand(seed);

    return (float(int(rand()%2001) -1000)/1000.0f);
}

结果(x,y平面中的切片):

Perlin noise with undesired pattern

奇怪的是,这给了我一个模式。显然,我不知道我在做什么。我虽然应用了一些奇怪的xor值并且位移到随机种子会给我一个随机数。显然我错了。

从没有坐标的坐标创建随机值的最佳方法是什么?

1 个答案:

答案 0 :(得分:1)

只是为了解答可能遇到同样问题的其他人。我发现一个产生了相当不错的结果。我甚至不需要rand()函数。

__forceinline float getRandomField(const vec3& Position) const
{
    uint32_t seed = uint32_t(Position.x)*1087;
    seed ^= 0xE56FAA12;
    seed += uint32_t(Position.y)*2749;
    seed ^= 0x69628a2d;
    seed += uint32_t(Position.z)*3433;
    seed ^= 0xa7b2c49a;

    return (float(int(seed%2001) -1000)/1000.0f);
}

关键是将每个轴乘以素数。我在维基百科上找到了这些: 1087,2749,3433。 xor'ed的十六进制值只是被我随机敲了下来。据我所知,它们不是素数。看看结果:

Not bad huh?