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
  1. package com.gloomyfish.perlin.noise;
  2. import java.util.Random;
  3. public class PerlinNoiseCreator {
  4. private int[][] angryFireColorTable = {
  5. {255, 255, 204},    {255, 255, 204},    {255, 255, 204},    {255, 255, 204},
  6. {255, 255, 204},    {255, 255, 204},    {255, 255, 204},    {255, 255, 204},    {255, 255, 204},
  7. {255, 255, 204},    {255, 255, 204},    {255, 255, 204},    {255, 255, 204},    {255, 255, 204},
  8. {255, 255, 204},    {255, 255, 204},    {255, 255, 204},    {255, 255, 204},    {255, 255, 204},
  9. {255, 255, 204},    {255, 255, 204},    {255, 255, 204},    {255, 255, 204},    {255, 255, 204},
  10. {255, 255, 204},    {255, 255, 204},    {255, 255, 204},    {255, 255, 204},    {255, 255, 204},
  11. {255, 255, 204},    {255, 255, 204},    {255, 255, 204},    {255, 255, 204},    {255, 255, 204},
  12. {255, 255, 204},    {255, 255, 204},    {255, 255, 204},    {255, 255, 204},    {255, 255, 199},
  13. {255, 255, 199},    {255, 255, 197},    {255, 255, 197},    {255, 255, 193},    {255, 255, 193},
  14. {255, 255, 191},    {255, 255, 191},    {255, 255, 189},    {255, 255, 189},    {255, 255, 185},
  15. {255, 255, 185},    {255, 255, 183},    {255, 255, 183},    {255, 255, 179},    {255, 255, 179},
  16. {255, 255, 177},    {255, 255, 177},    {255, 255, 175},    {255, 255, 175},    {255, 255, 171},
  17. {255, 255, 171},    {255, 255, 169},    {255, 255, 169},    {255, 255, 167},    {255, 255, 167},
  18. {255, 255, 163},    {255, 255, 161},    {255, 255, 157},    {255, 255, 155},    {255, 255, 153},
  19. {255, 251, 149},    {255, 249, 147},    {255, 246, 144},    {255, 244, 142},    {255, 242, 140},
  20. {253, 244, 205},    {248, 246, 197},    {248, 246, 187},    {248, 245, 178},    {248, 245, 168},
  21. {247, 245, 160},    {248, 243, 149},    {247, 244, 141},    {249, 243, 133},    {248, 243, 123},
  22. {249, 242, 112},    {248, 242, 102},    {248, 242, 92}, {247, 241, 81}, {248, 241, 73},
  23. {247, 240, 63}, {249, 239, 53}, {247, 239, 42}, {249, 238, 32}, {249, 238, 26},
  24. {248, 234, 21}, {248, 231, 21}, {250, 224, 25}, {248, 218, 24}, {249, 214, 26},
  25. {249, 209, 26}, {252, 204, 32}, {251, 198, 32}, {251, 191, 33}, {251, 186, 34},
  26. {250, 179, 35}, {252, 176, 38}, {252, 169, 41}, {252, 164, 41}, {254, 157, 44},
  27. {254, 151, 46}, {253, 145, 47}, {254, 141, 49}, {251, 136, 47}, {253, 135, 48},
  28. {251, 130, 47}, {250, 129, 46}, {249, 126, 46}, {247, 124, 44}, {246, 120, 43},
  29. {244, 118, 41}, {243, 115, 42}, {241, 113, 40}, {242, 111, 41}, {240, 109, 39},
  30. {239, 104, 40}, {236, 101, 37}, {234, 99, 35},  {235, 97, 34},  {232, 93, 34},
  31. {231, 91, 32},  {229, 88, 32},  {227, 86, 30},  {227, 83, 30},  {225, 81, 28},
  32. {224, 78, 27},  {222, 76, 25},  {223, 72, 27},  {221, 70, 25},  {219, 66, 24},
  33. {216, 63, 22},  {216, 58, 21},  {212, 54, 19},  {210, 50, 18},  {209, 45, 17},
  34. {206, 40, 14},  {206, 37, 14},  {203, 32, 12},  {200, 29, 9},   {200, 24, 9},
  35. {197, 21, 6},   {195, 17, 7},   {191, 13, 3},   {190, 7, 3},    {188, 5, 1},
  36. {184, 2, 0},    {180, 0, 0},    {178, 0, 0},    {174, 0, 0},    {172, 0, 0},
  37. {169, 1, 0},    {164, 0, 1},    {160, 0, 0},    {158, 0, 0},    {154, 0, 0},
  38. {150, 0, 0},    {146, 0, 0},    {144, 0, 0},    {140, 0, 1},    {136, 0, 2},
  39. {133, 0, 1},    {130, 0, 0},    {126, 1, 0},    {124, 0, 2},    {120, 0, 1},
  40. {116, 0, 0},    {112, 0, 0},    {109, 1, 1},    {104, 0, 0},    {103, 0, 1},
  41. {98, 0, 0}, {95, 0, 0}, {92, 1, 0}, {92, 1, 0}, {90, 0, 0},
  42. {89, 1, 0}, {88, 0, 0}, {86, 0, 0}, {86, 0, 0}, {84, 0, 0},
  43. {84, 0, 0}, {82, 1, 0}, {82, 1, 0}, {80, 0, 0}, {80, 0, 0},
  44. {79, 1, 1}, {78, 0, 0}, {76, 0, 0}, {76, 0, 0}, {74, 0, 0},
  45. {74, 0, 0}, {72, 0, 1}, {72, 0, 1}, {70, 0, 0}, {70, 0, 0},
  46. {69, 1, 2}, {68, 0, 1}, {66, 0, 1}, {66, 0, 1}, {64, 0, 0},
  47. {62, 1, 0}, {61, 1, 1}, {60, 0, 0}, {60, 0, 0}, {60, 0, 0},
  48. {58, 0, 0}, {58, 0, 0}, {56, 0, 1}, {56, 0, 1}, {54, 0, 0},
  49. {54, 0, 0}, {52, 1, 0}, {51, 0, 0}, {50, 0, 1}, {50, 0, 1},
  50. {49, 1, 1}, {48, 0, 0}, {46, 0, 0}, {46, 0, 0}, {44, 0, 1},
  51. {42, 0, 1}, {42, 0, 1}, {40, 0, 0}, {40, 0, 0}, {39, 0, 0},
  52. {38, 0, 0}, {38, 0, 0}, {36, 0, 0}, {35, 0, 0}, {34, 0, 0},
  53. {34, 0, 0}, {32, 0, 1}, {30, 0, 0}, {30, 0, 0}, {29, 1, 0},
  54. {28, 0, 0}, {28, 0, 0}, {26, 0, 1}, {24, 0, 0}, {22, 1, 0},
  55. {22, 1, 0}, {21, 1, 0}, {20, 0, 0}, {19, 1, 1}, {19, 1, 1},
  56. {16, 0, 0}, {16, 0, 0}, {16, 0, 0}, {14, 0, 0}, {12, 0, 0},
  57. {12, 0, 0}, {11, 1, 0}, {10, 0, 0}, {9, 1, 0},  {8, 0, 0},
  58. {6, 0, 0},  {6, 0, 0},  {5, 1, 0},  {4, 0, 0},  {2, 1, 0},
  59. {2, 1, 0},  {1, 1, 1},  {0, 0, 0},  {0, 0, 0},  {0, 0, 0},
  60. };
  61. public void generateNoise(int[] noiseData, int rows, int cols) {
  62. float[][] whiteNoise = GenerateWhiteNoise(rows, cols);
  63. float[][] perlinNoise = GeneratePerlinNoise(whiteNoise, 6); // default value is 6
  64. //float[][] colorData = MapGradient(perlinNoise);
  65. float[][] colorData = MapGray(perlinNoise);
  66. int index = 0;
  67. for(int row = 0; row<rows; row++) {
  68. for(int col=0; col<cols; col++) {
  69. index = row * cols + col;
  70. noiseData[index] = (int)colorData[row][col];
  71. }
  72. }
  73. }
  74. public float[][] GenerateWhiteNoise(int width, int height)
  75. {
  76. Random random = new Random(System.currentTimeMillis()); //Seed to 0 for testing
  77. float[][] noise = new float[width][height];
  78. for (int i = 0; i < width; i++)
  79. {
  80. for (int j = 0; j < height; j++)
  81. {
  82. noise[i][j] = (float)random.nextDouble();
  83. }
  84. }
  85. return noise;
  86. }
  87. public float[][] GenerateSmoothNoise(float[][] baseNoise, int octave)
  88. {
  89. int width = baseNoise.length;
  90. int height = baseNoise[0].length;
  91. float[][] smoothNoise = new float[width][height];
  92. int samplePeriod = 1 << octave; // calculates 2 ^ k
  93. float sampleFrequency = 1.0f / samplePeriod;
  94. for (int i = 0; i < width; i++)
  95. {
  96. //calculate the horizontal sampling indices
  97. int sample_i0 = (i / samplePeriod) * samplePeriod;
  98. int sample_i1 = (sample_i0 + samplePeriod) % width; //wrap around
  99. float horizontal_blend = (i - sample_i0) * sampleFrequency;
  100. for (int j = 0; j < height; j++)
  101. {
  102. //calculate the vertical sampling indices
  103. int sample_j0 = (j / samplePeriod) * samplePeriod;
  104. int sample_j1 = (sample_j0 + samplePeriod) % height; //wrap around
  105. float vertical_blend = (j - sample_j0) * sampleFrequency;
  106. //blend the top two corners
  107. float top = Interpolate(baseNoise[sample_i0][sample_j0],
  108. baseNoise[sample_i1][sample_j0], horizontal_blend);
  109. //blend the bottom two corners
  110. float bottom = Interpolate(baseNoise[sample_i0][sample_j1],
  111. baseNoise[sample_i1][sample_j1], horizontal_blend);
  112. //final blend
  113. smoothNoise[i][j] = Interpolate(top, bottom, vertical_blend);
  114. }
  115. }
  116. return smoothNoise;
  117. }
  118. public float Interpolate(float x0, float x1, float alpha)
  119. {
  120. return x0 * (1 - alpha) + alpha * x1;
  121. }
  122. public float[][] GeneratePerlinNoise(float[][] baseNoise, int octaveCount)
  123. {
  124. int width = baseNoise.length;
  125. int height = baseNoise[0].length;
  126. float[][][] smoothNoise = new float[octaveCount][][]; //an array of 2D arrays containing
  127. float persistance = 0.5f; // default value is 0.5f
  128. //generate smooth noise
  129. for (int i = 0; i < octaveCount; i++)
  130. {
  131. smoothNoise[i] = GenerateSmoothNoise(baseNoise, i);
  132. }
  133. float[][] perlinNoise = new float[width][height];
  134. float amplitude = 1.0f;
  135. float totalAmplitude = 0.0f;
  136. //blend noise together
  137. for (int octave = octaveCount - 1; octave >= 0; octave--)
  138. {
  139. amplitude *= persistance;
  140. totalAmplitude += amplitude;
  141. for (int i = 0; i < width; i++)
  142. {
  143. for (int j = 0; j < height; j++)
  144. {
  145. perlinNoise[i][j] += smoothNoise[octave][i][j] * amplitude;
  146. }
  147. }
  148. }
  149. //normalization
  150. for (int i = 0; i < width; i++)
  151. {
  152. for (int j = 0; j < height; j++)
  153. {
  154. perlinNoise[i][j] /= totalAmplitude;
  155. }
  156. }
  157. return perlinNoise;
  158. }
  159. float[][] MapGray(float[][] perlinNoise)
  160. {
  161. int width = perlinNoise.length;
  162. int height = perlinNoise[0].length;
  163. float[][] image = new float[width][height];
  164. int ta=0, tr=0, tb=0, tg=0;
  165. for (int i = 0; i < width; i++)
  166. {
  167. for (int j = 0; j < height; j++)
  168. {
  169. ta = 255;
  170. int u = (int)(perlinNoise[i][j] * (float)80.0);
  171. tr = u+100;
  172. tg = u+100;
  173. tb = u+100;
  174. //ta = (int)(255.0f * perlinNoise[i][j]);
  175. image[i][j] = (ta << 24) | (tr << 16) | (tg << 8) | tb;
  176. }
  177. }
  178. return image;
  179. }
  180. float[][] MapGradient(float[][] perlinNoise)
  181. {
  182. int width = perlinNoise.length;
  183. int height = perlinNoise[0].length;
  184. float[][] image = new float[width][height];
  185. int ta=0, tr=0, tb=0, tg=0;
  186. for (int i = 0; i < width; i++)
  187. {
  188. for (int j = 0; j < height; j++)
  189. {
  190. ta = 255;
  191. int u = (int)(perlinNoise[i][j] * (float)angryFireColorTable.length);
  192. tr = (int)angryFireColorTable[u][0];
  193. tg = (int)angryFireColorTable[u][1];
  194. tb = (int)angryFireColorTable[u][2];
  195. image[i][j] = (ta << 24) | (tr << 16) | (tg << 8) | tb;
  196. }
  197. }
  198. return image;
  199. }
  200. }

