2013-06-06 2 views
1

Недавно я работал с перлинским шумом, и, внедряя его в мозаичный движок, я использую, я заметил, что функция шума perlin создала «блоки», как показано на рисунке ниже. Каждый пиксель представляет собой другое другое местоположение в массиве 500 на 500, которое возвращается из функции шума perlin.Perlin Noise Generation не работает должным образом

в этом примере живучесть составляет 0,5 с подсчетом октавы 5 enter image description here

При воспроизведении с ней дальше, тем больше октав у меня есть, чем больше блок кусковых.

Вот код, который я использую, чтобы вызвать функцию Перлин шума:

PerlinNoise p = new PerlinNoise(); 
//returns a float[][] array of 500 by 500 
p.GeneratePerlinNoise(p.genWhiteNoise(500, 500), 5, (float) 0.1); 

шумом Перлина класс

импорт java.util.Random;

public class PerlinNoise { 
Random r; 

public PerlinNoise() { 
    r = new Random(); 
} 

public void setSeed(long seed) { 
    r.setSeed(seed); 
} 

public void printOutArray(float[][] arr) { 
    for(int i = 0; i < arr.length; i++) { 
     for(int n = 0; n < arr[0].length; n++) { 
      System.out.print(arr[i][n] + ", "); 
     } 
     System.out.print("\n"); 
    } 
} 

public void printOutTerrain(float[][] arr) { 
    for(int i = 0; i < arr.length; i++) { 
     for(int n = 0; n < arr[0].length; n++) { 
      float a = arr[i][n]; 
      if(a < 0.4) { 
       System.out.print("W"); 
      } else { 
       System.out.print("L"); 
      } 
     } 
     System.out.print("\n"); 
    } 
} 

//-------------------------------------------------------------// 

float[][] genWhiteNoise(int width, int height) { 
    float[][] noise = new float[height][width]; 

    for(int y = 0; y < height; y++) { 
     for(int x = 0; x < width; x++) { 
      noise[y][x] = r.nextFloat(); 
     } 
    } 

    return noise; 
} 

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

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

    int samplePeriod = 1 << octave; //calculates 2^k 
    float sampleFrequency = (float) (1.0/samplePeriod); 

    for(int i = 0; i < height; i++) { 
     int sample_i0 = (i/samplePeriod) * samplePeriod; 
     int sample_i1 = (sample_i0 + samplePeriod) % height; //wrap around 
     float vertical_blend = (i - sample_i0) * sampleFrequency; 

     for(int n = 0; n < width; n++) { 
      int sample_n0 = (n/samplePeriod) * samplePeriod; 
      int sample_n1 = (sample_n0 + samplePeriod) % width; //wrap around 
      float horizontal_blend = (n - sample_n0) * sampleFrequency; 

      //blend the top two corners 
      float top = Interpolate(baseNoise[sample_i0][sample_n0], 
       baseNoise[sample_i1][sample_n0], horizontal_blend); 

      //blend the bottom two corners 
      float bottom = Interpolate(baseNoise[sample_i0][sample_n1], 
       baseNoise[sample_i1][sample_n1], horizontal_blend); 

      //final blend 
      smoothNoise[i][n] = Interpolate(top, bottom, vertical_blend); 
     } 
    } 

    return smoothNoise; 
} 

float[][] GeneratePerlinNoise(float[][] baseNoise, int octaveCount, float persistance) 
{ 
    int height = baseNoise.length; 
    int width = baseNoise[0].length; 

    float[][][] smoothNoise = new float[octaveCount][][]; //an array of 2D arrays containing 

    //generate smooth noise 
    for (int i = 0; i < octaveCount; i++) 
    { 
     smoothNoise[i] = genSmoothNoise(baseNoise, i); 
    } 

    float[][] perlinNoise = new float[height][width]; 
    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 < height; i++) 
     { 
      for (int j = 0; j < width; j++) 
      { 
      perlinNoise[i][j] += smoothNoise[octave][i][j] * amplitude; 
      } 
     } 
    } 

    //normalisation 
    for (int i = 0; i < height; i++) 
    { 
     for (int j = 0; j < width; j++) 
     { 
     perlinNoise[i][j] /= totalAmplitude; 
     } 
    } 

    return perlinNoise; 
} 

//linear average between two points 
float Interpolate(float x0, float x1, float alpha) 
{ 
    return Cosine_Interpolate(x0, x1, alpha); 
} 

//Linear Interpolation 
float Linear_Interpolate(float x0, float x1, float alpha) 
{ 
    return x0 * (1 - alpha) + alpha * x1; 
} 

//Cosine interpolation (much smoother) 
float Cosine_Interpolate(float x0, float x1, float alpha) 
{ 
    float ft = (float) (alpha * 3.141592653589); 
    float f = (float) ((1 - Math.cos(ft)) * 0.5); 

    return x0*(1-f) + x1*f; 
} 


} 

Так повторить свой вопрос: Почему моя функция шума Перлина ведет себя так, как это делает, как только формировать пространство на куски?

+0

Просить людей обнаружить ошибки в вашем коде не особенно продуктивно. Вы должны использовать отладчик (или добавить заявления печати), чтобы изолировать проблему, отслеживая ход вашей программы и сравнивая ее с тем, что вы ожидаете. Как только двое расходятся, вы нашли свою проблему. (И затем, если необходимо, вы должны построить [минимальный тестовый сценарий] (http://sscce.org).) –

ответ

3

Чтобы исправить это, все, что мне нужно было сделать, это обмен переменных vertical_blend и horizontal_blend в методе genSmoothNoise(). Удивительно, что вы заметили после перерыва.

Смежные вопросы