• 柏林噪声产生火焰等纹理 分类: 视频图像处理 2015-07-24 09:32 29人阅读 评论(0) 收藏


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

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

    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;

        }

    程序完全源代码如下:

    1. package com.gloomyfish.perlin.noise;  
    2.   
    3. import java.util.Random;  
    4.   
    5. public class PerlinNoiseCreator {  
    6.       
    7.     private int[][] angryFireColorTable = {  
    8.             {255255204},    {255255204},    {255255204},    {255255204},  
    9.             {255255204},    {255255204},    {255255204},    {255255204},    {255255204},  
    10.             {255255204},    {255255204},    {255255204},    {255255204},    {255255204},  
    11.             {255255204},    {255255204},    {255255204},    {255255204},    {255255204},  
    12.             {255255204},    {255255204},    {255255204},    {255255204},    {255255204},  
    13.             {255255204},    {255255204},    {255255204},    {255255204},    {255255204},  
    14.             {255255204},    {255255204},    {255255204},    {255255204},    {255255204},  
    15.             {255255204},    {255255204},    {255255204},    {255255204},    {255255199},      
    16.             {255255199},    {255255197},    {255255197},    {255255193},    {255255193},  
    17.             {255255191},    {255255191},    {255255189},    {255255189},    {255255185},  
    18.             {255255185},    {255255183},    {255255183},    {255255179},    {255255179},  
    19.             {255255177},    {255255177},    {255255175},    {255255175},    {255255171},          
    20.             {255255171},    {255255169},    {255255169},    {255255167},    {255255167},  
    21.             {255255163},    {255255161},    {255255157},    {255255155},    {255255153},  
    22.             {255251149},    {255249147},    {255246144},    {255244142},    {255242140},  
    23.             {253244205},    {248246197},    {248246187},    {248245178},    {248245168},  
    24.             {247245160},    {248243149},    {247244141},    {249243133},    {248243123},  
    25.             {249242112},    {248242102},    {24824292}, {24724181}, {24824173},  
    26.             {24724063}, {24923953}, {24723942}, {24923832}, {24923826},  
    27.             {24823421}, {24823121}, {25022425}, {24821824}, {24921426},  
    28.             {24920926}, {25220432}, {25119832}, {25119133}, {25118634},  
    29.             {25017935}, {25217638}, {25216941}, {25216441}, {25415744},  
    30.             {25415146}, {25314547}, {25414149}, {25113647}, {25313548},  
    31.             {25113047}, {25012946}, {24912646}, {24712444}, {24612043},  
    32.             {24411841}, {24311542}, {24111340}, {24211141}, {24010939},  
    33.             {23910440}, {23610137}, {2349935},  {2359734},  {2329334},  
    34.             {2319132},  {2298832},  {2278630},  {2278330},  {2258128},  
    35.             {2247827},  {2227625},  {2237227},  {2217025},  {2196624},  
    36.             {2166322},  {2165821},  {2125419},  {2105018},  {2094517},  
    37.             {2064014},  {2063714},  {2033212},  {200299},   {200249},  
    38.             {197216},   {195177},   {191133},   {19073},    {18851},  
    39.             {18420},    {18000},    {17800},    {17400},    {17200},  
    40.             {16910},    {16401},    {16000},    {15800},    {15400},  
    41.             {15000},    {14600},    {14400},    {14001},    {13602},  
    42.             {13301},    {13000},    {12610},    {12402},    {12001},  
    43.             {11600},    {11200},    {10911},    {10400},    {10301},  
    44.             {9800}, {9500}, {9210}, {9210}, {9000},  
    45.             {8910}, {8800}, {8600}, {8600}, {8400},  
    46.             {8400}, {8210}, {8210}, {8000}, {8000},  
    47.             {7911}, {7800}, {7600}, {7600}, {7400},  
    48.             {7400}, {7201}, {7201}, {7000}, {7000},  
    49.             {6912}, {6801}, {6601}, {6601}, {6400},  
    50.             {6210}, {6111}, {6000}, {6000}, {6000},  
    51.             {5800}, {5800}, {5601}, {5601}, {5400},  
    52.             {5400}, {5210}, {5100}, {5001}, {5001},  
    53.             {4911}, {4800}, {4600}, {4600}, {4401},  
    54.             {4201}, {4201}, {4000}, {4000}, {3900},  
    55.             {3800}, {3800}, {3600}, {3500}, {3400},  
    56.             {3400}, {3201}, {3000}, {3000}, {2910},  
    57.             {2800}, {2800}, {2601}, {2400}, {2210},  
    58.             {2210}, {2110}, {2000}, {1911}, {1911},  
    59.             {1600}, {1600}, {1600}, {1400}, {1200},  
    60.             {1200}, {1110}, {1000}, {910},  {800},  
    61.             {600},  {600},  {510},  {400},  {210},  
    62.             {210},  {111},  {000},  {000},  {000},  
    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. }  

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

  • 相关阅读:
    js兼容性问题总结
    style设置/获取样式的问题 和 offsetWidth/offsetHeight的问题
    常用SQL总结
    完美运动框架,兼容性好,可多次调用
    JS—实现拖拽
    java设计模式——享元模式
    java设计模式——适配器模式
    java设计模式——装饰者模式
    java设计模式——外观模式(门面模式)
    java设计模式——单例模式(三)
  • 原文地址:https://www.cnblogs.com/mao0504/p/4706375.html
Copyright © 2020-2023  润新知