版权声明:本文为博主原创文章,未经博主允许不得转载。

  • 上一篇图像处理之快速均值模糊(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

柏林噪声产生火焰等纹理相关推荐

  1. 柏林噪声(Perlin Noise)

    什么是柏林噪声? 说起噪声大家可能会想起这个: 但是这个噪声看起来很不自然,而且现实中的自然噪声并不长这个样子,比如起伏的山脉,大理石的纹理,天空的云彩,这些噪声虽然看起来杂乱无章,其实它们都有着内在 ...

  2. Unity 使用柏林噪声(Perlin Noise)生成网格地图

    前言 最近在尝试制作一个基于网格地图的RPG游戏,所以想着自己生成一个网格地图. 但是网格地图的生成有很多的方式,大多数的方式都达不到我的要求,我需要一个地图可以随机生成各种地形,也可以储存一些地形数 ...

  3. 【转载】柏林噪声算法

    转载自:https://www.cnblogs.com/leoin2012/p/7218033.html   原作者:立航 柏林噪声是一个非常强大算法,经常用于程序生成随机内容,在游戏和其他像电影等多 ...

  4. 一篇文章搞懂柏林噪声算法,附代码讲解

    本文目的是以一种通俗简单的方式介绍Ken Perlin的改进版柏林噪声算法,讲解代码采用c#编写,开源免费使用.如果你只是想看完整代码,点击这里. 柏林噪声是一个非常强大算法,经常用于程序生成随机内容 ...

  5. 木木的Unity学习笔记(四)—— Unity中的柏林噪声(Perlin Noise)

    木木的Unity学习笔记(四)-- Unity中的柏林噪声 柏林噪声是一个非常强大算法,经常用于程序生成随机内容,在游戏和其他像电影等多媒体领域广泛应用.算法发明者Ken Perlin也因此算法获得奥 ...

  6. html 生成image java makenoise,[图形学] 柏林噪声 (perlin noise)

    参考论文:<An Image Synthesizer> Ken Perlin 如果你是游戏玩家,你也许曾在游戏风景中驻足,并仔细观察草木和岩石的贴图,并感叹于它那看似杂乱而又自然的纹脉.你 ...

  7. 3D数学之柏林噪声(Perlin Noise)

    好了,转入正题. 其实它的原理并不是很难,但是由于网上实现的版本太多太杂,真要实现起来竟然不知从何处下手,而且自己写的时候会遇到各种各样的问题.最终写出来了,所以很欣然. 先看下,我在网上找的一些资料 ...

  8. 柏林噪声算法制作地图+小地图

    以上是效果展示 1,柏林噪声算法做地图代码 using System.Collections; using System.Collections.Generic; using UnityEngine; ...

  9. VTK:柏林噪声用法实战

    VTK:柏林噪声用法实战 程序输出 程序完整源代码 程序输出 程序完整源代码 #include <vtkActor.h> #include <vtkCamera.h> #inc ...

最新文章

  1. 用easyui动态创建一个对话框
  2. 【蓝桥java】递归基础之输出连续数字
  3. js解析json字符串数组
  4. SAP Spartacus 开发规范
  5. A small tip to explore how to call a method of a control
  6. java定时器_拾遗Timer定时器
  7. ios 销毁当前页面重新开启_问:如何强制销毁iOS中的视图控制器?
  8. mobile.php discuz,电脑访问discuz手机版【触屏版跳转标准版的修改方法】
  9. Getter DI是个好主意吗?
  10. python画同心圆程序_Python Turtle:使用circle()方法绘制同心圆
  11. Ext3和Ext4文件系统
  12. spring学习---IOC--基于xml--bean管理--spring创建对象--spring注入属性--其他属性注入--外部bean--内部bean
  13. jquery插件库免费下载,原生下载非扣代码,jq22 vip下载方法
  14. Wii 补充运动利器
  15. c语言网络套接字讲解,C语言学习笔记-网络与套接字
  16. HAU寒假训练第二周
  17. User Agreement(APP用户协议)
  18. 实现数据开放共享的方法
  19. 云数据库有什么用?有了云服务器为什么还要云数据库?
  20. HDU 5441并查集 by cyl

热门文章

  1. java valueof的用法_Java SignStyle valueOf()用法及代码示例
  2. mysql 并行复制搭建_基于GTID的主从实践系列之④并行复制搭建及测试
  3. admui 能再php上用吗,Javascript 方法
  4. 在XCode中使用SVN
  5. 用来定制shell环境 set/shopt
  6. sap系统操作流程财务软件_金蝶财务软件的操作流程汇总
  7. linux trap命令
  8. iOS应用间相互跳转
  9. MySQL复制类型介绍
  10. [Scheduled Timer]第三回:事件存储(EventStorage)