前幾天看到一本《DirectX特效開發》的書,翻了幾頁發現了關於一些Perlin Noise和雲紋理的產生。自己做了一下,搞到現在終於弄出個比較像Perlin Noise的噪音圖。
Perlin Noise主要目標是產生一個比較平滑的隨機數,如果是紋理圖,那麼U,V方向的各個紋素應該較為平滑,不能太過劇烈的變化。
頻率:波長的倒數,這裡是指距上一次隨機點多遠取一個隨機數。也就是兩個隨機數之間的寬度的倒數。頻率越高說明波長越短,也就有更多的鋸齒。
振幅:波的高度,這裡也就是隨機數產生的範圍,振幅越大,範圍越大。
實質:首先我們要一個大體輪廓,然後輪廓是大體平滑的有些凸起的地方(振幅大,頻率低),然後在其中平滑的地方再次添加輪廓(振幅比上次小,頻率比上次高,添加細節),然後再繼續,當然可以無限劃分,不過我們一般使用在10次以內。這就是所謂的分形,比如一座山,遠遠望去你可以看到輪廓,走近點,還有凹凸,如果有顯微鏡,還可以看到更小的尺寸也是不平整的,柏林噪音就類比了這些東西,也包括雲。inline float Noise2D(int x, int y)
{
int n = x+y*57;
n = (n<<13)^n;
return (1.0f - ((n*(n*(n*n*15731+789221)+1376312589)&0x7fffffff)/1073741824.0f));
}
這是一個隨機數種子,產生[-1,+1]範圍內的隨機數,對應於顏色為[0,255]
對於我們的紋理,振幅大也就相當於0~255,不過當然要稍微設定得小一點。那麼頻率呢,假設第一張紋理圖為16X16.那麼相當於U方向取樣16個隨機點,對於32X32那麼相當於U方向取樣32個隨機點,因此,頻率增大了一倍。當然,頻率大的只是為了增加更小尺寸的細節輪廓,因此增幅就不能超過16x16的範圍了,一般為前者的0.5倍。這就是通常所說的“倍頻層”,依次類推。至於隨機點的插值運算,我們就直接交給顯卡了,使用紋理的雙線性插值法。當然,頻率越高需要插值的次數越少,極端一點,頻率無限大那麼就是連續函數了。而頻率越大則紋理的尺寸越大32x32 映射到512X512的螢幕上自然要比16x16插值的次數少。
將每張紋理渲染到使用線性插值渲染到RenderTarget後,再將RenderTarge的紋理進行複合再渲染就行了。
代碼:/Files/ttthink/Noise.rar