Шум Перлина - что я делаю не так?

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

Вот мой метод Java.

private static double[][] createNoise(int xn, int yn, int sps) {
    int m = yn * sps;
    int n = xn * sps;
    double[][] u = new double[yn + 1][];
    double[][] v = new double[yn + 1][];

    double[][] x = new double[m][];
    double[][] y = new double[m][];
    double[][] z = new double[m][];

    for (int i = 0; i < m; i++) {
        x[i] = new double[n];
        y[i] = new double[n];
        z[i] = new double[n];
    }
    for (int i = 0; i < yn + 1; i++) {
        u[i] = new double[xn + 1];
        v[i] = new double[xn + 1];
    }

    for (int i = 0; i < xn + 1; i++) {
        for (int j = 0; j < yn + 1; j++) {
            u[i][j] = nextRandom();
            v[i][j] = nextRandom();
        }
    }
    double hx = xn / (n - 1);
    double hy = yn / (m - 1);
    for (int i = 0; i < m; i++) {
        for (int j = 0; j < n; j++) {
            x[i][j] = hx * j;
            y[i][j] = hy * i;
        }
    }

    for (int i = 0; i < m; i++) {
        for (int j = 0; j < n; j++) {
            int xc = (int)x[i][j];
            int yc = (int)y[i][j];

            if (x[i][j] % 1 == 0 && x[i][j] != 0 ) xc = xc - 1;
            if (y[i][j] % 1 == 0 && y[i][j] != 0 ) yc = yc - 1;

            double xr = x[i][j] - xc;
            double yr = y[i][j] - yc;
            double s11[] = {-xr, -yr};
            double s21[] = {-xr, 1 - yr};
            double s22[] = {1 - xr, 1 - yr};
            double s12[] = {1 - xr, -yr};

            double q11 = s11[0] * u[yc][xc] + s11[1] * v[yc][xc];
            double q21 = s21[0] * u[yc + 1][xc] + s21[1] * v[yc + 1][xc];
            double q22 = s22[0] * u[yc + 1][xc + 1] + s22[1] * v[yc + 1][xc + 1];
            double q12 = s12[0] * u[yc][xc + 1] + s12[1] * v[yc][xc + 1];

            z[i][j] = lerp(x[i][j], y[i][j], xc, xc + 1, yc, yc + 1, q11, q12, q21, q22);
        }
    }

    return z;
}

К сожалению, карта высот, которую возвращает метод, выглядит так:

введите здесь описание изображения

Как видите, первая строка/столбец работает, но после этого алгоритм, похоже, дает сбой. Я убедился, что метод

nextRandom();

возвращает значение с плавающей запятой между -1 и 1.

Большое спасибо!


person Bram    schedule 18.07.2013    source источник
comment
Я ничего не знаю о шуме перлина, но одна из ваших проблем здесь: hx = xn / (n - 1); он почти всегда даст вам 0, потому что в java этот оператор обрабатывается как деление двух целых чисел, а результат - целое число, а затем приводится к двойному   -  person gawi    schedule 18.07.2013
comment
Ну вот, спасибо, сэр, вы только что спасли положение!   -  person Bram    schedule 18.07.2013
comment
Не имея полного исходного кода (например, функции lerp), я не могу быть уверен, но буду ли я прав, если скажу, что каждый раз, когда вы запускаете это, вы получаете различный шум (nextRandom() для меня красный флаг). Наиболее полезными свойствами шума перлина является его воспроизводимость; то есть вы можете получить конкретное значение шума для (x, y) в любое время; зная только некоторую информацию о посеве и координаты (x, y). Это особенно полезно для бесконечных миров, где создание всего мира за один раз явно невозможно.   -  person Richard Tingle    schedule 18.07.2013


Ответы (1)


Спасибо пользователю @gawi за указание на это.

hx = xn / (n - 1);

разделит 2 целых числа и, скорее всего, вернет 0. Вы можете исправить это, приведя к нему двойное число:

double hx = (double)xn / (n - 1);

Тогда карта просто работает!

person Bram    schedule 18.07.2013
comment
Я знаю, но он говорит мне, что я должен ждать 2 дня -.- - person Bram; 18.07.2013
comment
@gawi Сначала вы должны опубликовать это как ответ;) - person joe776; 18.07.2013
comment
@ joe776 Я знаю, но я не был уверен, что это проблема: иногда люди делают такие вещи намеренно, и я действительно ничего не знаю об этом шуме перлина :D - person gawi; 18.07.2013
comment
@gawi Я имел в виду, что он не может принять это, так как вы разместили это только как комментарий;) Было приятно заметить это целочисленное деление! - person joe776; 18.07.2013
comment
@ joe776 Я знаю, но он может принять свой пост с ответом :), кстати, Harm-Jan, вы должны исправить и вторую строку;) (hy = yn / (m - 1);) или, если это не имеет значения, тогда измените свой код сделать его более эффективным - person gawi; 18.07.2013