2013-06-12 67 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

@佩特有道理,感謝煽動 –