2012-03-06 4 views
0

Я использую функцию шума perlin для генерации данных для игры, которую я создаю, но по какой-то причине она возвращает возвращающие точные результаты для разных входных данных. Я провел 4 часа, пытаясь отладить это на моей функции FBM и не мог понять, поэтому я попробовал улучшенную функцию шума Кен Перлина, и то же самое происходит.Функция шума Perlin, возвращающая одинаковые результаты для разных входов

Кто-нибудь знает, почему это так? Что это хороший способ исправить? Единственное, что мне удалось сделать, это добавить десятичное значение, например .6473, в координаты x и y, что помогло, но ввело другие проблемы, такие как значения, повторяющиеся внутри массивов.

Вот несколько тестовых кодов. Я пытаюсь создать два разных 2D массива, заполненных значениями шума. Входы x и y являются координатами из моей игры. На линиях с '* *' после них, если я не увеличу эти значения, оба массива будут заполнены всеми нулями. В этом примере координаты (0.0, -768.0) и (-1024.0, -768.0) возвращают одинаковые значения шума. В моей игре 9 разных координат возвращают одни и те же значения.

Функция шума Перлина Я использую для этого теста here

public class TestPerlinMain 
{ 
    public static void main(String[] args) 
    { 
     int seed = 532434; 

     //create first noise array 
     double x = 0.0; //x-coordinate 
     double y = -768.0; //y-coordinate 
     float z = 10.0f; 

     double[][] test = new double[15][15]; 

     System.out.println("Noise Array 1: "); 

     for(int i = 0; i < test.length; i++) 
     { 
      for(int j = 0; j < test[i].length; j++) 
      { 
       test[i][j] = ImprovedNoise.noise(x + (j * 64.0), y + (i * 64.0), 10.0); 
       x += .314f;//************ 

       System.out.print(test[i][j] + " "); 
      } 
      y += .314f;//*********** 

     } 
     System.out.println(); 

     //create 2nd noise array 
     double x2 = -1024.0; //x coordinate 
     double y2 = -768.0; //y coordinate 
     float z2 = 10.0f;  

     System.out.println(); 

     double[][] test2 = new double[15][15]; 

     System.out.println("Noise Array 2: "); 

     for(int i = 0; i < test2.length; i++) 
     { 
      for(int j = 0; j < test2[i].length; j++) 
      { 
       test2[i][j] = ImprovedNoise.noise(x2 + (j * 64.0), y2 + (i * 64.0), 10.0); 
       x2 += .314f;//************* 

       System.out.print(test2[i][j] + " "); 
      } 
      y2 += .314f;//************ 

     } 
     System.out.println(); 
    } 

ответ

2

Перлина шум определяется как 0 во всех точках сетки (целое х, у, г). Вы можете доказать это сами, вручную имитируя его в коде, который вы связали. Так как x, y и z все становятся равными 0, когда их полы вычитаются, то grad() значение равно 0, поэтому lerp() значения равны 0.

Есть несколько способов получить шум вы хотите. Во-первых, если вы используете нецелое значение z, тогда вы должны получить случайные значения шума. Однако, поскольку ваш интервал между сетками 64 намного больше, чем уровень шума, это будет выглядеть как статический, а не шум Perlin. Лучшим подходом было бы увеличить шум, сделав что-то вроде noise(j/4., i/4., z). Сэмплирование по 4 балла по каждой шумовой ячейке позволит увидеть некоторую гладкость шума.

Заметим также, что ваша реализация шума разработана, чтобы повторить с плитками размером 256 в каждом направлении (см первую строку noise(). Вот почему вы получите повторяющиеся значения каждый 4 в массиве.

+0

Я попробовал все, что вы Я сделал z не значением int int и получил те же результаты. Я также попытался масштабировать шум, как вы предложили, сделав шум (j/4, i/4, z) и получив те же результаты. Кроме того, вы имеете в виду плиту размером 256x256 или массив, содержащий 256 плиток? – theDazzler

+0

Точка, которую я пыталась сделать в последнем абзаце, состоит в том, что функция шума повторяется каждые 256 (по x, y и z). Таким образом, значение в (1, 3) совпадает с значением (257, 259) или (1, 769) или вообще (x + 256n, y + 256 м). Поскольку 1024 и 768 являются множественными e из 256, конечно, второй массив соответствует первому. –

+0

Я проверю это, когда вернусь домой. В любом случае, я функция FBM, я просто использовал это для тестирования. Я получил его для работы прошлой ночью, внеся несколько изменений, но я не думаю, что это идеально. – theDazzler