柏林噪声产生火焰等纹理

柏林噪声是一种特殊的随机噪声,即对于每个给定的值产生的随机数是唯一的,但是不同的

值产生不同的随机数。关于柏林噪声更详细的解释可以参考这里:

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

柏林噪声产生火焰等纹理的相关文章

Photoshop制作漂亮的立体火焰字

本教程非常详细的介绍了立体火焰字的制作方法.教程把文字及火焰效果分开来做.先制作立体字,方法有很多,最好把每一个字安置在一个图层.火焰部分利用了一些火焰及纹理素材,制作的时候需要注意细节部分的修饰. 最终效果 第一部分:立体字的制作: 先来看一下效果.     1.新建文档,填充黑色,输入文字,颜色设为红色,栅格化文字. 2.ctrl+T对文字进行变形处理,方法见下图. 3.按住ctrl键,鼠标点击文字图层,按住ctrl+alt,鼠标按键盘向上方向键,完成后ctrl+J复制.   分类: PS文

Photoshop制作一个火焰球

火焰球的制作思路非常简单.先用选区及图层样式做出一个球体,然后在上面增加火焰及纹理素材,渲染出火焰的效果即可. 最终效果 1.打开PS,新建800 * 800像素的文档,首先制作背景层.打开渐变工具,设置好颜色后,由画布中心向外部做一个径向渐变,然后再在此图层上新建图层,填充自制的图案. 2.使用椭圆工具,按住Shift + Alt从中心做一个圆,并对此图层进行如下图设置. 3.下面为这个珠子添加一些火焰素材,将素材摆好位置,再把图层模式改为"滤色",然后用蒙版工具擦出多余部分. 4.

Photoshop 鼠绘梦幻冰火天使

  笔者本次给大家带来冰火天使的详尽绘制教程,力求将冰火两重感觉都赋予到天使身上,给大家带来不一样的视觉感受,更多的方法还要请大家多多指教,共同进步.先看效果图. Photoshop绘制冰火天使最终效果图 本次"冰火天使"这个效果图运用到了PS的几大功能的综合: 1."抽出"功能制作升腾的"冰气息" 2."扭曲"功能制作天使翅膀骨架部分; 3."云彩"."径向模糊"功能制作火焰部分和背景

OpenCV+OpenGL 双目立体视觉三维重建

0.绪论 这篇文章主要为了研究双目立体视觉的最终目标--三维重建,系统的介绍了三维重建的整体步骤.双目立体视觉的整体流程包括:图像获取,摄像机标定,特征提取(稠密匹配中这一步可以省略),立体匹配,三维重建.我在做双目立体视觉问题时,主要关注的点是立体匹配,本文主要关注最后一个步骤三维重建中的:三角剖分和纹理贴图以及对应的OpenCV+OpenGL代码实现. 1.视差计算 1.1基于视差信息的三维重建 特征提取 由双目立体视觉进行三位重建的第一步是立体匹配,通过寻找两幅图像中的对应点获取视差.Op

利用PS纹理素材及图层样式制作火焰熔岩字

熔岩字制作方法有很多,最快捷的就是直接使用纹理素材.制作效果之前,自己找一些有裂纹的纹理素材,然后用图层样式等加强纹理效果及颜色,后期渲染高光及火焰等即可. photoshop教程最终效果 <点小图查看大图> 1.打开下图所示的背景素材. <点小图查看大图> 2.加一个小小的径向渐变,反向如下图,混合模式改为"正片叠底". 3.输入文字,字体找个粗大的.做效果的字体一定要粗大. 4.给文字添加图层样式: 描边-大小1PX.内部.混合模式浅色.类型渐变颜色是FB8

Photoshop制作立体纹理火焰字

纹理火焰字跟其它火焰字制作思路基本一致,只是在制作火焰字之前,需要先给文字增加一些独特的纹理,如裂纹或其它材质.这样做出的火焰字更有个性. 最终效果 <点小图查看大图> 1.首先选择自己喜欢的字体,在Ai里面转为矢量,然后通过添加一些笔触,增加书法字体的形式感.这里可以直接先保存下图所示的PNG素材图片,新建一个800 * 600像素的文件,背景填充黑色,把文字素材拖进来,填充为白色. 2.给字体增加材质,打开下图所示的纹理素材,拖到文字上面,载入文字选区,按Ctrl + J把选区部分的纹理复

利用纹理及火焰素材制作绚丽的火焰立体字

这里介绍的火焰字是使用火焰素材来完成的.过程:先设置好想要的文字,如果喜欢立体效果,就需要用3D等做出立体字:然后用纹理素材给文字表面增加一些纹理,并用火焰素材叠加到文字上面:后期给文字周围及画布的其它位置增加一些火焰即可. 最终效果 1.新建一个黑色背景1400px * 782px的文档,我们将从使用下载的碎石纹理准备大地开始.在Photoshop中打开这个纹理并画选区. 2.复制粘贴这个选区到我们的文件,并使用自由变换来改变选区的角度. 3.使用软橡皮工具减淡纹理的边缘. [1] [2] [

PS怎么制作纹理质感火焰字体

  最终效果 PS怎么制作纹理质感火焰字体 1.首先选择自己喜欢的字体,在Ai里面转为矢量,然后通过添加一些笔触,增加书法字体的形式感.这里可以直接先保存下图所示的PNG素材图片,新建一个800 * 600像素的文件,背景填充黑色,把文字素材拖进来,填充为白色 2.给字体增加材质,打开下图所示的纹理素材,拖到文字上面,载入文字选区,按Ctrl + J把选区部分的纹理复制到新的图层

Photoshop制作大气的教师节火焰纹理字

  效果字的层次比较多,由立体面.金属边框.火焰纹理三大部分构成.制作的时候也是把文字多复制几层,立面图及金属边框都是用图层样式来完成,火焰纹理层使用了火焰图案,再加上一些浮雕效果即可. 最终效果 教程开始之前,我们先定义一款图案.点击下图打开纹理素材大图,然后右键选择"图片另存为"保存到本机,然后用PS打开,选择菜单:编辑 > 定义图案,命名后关闭图片. <点小图查看大图> 1.按Ctrl + N 新建画布,大小为1280 * 634像素,分辨率为72像素/英寸,如