2017-04-07 46 views
0

我是佩林噪音的新手,我遇到了障礙。我從C++翻譯過來的perlin噪聲函數似乎可以正常工作於一個八度音階,但是我發現較低的八度音階不會添加到原始的Perlin噪聲中。這裏是我的代碼:佩林噪音沒有得到更深的Octaves

public class Perlin { 
    float[][] generateWhiteNoise(int width, int height) { 
     Random random = new Random(0); 
     float[][] noise = new float[width][height]; 

     for (int i = 0; i < noise.length; i++) { 
      for (int j = 0; j < noise[i].length; j++){ 
       noise[i][j] = (float)random.nextDouble(); 
      } 
     } 

     return noise; 
    } 

    float[][] generateSmoothNoise(float[][] baseNoise, int octave){ 
     int width = baseNoise.length; 
     int height = baseNoise[0].length; 

     float[][] smoothNoise = baseNoise; 

     int samplePeriod = (int) Math.pow(2,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; 
    } 

    float interpolate(float x0, float x1, float alpha){ 
     return (float) ((float)(x0) * (float)(1 - alpha) + (float)(alpha * x1)); 
    } 

    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 = .5f; 

     //generate smooth noise 
     for (int i = 0; i<octaveCount; i++) { 
      System.out.println("Generating Smooth Noise: " + 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; 
      System.out.println("Adding smooth noise for octave: " + octave + " at amplitude: " + 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; 
    } 

    public float[][] printVals(float[][] baseNoise){ 
     baseNoise = generatePerlinNoise(generateWhiteNoise(800,800),6); 
     for(int i = 0; i<baseNoise.length; i++){ 
      String row = ""; 
      for(int j = 0; j<baseNoise[i].length;j++){ 
       row+= (int)(baseNoise[i][j]*255) + " "; 
      } 
      System.out.println(row); 
     } 
     return baseNoise; 
    } 
} 

下面是在代碼中,我用得到的值:

baseNoise = generatePerlinNoise(generateWhiteNoise(800,800),6); 

這裏是在八度1,2,3的輸出,以及4

Frequency 1 Frequency 2 Frequency 3 Frequency 4

任何HEL p將不勝感激!

編輯: 經過反覆試驗,我發現,爲了有問題,最有可能的區域是在generatePerlinNoise()功能。如果我改變八度音,我會得到所需的噪音水平,這是我想要的。這也意味着generateWhiteNoise()generateSmoothNoise()的作品。所以,在generatePerlinNoise()混合的地方有一個問題,但它似乎應該工作。

回答

0

我找到了答案。我曾認爲generateSmoothNoise()命令會給我多個八度perlin噪音。然而,我意識到我需要建立另一個類似混合平滑噪音以混合我不同的八分之一貝林噪音的命令。

public float[][] generateMultiOctavePerlinNoise(int octaves, double persistence, double dropoff, int width, int height){ 
     float[][][]noise = new float[octaves][width][height]; 
     for(int i = octaves - 1; i > 0;i--){ 
      noise[i] = generatePerlinNoise(generateWhiteNoise(width,height),octaves - i); 
     } 

     float[][] multiOctave = new float[width][height]; 

     for(int a= 0; a<noise.length; a++){ 
      persistence*= dropoff; 
      for(int i = 0; i<multiOctave.length; i++){ 
       for(int j = 0; j<multiOctave[i].length; j++){ 
        multiOctave[i][j] += noise[a][i][j]*persistence; 
       } 
      } 
     } 
     return multiOctave; 

    }