Perlin noise(一)
Perlin noise(一)
一、分形噪聲
??分形幾何學(xué)的基本思想是:客觀事物具有自相似的層次結(jié)構(gòu),局部與整體在形態(tài)、功能、信息、時(shí)間、空間等方面具有統(tǒng)計(jì)意義上的相似性,稱為自相似性??陀^自然界中許多事物,具有自相似的“層次”結(jié)構(gòu),在理想情況下,甚至分形分形至具有無窮層次。適當(dāng)?shù)姆糯蠡蚩s小事物的幾何尺寸,整個(gè)結(jié)構(gòu)并不改變。不少復(fù)雜的物理現(xiàn)象,背后就是反映著這類層次結(jié)構(gòu)的分形幾何學(xué)。分形思想的提出讓我們了解事物的本質(zhì)更進(jìn)一步,同時(shí)也提供了一種研究問題的方法,那就是通過疊加來最終模擬出超乎想像的自然物體。更通俗易懂的來說,分形就是把復(fù)雜的自然物體分成一個(gè)個(gè)的簡單形態(tài),這有點(diǎn)像傅立葉提出的“任何連續(xù)周期信號(hào)可以由一組適當(dāng)?shù)恼仪€組合而成”,事實(shí)證明傅立葉是對(duì)的,即便是拉格朗日也阻止不了。反過來說,可以由簡單的形態(tài)通過無限次的疊加來模擬自然現(xiàn)象。
??這是計(jì)算機(jī)圖形學(xué)家利用分形理論通過迭代算法最終生成的精美圖像。分形理論打開了圖形學(xué)描述自然的一扇大門,影響著圖形學(xué)、幾何學(xué)的發(fā)展。在了解完分形概念之后,我們再來回顧一些基本知識(shí)。
波長(Wavelength):指的是兩個(gè)波谷(波峰)之間的距離
振幅(amlitude):指波的高度
頻率(frequency):指的是波的振動(dòng)快慢,頻率就是1/波長
在正弦波中,他們非常容易區(qū)分。在噪聲波中,也有波長,振幅,頻率之分,如下圖所示。
波長(Wavelength):指的是波峰與波谷之間的距離
振幅(amlitude):指波的高大高度
頻率(frequency):指的是波的振動(dòng)快慢,頻率就是1/波長
持續(xù)度(Persistence):這個(gè)詞是由《大自然的分形幾何學(xué)》[波] 伯努瓦·B. 曼德布羅特(Mandelbrot)引入的,Mandelbrot開創(chuàng)了分形幾何先河。持續(xù)度指的是表示每個(gè)頻率下的振幅,也可以看成是柔合了頻率和振幅,或者說是分形中某種單一層次分形波的特征,持續(xù)度展示了疊加的每個(gè)組成部分:
frequency=2i
amplitude=persistencei
下圖中,Persistence值分別為 1/4, 1/2 與 3/4??梢钥闯霾煌腜ersistence值對(duì)每個(gè)倍頻的頻率和波幅以及最后結(jié)果的影響。(注:以下若干圖片來自參考文獻(xiàn)3)
倍頻 (Octaves):從字面上來理解,倍頻就是加倍的頻率,也是分形疊加中疊加的某種單一層次分形波的特征,倍頻不一定是2倍,也可以是其他倍數(shù),如4倍頻與8倍頻,倍頻越高越多,最后得到的波形包含的細(xì)節(jié)越多,也越自然。
??為加深理解,我們來看看在頻率加倍,振幅減半的一維perlin 噪聲。
??可以看到,隨著頻率的升高,在同一尺度下提供了更高的細(xì)節(jié),但波動(dòng)(振幅)影響的范圍卻更小了。為更直觀的演示這種效果,我們分形疊加不同的倍頻,分別是1倍頻,2倍頻,4倍頻與8倍頻。
??可以看到倍頻數(shù)越高,Perlin噪聲就越精細(xì),但整體形狀不會(huì)有很大的改變。這符合自然現(xiàn)象。最平常的例子是山峰輪廓,它包含著高度上的很大變化(山峰),中等變化(丘陵),小的變化(礫石),微小變化(石頭)…你可以繼續(xù)想象。所以在我們程序中,我們用低頻率,大振幅來模擬大尺度變化,用高頻率,小振幅來模擬小尺度的變化,并將之分形疊加,最終達(dá)到我們想要的效果。
二、分形布朗運(yùn)動(dòng)
??布朗運(yùn)動(dòng)(Brownian movement) 指微小粒子表現(xiàn)出的無規(guī)則運(yùn)動(dòng)。1827年英國植物學(xué)家R.布朗在花粉顆粒的水溶液中觀察到花粉不停頓的無規(guī)則運(yùn)動(dòng)。進(jìn)一步實(shí)驗(yàn)證實(shí),不僅花粉顆粒,其他懸浮在流體中的微粒也表現(xiàn)出這種無規(guī)則運(yùn)動(dòng),如懸浮在空氣中的塵埃。后人就把這種微粒的運(yùn)動(dòng)稱之為布朗運(yùn)動(dòng)。這里我們要講的布朗運(yùn)動(dòng)跟這個(gè)有點(diǎn)區(qū)別,要講清分形布朗運(yùn)動(dòng)還得從《大自然的分形幾何學(xué)》和最簡單的正弦波入手,本篇開篇我們即闡明了:客觀事物具有自相似的層次結(jié)構(gòu),局部與整體在形態(tài)、功能、信息、時(shí)間、空間等方面具有統(tǒng)計(jì)意義上的相似性,稱為自相似性。這是分形學(xué)的最重要的結(jié)論。下面我們從正弦波入手來分別講解。
??正弦波是最簡單的波形之一,正弦波有個(gè)非常有意思的特性,那就是波可以疊加。如下:
圖上一個(gè)是頻率為1的正弦波,另一個(gè)是頻率為2的正弦波,通過疊加產(chǎn)生了一個(gè)新的波,這個(gè)波的振幅由這兩個(gè)波通過簡單的加減構(gòu)成。不僅是正弦波,其他波也有類似的疊加特性。在音樂中,每一個(gè)音階都對(duì)應(yīng)著特定的頻率,頻率加倍或者減半對(duì)應(yīng)著另一個(gè)八度音階(octave),可以看到octave這個(gè)詞是從音樂中引用過來的,前面我們翻譯成倍頻,根據(jù)我們剛說的,octave對(duì)應(yīng)頻率的加倍或減半而不是加1.5倍或減0.4倍。我們稍后也會(huì)對(duì)噪聲作類似處理。
??現(xiàn)在我們由正弦波來討論P(yáng)erlin噪聲(下圖是一維Perlin噪聲圖),Perlin噪聲有著和正弦波一樣的振幅和頻率,雖然這個(gè)振幅和頻率在一定的范圍內(nèi)波動(dòng),雖然不像正弦波那樣規(guī)律,但我們還是可以看得出振幅和頻率只是在一定范圍內(nèi)的合理偏離。由波的疊加可知,利用Perlin噪聲不同倍頻波的疊加可以很容易的更隨機(jī)的波形。
??我們通過一個(gè)步進(jìn)值(lacunarity)逐漸的增大頻率,同時(shí)也同過一個(gè)增益值(gain)逐漸的減小振幅,主可以得到不同的倍頻(octaves),然后再將不同的倍頻疊加,這種技術(shù)就叫分形布朗運(yùn)動(dòng)(fractal Brownian Motion(fBM) )。簡單的分形布朗運(yùn)動(dòng)可以由下面的代碼生成。
const int octaves = 2; float lacunarity = 2.0; float gain = 0.5; float amplitude = 1.; float frequency = 1.;// 疊代 octaves,y縱軸,x為橫軸 for (int i = 0; i < octaves; i++) {y += amplitude * noise(frequency*x);frequency *= lacunarity;amplitude *= gain; }??下面是octaves為2,4,8時(shí)的一維Perlin噪聲,可以看到疊加的octave越多,噪聲的細(xì)節(jié)就越多,另外一個(gè)值得注意的地方是,疊加的細(xì)節(jié)與原波形具備宏觀上的相似性,這就是我們說過的分形的最重要的特征。
??分形布朗運(yùn)動(dòng)是分形幾何里的重要概念,理論上疊加無限多的octave,可以得到無限細(xì)節(jié)的分形幾何圖形,在實(shí)際運(yùn)用中,過多的疊加會(huì)削弱圖形性能,根據(jù)需要取合適的值。
三、Perlin noise原理
??Perlin noise原理很簡單:
??第一步:定義一個(gè)晶格結(jié)構(gòu),每個(gè)晶格的頂點(diǎn)有一個(gè)“偽隨機(jī)”的梯度向量。對(duì)于二維的Perlin噪聲來說,晶格結(jié)構(gòu)就是一個(gè)平面網(wǎng)格,三維的就是一個(gè)立方體網(wǎng)格。
??第二步:輸入一個(gè)點(diǎn)(二維的話就是二維坐標(biāo),三維就是三維坐標(biāo),n維的就是n個(gè)坐標(biāo)),我們找到和它相鄰的那些晶格頂點(diǎn)(二維下有4個(gè),三維下有8個(gè),n維下有2n個(gè)),計(jì)算該點(diǎn)到各個(gè)晶格頂點(diǎn)的距離向量,再分別與頂點(diǎn)上的梯度向量做點(diǎn)乘,得到2n個(gè)點(diǎn)乘結(jié)果。
??第三步:使用緩和曲線(ease curves)來計(jì)算它們的權(quán)重和。在原始的Perlin噪聲實(shí)現(xiàn)中,緩和曲線是s(t)=3t2?2t3,在2002年的論文6中,Perlin改進(jìn)為s(t)=6t5?15t4+10t3。由高等數(shù)學(xué)可以知道,函數(shù)越是高階可導(dǎo)函數(shù)曲線越是平滑,s(t)=3t2?2t3在一階導(dǎo)滿足連續(xù)性,但它的二階導(dǎo)在晶格頂點(diǎn)處(即t = 0或t = 1)不為0,會(huì)造成明顯的不連續(xù)性。s(t)=6t5?15t4+10t3在二階導(dǎo)上仍然滿足連續(xù)性。
??這就是計(jì)算Perlin噪聲的邏輯和流程。下面我們以二維Perlin噪聲為例加以說明:
第一步:構(gòu)建一個(gè)二維平面,同時(shí)生成每個(gè)頂點(diǎn)的“偽隨機(jī)”的梯度向量:
??這里,每個(gè)頂點(diǎn)各自生成一個(gè)偽隨機(jī)的梯度向量。梯度向量代表該頂點(diǎn)相對(duì)單元正方形內(nèi)某點(diǎn)的影響是正向還是反向的(一會(huì)我們會(huì)看到梯度向里對(duì)最終效果的影響)。而偽隨機(jī)是指,對(duì)于任意組相同的輸入,必定得到相同的輸出。雖然每個(gè)頂點(diǎn)生成的梯度向量看似隨機(jī),實(shí)際上并不是。這保證了在生成函數(shù)不變的情況下,每個(gè)坐標(biāo)的梯度向量都是確定不變的。同時(shí),這些梯度向量并不是完全隨機(jī)的,而是由單位正方體(3維)的中心點(diǎn)指向各條邊中點(diǎn)的12個(gè)向量:
(1,1,0),(-1,1,0),(1,-1,0),(-1,-1,0), (1,0,1),(-1,0,1),(1,0,-1),(-1,0,-1), (0,1,1),(0,-1,1),(0,1,-1),(0,-1,-1)
采用這些特殊梯度向量的原因在Ken Perlin’s SIGGRAPH 2002 paper: Improving Noise這篇文章里有具體說明。主要是為了避免“鏡像”現(xiàn)象。
第二步:輸入一個(gè)點(diǎn),找到和它相鄰的那些晶格頂點(diǎn):
找到輸入點(diǎn)所在的晶格的頂點(diǎn)梯度向量:
接著,求出另外4個(gè)距離向量,它們分別從各頂點(diǎn)指向輸入點(diǎn)(藍(lán)色點(diǎn)):
接下來,對(duì)相應(yīng)的頂點(diǎn)梯度向量與距離向里作點(diǎn)積運(yùn)算。從點(diǎn)積的特性可知:當(dāng)兩個(gè)向量的夾角小于90度時(shí)點(diǎn)積結(jié)果為正;當(dāng)兩個(gè)向量夾角大于90度時(shí)點(diǎn)積結(jié)果為負(fù);當(dāng)兩個(gè)向量夾角等于90度時(shí)點(diǎn)積結(jié)果為0。因此點(diǎn)積后的結(jié)果圖如下:
此圖很直觀的表現(xiàn)了梯度向量對(duì)最終效果的影響,這也是Perlin噪聲最終外觀表現(xiàn)的內(nèi)在原因。
第三步:對(duì)4個(gè)頂點(diǎn)的影響值做插值,緩和曲線的值會(huì)用來計(jì)算插值因子,這樣插值變化不再是單調(diào)的線性變化,而是這樣一個(gè)過程:初始變化慢,中間變化快,結(jié)尾變化又慢下來(也就是在當(dāng)數(shù)值趨近于整數(shù)時(shí)變化變慢,或者說是接近固定點(diǎn)時(shí)變化速率變緩)。我們用Perlin改進(jìn)的緩和曲線 s(t)=6t5?15t4+10t3。
這就是Perlin噪聲生成的原理同時(shí)也是步驟,理解起來不難。這里也可以看到,梯度值在生成噪聲中影響可謂是舉足輕重,這也是Perlin噪聲叫作梯度噪聲的來源。
四、小結(jié)
??本篇文章主要關(guān)注了分形噪聲,分形布朗運(yùn)動(dòng),介紹了Perlin噪聲原理,通過上文,我們可以看到,分形噪聲跟噪聲一點(diǎn)關(guān)系都沒有,分形布朗運(yùn)動(dòng)跟運(yùn)動(dòng)一點(diǎn)關(guān)系都沒有,不要僅僅局限于字面的理解,更要理解概念的實(shí)質(zhì),這更重要。
參考文獻(xiàn):
1、《大自然的分形幾何學(xué)》[波] 伯努瓦·B. 曼德布羅特(Mandelbrot)
2、Perlin Noise http://freespace.virgin.net/hugo.elias/models/m_perlin.htm
3、關(guān)于噪聲的一些基本定義 http://www.gamersky.com/handbook/201601/708963_2.shtml?tag=wap
4、Fractal Brownian Motion https://thebookofshaders.com/13/
5、Understanding Perlin Noise ,https://flafla2.github.io/2014/08/09/perlinnoise.html
6、談?wù)勗肼?http://blog.csdn.net/candycat1992/article/details/50346469
總結(jié)
以上是生活随笔為你收集整理的Perlin noise(一)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python中的metaclass和__
- 下一篇: java面试题11 牛客:如下语句通过算