Berlin noise produces flame and other textures

Source: Internet
Author: User

Berlin noise is a special random noise, that is, the random number generated for each given value is unique, but different

Values generate different random numbers. For more details about Berlin noise, refer to the following:

Http://freespace.virgin.net/hugo.elias/models/m_perlin.htm

 

This article mainly discusses how to use the Berlin noise to produce the flame effect and the texture of the dark cloud effect. Before explaining the implementation code,

First, let's take a look at the two parameters that affect the Berlin noise effect, namely, the audios (ocave) and the persistence (persistence), which can be adjusted.

Texture size and density.

 

Final flame texture Effect

The final dark cloud texture Effect

The final grassland texture effect-how do you feel a little bit of the sprite grass in Warcraft? haha

Code explanation

First, generate random blank noise, use random blank noise to generate Berlin noise, and map the Berlin noise to an RGB value.

The Code is as follows:

Float[] [] Whitenoise = generatewhitenoise (rows, cols );

Float[] [] Perlinnoise = generateperlinnoise (whitenoise, 6 );//

Float[] [] Colordata = mapgray (perlinnoise );

 

White Noise is generated mainly by using the system time in Java as the seed to generate [0 ~ 1] noise Array

The Code is as follows:

Public float[] [] Generatewhitenoise (IntWidth,
IntHeight)

{

Random random =NewRandom (system.Currenttimemillis());

Float[] [] Noise =New float[Width] [height];

For(IntI = 0; I <width; I ++)

{

For(IntJ = 0; j

{

Noise [I] [J] = (Float) Random. nextdouble ();

}

}

ReturnNoise;

}

 

The noise in Berlin is a little more complex. First, we bring the above white noise data into it and use the interpolation formula to produce smooth noise.

Data. The number of smoothing noise data to be generated depends on the Ave parameter. The interpolation formula in this program is very simple,

The Code is as follows:

Public floatInterpolate (FloatX0,
FloatX1,FloatAlpha)

{

ReturnX0 * (1-alpha) + Alpha * x1;

}

Finally, the smooth noise of these groups is combined with different amplitude to generate an output array. The result is the Berlin noise.

The above is not enough to produce the effect of the texture, another top secret is how to put Berlin Noise

Map to the expected RGB value. The Code is as follows:

Float[] [] Mapgradient (Float[] [] Perlinnoise)

{

IntWidth = perlinnoise. length;

IntHeight = perlinnoise [0]. length;

Float[] [] Image =New float[Width] [height];

IntTa = 0, TR = 0, TB = 0, Tg = 0;

For(IntI = 0; I <width; I ++)

{

For(IntJ = 0; j

{

Ta = 255;

IntU = (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;

}

}

ReturnImage;

}

The complete source code of the program is as follows:

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); // default value is 6//float[][] colorData = MapGradient(perlinNoise);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()); //Seed to 0 for testing    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; // calculates 2 ^ k   float sampleFrequency = 1.0f / samplePeriod;    for (int i = 0; i < width; i++)   {      //calculate the horizontal sampling indices      int sample_i0 = (i / samplePeriod) * samplePeriod;      int sample_i1 = (sample_i0 + samplePeriod) % width; //wrap around      float horizontal_blend = (i - sample_i0) * sampleFrequency;       for (int j = 0; j < height; j++)      {         //calculate the vertical sampling indices         int sample_j0 = (j / samplePeriod) * samplePeriod;         int sample_j1 = (sample_j0 + samplePeriod) % height; //wrap around         float vertical_blend = (j - sample_j0) * sampleFrequency;          //blend the top two corners         float top = Interpolate(baseNoise[sample_i0][sample_j0],            baseNoise[sample_i1][sample_j0], horizontal_blend);          //blend the bottom two corners         float bottom = Interpolate(baseNoise[sample_i0][sample_j1],            baseNoise[sample_i1][sample_j1], horizontal_blend);          //final 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][][]; //an array of 2D arrays containing    float persistance = 0.5f; // default value is 0.5f    //generate smooth noise   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;     //blend noise together    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;          }       }    }    //normalization   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;      //ta = (int)(255.0f * perlinNoise[i][j]);      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;}}
Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.