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. 编程软件python中的if用法-给Python初学者的一些编程技巧
  2. [OSG]OSG的相关扩展
  3. 数据千万条,备份第一条:VFEmail被擦除所有数据面临关停
  4. CES 2018 七大看点前瞻:模块化电视、枪型游戏设备……
  5. JAVA day05 构造方法,this关键字,方法的重载,引用类型数组
  6. 如何对ado.net做比较好的封装?
  7. CMake使用总结,不断更新
  8. 【Android-混合开发】mPaas-多版本接入篇
  9. 关于android studio报错Attempt to invoke virtual method 'void android.widget.ListView.setAdapter(android.
  10. 设计FMEA步骤四:失效分析
  11. 原版XP SP3安装程序集成识别SATA的AHCI驱动的解决方法
  12. 2015QS世界大学排名-[转]
  13. Jmeter 线程数、Ramp-Up、循环次数 详解
  14. 2345看图王总是弹窗广告怎么办?
  15. 自定义进度条PictureProgressBar
  16. 阿里某新员工感慨:入职阿里三个月生活一团糟,天天想离职
  17. 按头安利 好看又实用的运动健身 体育海报模板素材看这里
  18. 基于Web的在线教师备课系统毕业设计
  19. 天线原理答案 魏文元
  20. 公司邮箱一般是什么邮箱?专业的电子邮件可以事半功倍

热门文章

  1. leetcode算法题--Reverse Words in a String
  2. leetcode算法题--矩阵中的路径
  3. 用计算机计算线性卷积的基本规则,实验三_线性卷积与圆周卷积的计算.doc
  4. 二维方向图matlab程序,二维点源阵方向图,阵因子matlab
  5. centos7-yum安装与卸载
  6. Data Lake Analytics: 读/写PolarDB的数据
  7. Java如何调用dll
  8. Centos7环境下etcd集群的搭建
  9. Kubernetes Nginx Ingress 安装与使用
  10. 意外发现:网盾升级后支持soso和有道