2013-06-12 44 views
3

我正在制作一个3d珀林噪音发生器。坐标是种子很重要,因为它每次都给我相同的随机值(噪音永远不会被存储)。这是我的用于基于种子这是坐标产生随机值功能:如何在制作随机珀林噪音时避免图案

__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

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

什么是最好的方式来创建一个坐标随机值没有它导致了一个模式?

+0

A *慢*的方式将散列的3个位置的串联[例如哈希你的种子忽略XOR位](使用说md5),并拉出最低的2个字节。虽然会工作。 –

+0

我必须(相对)快速。我对md5一无所知,但是我看到一些md5生成器的代码在536行上。这是缓慢的方式。 – bofjas

+0

这是一个有趣的俄勒冈州噪声pdf http://web.engr.oregonstate.edu/~mjb/cs519/Handouts/noise.1pp.pdf –

回答

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?

+0

我已经使用珀林噪音了一段时间,我知道它使用素数的重要性,但从不*为什么素数是关键。你有没有煽动这个? –

+0

@RichardTingle我相信这是因为素数不能被对方整除。你有一个网格,为一个素数的每个倍数绘制一个点,这样你就不太可能重叠。 http://io9.com/5895840/why-do-cicadas-know-prime-numbers – Pete

+0

@佩特有道理,感谢煽动 –