Функция Perlin Noise, возвращающая одинаковые результаты для разных входов - PullRequest
0 голосов
/ 06 марта 2012

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

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

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

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

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

1 Ответ

2 голосов
/ 06 марта 2012

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

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

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

...