2017-04-07 12 views
0

저는 Perlin 노이즈에 익숙하지 않으며로드 블록에 부딪혔습니다. C++에서 번역 한 perlin 노이즈 함수는 한 옥타브에서 올바르게 작동하는 것처럼 보입니다. 그러나 노이즈의 낮은 옥타브는 원래의 Perlin Noise에 추가되지 않습니다.Perlin 노이즈가 더 많은 옥타브에서 깊이를 얻지 못합니다.

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

옥타브 1,2,3의 출력, 그리고 4

Frequency 1 : 여기

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; 
    } 
} 

내가 값을 얻기 위해 사용하는의 코드입니다 : 여기 내 코드입니다 Frequency 2 Frequency 3 Frequency 4

모든 HEL P는 인정 될 것이다!

편집 : 문제가있을에 대한 가능성이 가장 높은 지역은 generatePerlinNoise() 기능에 있음을 시행 착오를 통해 , 나는 발견했다. 옥타브를 바꾸면 원하는 잡음 레벨을 얻을 수 있습니다. 이는 generateWhiteNoise()generateSmoothNoise()도 작동한다는 것을 의미합니다. 그래서, 어딘가에 generatePerlinNoise() 블렌딩 내에서 문제가 있지만 작동해야합니다.

답변

0

답변을 찾았습니다. 나는 generateSmoothNoise() 명령이 멀티 옥타브 펄린 노이즈를 줄 것이라고 생각했습니다. 그러나 필자는 필자의 다른 옥타브의 옥타브 노이즈를 혼합하기 위해 부드러운 노이즈의 혼합과 비슷한 다른 명령을 만들어야한다는 것을 깨달았다.

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; 

    }