from: http://blog.csdn.net/jia20003/article/details/7220740
柏林噪聲是一種特殊的隨機噪聲,即對于每個給定的值產生的隨機數是唯一的,但是不同的
值產生不同的隨機數。關于柏林噪聲更詳細的解釋可以參考這里:
http://freespace.virgin.net/hugo.elias/models/m_perlin.htm
?
本文主要是探討如何使用柏林噪聲產生火焰效果與烏云效果的紋理,在解釋實現代碼之前,
首先來看一下影響柏林噪聲效果的兩個參數音度(Octave) 與余輝(Persistence),可以調節
紋理的大小和密度。
?
最終實現的火焰紋理效果
最終實現的烏云紋理效果
最終實現的草地紋理效果–怎么感覺有點魔獸中精靈族的草地啊,哈哈
代碼解釋
首先產生隨機空白噪聲,使用隨機空白噪聲產生柏林噪聲,最后將柏林噪聲映射為RGB值
輸出到指定大小的圖像中,代碼如下:
float[][] whiteNoise = GenerateWhiteNoise(rows, cols);
float[][] perlinNoise = GeneratePerlinNoise(whiteNoise, 6); //
float[][] colorData = MapGray(perlinNoise);
?
白噪聲產生主要是利用JAVA中的系統時間作為種子,產生[0~1]之間的噪聲數組
代碼如下:
public float[][] GenerateWhiteNoise(int width,int height)
{
Random random = new Random(System.currentTimeMillis()); ???
float[][] noise = new float[width][height];
for (int i = 0; i < width; i++)
{
??? ??? for (int j = 0; j <height; j++)
??? ??? {
??? ???? ?? noise[i][j] = (float)random.nextDouble();
??? ??? }
??? }
??? return noise;
}
?
柏林噪聲的產生稍微復雜一點點,首先把上面的白噪聲數據帶入,利用插值公式產生平滑的噪聲
數據,具體要產生幾組平滑噪聲數據取決于音度(Octave)參數。本程序的插值公式非常簡單,
代碼如下:
public float Interpolate(float x0,float x1, float alpha)
{
return x0 * (1 - alpha) + alpha * x1;
}
最后把這些組的平滑噪聲加上不同的振幅混合在一起產生一個輸出數組結果即為柏林噪聲。
完成上面這些還不足以產生那些效果震撼的紋理,另外一個頂級秘訣在于怎么把柏林噪聲
映射到你想要的RGB值。代碼如下:
?? ?float[][] MapGradient(float[][] perlinNoise)
??? {
??? ?? int width =perlinNoise.length;
??? ?? int height =perlinNoise[0].length;
??? ?? float[][] image = new float[width][height];
??? ?? int ta=0, tr=0, tb=0,tg=0;
??? ?? for (int i = 0; i <width; i++)
??? ?? {
??? ????? for (int j = 0; j <height; j++)
??? ????? {
??? ??? ??ta = 255;
??? ??? ??int u = (int)(perlinNoise[i][j] * (float)angryFireColorTable.length);
??? ??? ??tr = (int)angryFireColorTable[u][0];
??? ??? ??tg = (int)angryFireColorTable[u][1];
??? ??? ??tb = (int)angryFireColorTable[u][2];
??? ??? ??image[i][j] = (ta <<24) | (tr << 16) | (tg << 8) | tb;
??? ????? }
??? ?? }
??? ??
??? ?? return image;
??? }
程序完全源代碼如下:
[java] view plaincopy
package?com.gloomyfish.perlin.noise;????import?java.util.Random;????public?class?PerlinNoiseCreator?{????????????private?int[][]?angryFireColorTable?=?{??????????????{255,?255,?204},????{255,?255,?204},????{255,?255,?204},????{255,?255,?204},??????????????{255,?255,?204},????{255,?255,?204},????{255,?255,?204},????{255,?255,?204},????{255,?255,?204},??????????????{255,?255,?204},????{255,?255,?204},????{255,?255,?204},????{255,?255,?204},????{255,?255,?204},??????????????{255,?255,?204},????{255,?255,?204},????{255,?255,?204},????{255,?255,?204},????{255,?255,?204},??????????????{255,?255,?204},????{255,?255,?204},????{255,?255,?204},????{255,?255,?204},????{255,?255,?204},??????????????{255,?255,?204},????{255,?255,?204},????{255,?255,?204},????{255,?255,?204},????{255,?255,?204},??????????????{255,?255,?204},????{255,?255,?204},????{255,?255,?204},????{255,?255,?204},????{255,?255,?204},??????????????{255,?255,?204},????{255,?255,?204},????{255,?255,?204},????{255,?255,?204},????{255,?255,?199},??????????????????{255,?255,?199},????{255,?255,?197},????{255,?255,?197},????{255,?255,?193},????{255,?255,?193},??????????????{255,?255,?191},????{255,?255,?191},????{255,?255,?189},????{255,?255,?189},????{255,?255,?185},??????????????{255,?255,?185},????{255,?255,?183},????{255,?255,?183},????{255,?255,?179},????{255,?255,?179},??????????????{255,?255,?177},????{255,?255,?177},????{255,?255,?175},????{255,?255,?175},????{255,?255,?171},??????????????????????{255,?255,?171},????{255,?255,?169},????{255,?255,?169},????{255,?255,?167},????{255,?255,?167},??????????????{255,?255,?163},????{255,?255,?161},????{255,?255,?157},????{255,?255,?155},????{255,?255,?153},??????????????{255,?251,?149},????{255,?249,?147},????{255,?246,?144},????{255,?244,?142},????{255,?242,?140},??????????????{253,?244,?205},????{248,?246,?197},????{248,?246,?187},????{248,?245,?178},????{248,?245,?168},??????????????{247,?245,?160},????{248,?243,?149},????{247,?244,?141},????{249,?243,?133},????{248,?243,?123},??????????????{249,?242,?112},????{248,?242,?102},????{248,?242,?92},?{247,?241,?81},?{248,?241,?73},??????????????{247,?240,?63},?{249,?239,?53},?{247,?239,?42},?{249,?238,?32},?{249,?238,?26},??????????????{248,?234,?21},?{248,?231,?21},?{250,?224,?25},?{248,?218,?24},?{249,?214,?26},??????????????{249,?209,?26},?{252,?204,?32},?{251,?198,?32},?{251,?191,?33},?{251,?186,?34},??????????????{250,?179,?35},?{252,?176,?38},?{252,?169,?41},?{252,?164,?41},?{254,?157,?44},??????????????{254,?151,?46},?{253,?145,?47},?{254,?141,?49},?{251,?136,?47},?{253,?135,?48},??????????????{251,?130,?47},?{250,?129,?46},?{249,?126,?46},?{247,?124,?44},?{246,?120,?43},??????????????{244,?118,?41},?{243,?115,?42},?{241,?113,?40},?{242,?111,?41},?{240,?109,?39},??????????????{239,?104,?40},?{236,?101,?37},?{234,?99,?35},??{235,?97,?34},??{232,?93,?34},??????????????{231,?91,?32},??{229,?88,?32},??{227,?86,?30},??{227,?83,?30},??{225,?81,?28},??????????????{224,?78,?27},??{222,?76,?25},??{223,?72,?27},??{221,?70,?25},??{219,?66,?24},??????????????{216,?63,?22},??{216,?58,?21},??{212,?54,?19},??{210,?50,?18},??{209,?45,?17},??????????????{206,?40,?14},??{206,?37,?14},??{203,?32,?12},??{200,?29,?9},???{200,?24,?9},??????????????{197,?21,?6},???{195,?17,?7},???{191,?13,?3},???{190,?7,?3},????{188,?5,?1},??????????????{184,?2,?0},????{180,?0,?0},????{178,?0,?0},????{174,?0,?0},????{172,?0,?0},??????????????{169,?1,?0},????{164,?0,?1},????{160,?0,?0},????{158,?0,?0},????{154,?0,?0},??????????????{150,?0,?0},????{146,?0,?0},????{144,?0,?0},????{140,?0,?1},????{136,?0,?2},??????????????{133,?0,?1},????{130,?0,?0},????{126,?1,?0},????{124,?0,?2},????{120,?0,?1},??????????????{116,?0,?0},????{112,?0,?0},????{109,?1,?1},????{104,?0,?0},????{103,?0,?1},??????????????{98,?0,?0},?{95,?0,?0},?{92,?1,?0},?{92,?1,?0},?{90,?0,?0},??????????????{89,?1,?0},?{88,?0,?0},?{86,?0,?0},?{86,?0,?0},?{84,?0,?0},??????????????{84,?0,?0},?{82,?1,?0},?{82,?1,?0},?{80,?0,?0},?{80,?0,?0},??????????????{79,?1,?1},?{78,?0,?0},?{76,?0,?0},?{76,?0,?0},?{74,?0,?0},??????????????{74,?0,?0},?{72,?0,?1},?{72,?0,?1},?{70,?0,?0},?{70,?0,?0},??????????????{69,?1,?2},?{68,?0,?1},?{66,?0,?1},?{66,?0,?1},?{64,?0,?0},??????????????{62,?1,?0},?{61,?1,?1},?{60,?0,?0},?{60,?0,?0},?{60,?0,?0},??????????????{58,?0,?0},?{58,?0,?0},?{56,?0,?1},?{56,?0,?1},?{54,?0,?0},??????????????{54,?0,?0},?{52,?1,?0},?{51,?0,?0},?{50,?0,?1},?{50,?0,?1},??????????????{49,?1,?1},?{48,?0,?0},?{46,?0,?0},?{46,?0,?0},?{44,?0,?1},??????????????{42,?0,?1},?{42,?0,?1},?{40,?0,?0},?{40,?0,?0},?{39,?0,?0},??????????????{38,?0,?0},?{38,?0,?0},?{36,?0,?0},?{35,?0,?0},?{34,?0,?0},??????????????{34,?0,?0},?{32,?0,?1},?{30,?0,?0},?{30,?0,?0},?{29,?1,?0},??????????????{28,?0,?0},?{28,?0,?0},?{26,?0,?1},?{24,?0,?0},?{22,?1,?0},??????????????{22,?1,?0},?{21,?1,?0},?{20,?0,?0},?{19,?1,?1},?{19,?1,?1},??????????????{16,?0,?0},?{16,?0,?0},?{16,?0,?0},?{14,?0,?0},?{12,?0,?0},??????????????{12,?0,?0},?{11,?1,?0},?{10,?0,?0},?{9,?1,?0},??{8,?0,?0},??????????????{6,?0,?0},??{6,?0,?0},??{5,?1,?0},??{4,?0,?0},??{2,?1,?0},??????????????{2,?1,?0},??{1,?1,?1},??{0,?0,?0},??{0,?0,?0},??{0,?0,?0},??????????};??????????????public?void?generateNoise(int[]?noiseData,?int?rows,?int?cols)?{????????????float[][]?whiteNoise?=?GenerateWhiteNoise(rows,?cols);??????????float[][]?perlinNoise?=?GeneratePerlinNoise(whiteNoise,?6);?????????????????????float[][]?colorData?=?MapGray(perlinNoise);??????????int?index?=?0;??????????for(int?row?=?0;?row<rows;?row++)?{??????????????for(int?col=0;?col<cols;?col++)?{??????????????????index?=?row?*?cols?+?col;??????????????????noiseData[index]?=?(int)colorData[row][col];??????????????}??????????}??????}????????????public?float[][]?GenerateWhiteNoise(int?width,?int?height)??????{??????????Random?random?=?new?Random(System.currentTimeMillis());???????????float[][]?noise?=?new?float[width][height];?????????????????for?(int?i?=?0;?i?<?width;?i++)??????????{??????????????for?(int?j?=?0;?j?<?height;?j++)??????????????{??????????????????noise[i][j]?=?(float)random.nextDouble();??????????????}??????????}?????????????????return?noise;??????}????????????public?float[][]?GenerateSmoothNoise(float[][]?baseNoise,?int?octave)??????{?????????int?width?=?baseNoise.length;?????????int?height?=?baseNoise[0].length;????????????????float[][]?smoothNoise?=?new?float[width][height];????????????????int?samplePeriod?=?1?<<?octave;??????????float?sampleFrequency?=?1.0f?/?samplePeriod;????????????????for?(int?i?=?0;?i?<?width;?i++)?????????{????????????????????????int?sample_i0?=?(i?/?samplePeriod)?*?samplePeriod;????????????int?sample_i1?=?(sample_i0?+?samplePeriod)?%?width;?????????????float?horizontal_blend?=?(i?-?sample_i0)?*?sampleFrequency;???????????????????for?(int?j?=?0;?j?<?height;?j++)????????????{??????????????????????????????int?sample_j0?=?(j?/?samplePeriod)?*?samplePeriod;???????????????int?sample_j1?=?(sample_j0?+?samplePeriod)?%?height;????????????????float?vertical_blend?=?(j?-?sample_j0)?*?sampleFrequency;?????????????????????????????????????float?top?=?Interpolate(baseNoise[sample_i0][sample_j0],??????????????????baseNoise[sample_i1][sample_j0],?horizontal_blend);?????????????????????????????????????float?bottom?=?Interpolate(baseNoise[sample_i0][sample_j1],??????????????????baseNoise[sample_i1][sample_j1],?horizontal_blend);?????????????????????????????????????smoothNoise[i][j]?=?Interpolate(top,?bottom,?vertical_blend);????????????}?????????}????????????????return?smoothNoise;??????}????????????public?float?Interpolate(float?x0,?float?x1,?float?alpha)??????{?????????return?x0?*?(1?-?alpha)?+?alpha?*?x1;??????}????????????public?float[][]?GeneratePerlinNoise(float[][]?baseNoise,?int?octaveCount)??????{?????????int?width?=?baseNoise.length;?????????int?height?=?baseNoise[0].length;????????????????float[][][]?smoothNoise?=?new?float[octaveCount][][];?????????????????float?persistance?=?0.5f;??????????????????????????for?(int?i?=?0;?i?<?octaveCount;?i++)?????????{?????????????smoothNoise[i]?=?GenerateSmoothNoise(baseNoise,?i);?????????}?????????????????float[][]?perlinNoise?=?new?float[width][height];??????????float?amplitude?=?1.0f;??????????float?totalAmplitude?=?0.0f;???????????????????????????for?(int?octave?=?octaveCount?-?1;?octave?>=?0;?octave--)??????????{?????????????amplitude?*=?persistance;?????????????totalAmplitude?+=?amplitude;????????????????????for?(int?i?=?0;?i?<?width;?i++)?????????????{????????????????for?(int?j?=?0;?j?<?height;?j++)????????????????{???????????????????perlinNoise[i][j]?+=?smoothNoise[octave][i][j]?*?amplitude;????????????????}?????????????}??????????}?????????????????????????for?(int?i?=?0;?i?<?width;?i++)?????????{????????????for?(int?j?=?0;?j?<?height;?j++)????????????{???????????????perlinNoise[i][j]?/=?totalAmplitude;????????????}?????????}????????????????return?perlinNoise;??????}????????????float[][]?MapGray(float[][]?perlinNoise)??????{?????????int?width?=?perlinNoise.length;?????????int?height?=?perlinNoise[0].length;?????????float[][]?image?=?new?float[width][height];?????????int?ta=0,?tr=0,?tb=0,?tg=0;?????????for?(int?i?=?0;?i?<?width;?i++)?????????{????????????for?(int?j?=?0;?j?<?height;?j++)????????????{????????????????ta?=?255;????????????????int?u?=?(int)(perlinNoise[i][j]?*?(float)80.0);????????????????tr?=?u+100;????????????????tg?=?u+100;????????????????tb?=?u+100;????????????????????????????????image[i][j]?=?(ta?<<?24)?|?(tr?<<?16)?|?(tg?<<?8)?|?tb;????????????????????????????}?????????}??????????????????return?image;??????}????????????float[][]?MapGradient(float[][]?perlinNoise)??????{?????????int?width?=?perlinNoise.length;?????????int?height?=?perlinNoise[0].length;?????????float[][]?image?=?new?float[width][height];?????????int?ta=0,?tr=0,?tb=0,?tg=0;?????????for?(int?i?=?0;?i?<?width;?i++)?????????{????????????for?(int?j?=?0;?j?<?height;?j++)????????????{????????????????ta?=?255;????????????????int?u?=?(int)(perlinNoise[i][j]?*?(float)angryFireColorTable.length);????????????????tr?=?(int)angryFireColorTable[u][0];????????????????tg?=?(int)angryFireColorTable[u][1];????????????????tb?=?(int)angryFireColorTable[u][2];????????????????image[i][j]?=?(ta?<<?24)?|?(tr?<<?16)?|?(tg?<<?8)?|?tb;????????????}?????????}??????????????????return?image;??????}????}?? 版權聲明:本文為博主原創文章,未經博主允許不得轉載。
- 上一篇圖像處理之快速均值模糊(Box Blur)
- 下一篇HTML5 組件Canvas實現圖像灰度化
頂
2 踩
0
猜你在找
大數據編程語言:Java基礎JavaScript for Qt Quick(QML)深入淺出Java的反射深入淺出Java5新特性Java基礎語法之基礎知識-Java基礎視頻_深入淺出精華版
7樓
qq_21801751 2015-09-25 20:07發表 [回復] 請問,三維噪聲也是相同的原理嗎?
6樓
z18770085003 2014-12-21 16:45發表 [回復] 你上面那些二維素組都是width在外循環么?感覺怎么和一般矩陣的存儲方式相反了呢?一般是內循環才是width呀。。。不知道我理解對了么?
5樓
z18770085003 2014-12-21 15:46發表 [回復] 大神還在不?最近在學習柏林噪聲,但是你這個代碼還有很多地方不懂,有沒有完整的代碼,就是直接可以運行出來那種,我程序也是一個新手
4樓
z18770085003 2014-12-21 15:45發表 [回復] 大神還在不?最近在學習柏林噪聲,但是你這個代碼還有很多地方不懂,有沒有完整的代碼,就是直接可以運行出來那種,我程序也是一個新手
3樓
rex_zhu 2014-03-24 16:00發表 [回復] 萬能的樓主啊,還在嗎,為啥我用了您的代碼以后,輸出的數組和輸入的數組完全一樣啊.......一番運算后白噪聲還是白噪聲 Re: gloomyfish 2014-03-24 16:03發表 [回復] 回復rex_zhu:可能你運算精度不對,或者什么的,總之原理就是這個
或者是你的lookup color table有問題!
2樓
fulongfuhu 2013-07-15 08:22發表 [回復] 用你寫的MapGray函數 同樣是一塊一塊的,我感覺是平滑函數這里有問題,我是用vc改寫的 Re: gloomyfish 2013-07-15 09:20發表 [回復] 回復fulongfuhu:有可能是計算精度的問題,我run Java一直沒問題啊! Re: fulongfuhu 2013-07-15 16:46發表 [回復] 回復jia20003:可以把文章中帶界面的java程序源碼給一份嗎? Re: fulongfuhu 2013-07-15 20:11發表 [回復] 回復fulongfuhu:jingshishengxu@gmail.com,謝謝 Re: fulongfuhu 2013-07-15 20:19發表 [回復] 回復fulongfuhu:不用了,弄好了,是我代碼一個地方改錯了,謝謝 Re: gloomyfish 2013-07-15 22:24發表 [回復] 回復fulongfuhu:贊!
1樓
fulongfuhu 2013-07-14 08:07發表 [回復] 我用你的代碼,為什么出來的火焰效果是一塊一塊的,不連續呢? Re: gloomyfish 2013-07-14 15:25發表 [回復] 回復fulongfuhu:應該不會吧,你有調整color table嘛,一定要調整color table
總結
以上是生活随笔為你收集整理的柏林噪声产生火焰等纹理的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。