Проблемы с реализацией экспоненциально распределенных шумов Perlin - PullRequest
1 голос
/ 28 октября 2019

Я пытался реализовать улучшенный алгоритм Perlin Noise code paper in c#. Тем не менее, я получаю очень странные результаты - хотя я пересматривал свою версию кода снова и снова. Это моя функция шума:

public static float sample(float x, float y) {
    float tx = x + 4096;
    int bx0 = ((int) tx) & 255;
    int bx1 = (bx0 + 1) & 255;
    float rx0 = tx - (int) tx;
    float rx1 = rx0 - 1f;

    float ty = y + 4096;
    int by0 = ((int) ty) & 255;
    int by1 = (by0 + 1) & 255;
    float ry0 = ty - (int) ty;
    float ry1 = ry0 - 1f;

    int b00 = p[(p[bx0] + by0) & 255];
    int b10 = p[(p[bx1] + by0) & 255];
    int b01 = p[(p[bx0] + by1) & 255];
    int b11 = p[(p[bx1] + by1) & 255];

    float sx = s_curve(rx0);

    float u1 = m[b00] * (rx0 * g[b00].x + ry0 * g[b00].y);
    float v1 = m[b10] * (rx1 * g[b10].x + ry0 * g[b10].y);
    float a = Mathf.Lerp(sx, u1, v1);

    float u2 = m[b01] * (rx0 * g[b01].x + ry1 * g[b01].y);
    float v2 = m[b11] * (rx1 * g[b11].x + ry1 * g[b11].y);
    float b = Mathf.Lerp(sx, u2, v2);

    float sy = s_curve(ry0);
    return Mathf.Lerp(sy, a, b);
}

Где p - это случайно отсортированный массив целых чисел от 0 до 255, g - это массив из 256 нормализованных случайных двумерных векторов, а m - этопервые 256 элементов набора 1.02^-n.

Вот такие результаты я получаю (без дополнительных октав): noise map

Кто-нибудь получитЛюбая идея, где это идет не так?

1 Ответ

0 голосов
/ 28 октября 2019

На самом деле я допустил две ошибки:

  1. Переключен порядок аргументов для Math.Lerp, он должен быть Mathf.Lerp(sx, u1, v1, sx); вместо Mathf.Lerp(sx, u1, v1);, например

  2. Я округляю, приводя к целому числу - однако это вызывает проблемы с отрицательными координатами. Это должно быть изменено на Mathf.FloorToInt (как я использую Unity)

Итак, после этих изменений это мой (рабочий) код: public static float sample (float x, floaty) {float tx = x + 4096;int bx0 = Mathf.FloorToInt (tx) & 255;int bx1 = (bx0 + 1) & 255;float rx0 = tx - Mathf.FloorToInt (tx);float rx1 = rx0 - 1f;

float ty = y + 4096;
int by0 = Mathf.FloorToInt(ty) & 255;
int by1 = (by0 + 1) & 255;
float ry0 = ty - Mathf.FloorToInt(ty);
float ry1 = ry0 - 1f;

int b00 = p[(p[bx0] + by0) & 255];
int b10 = p[(p[bx1] + by0) & 255];
int b01 = p[(p[bx0] + by1) & 255];
int b11 = p[(p[bx1] + by1) & 255];

float sx = s_curve(rx0);

float u1 = m[b00] * (rx0 * g[b00].x + ry0 * g[b00].y);
float v1 = m[b10] * (rx1 * g[b10].x + ry0 * g[b10].y);
float a = Mathf.Lerp(u1, v1, sx);

float u2 = m[b01] * (rx0 * g[b01].x + ry1 * g[b01].y);
float v2 = m[b11] * (rx1 * g[b11].x + ry1 * g[b11].y);
float b = Mathf.Lerp(u2, v2, sx);

float sy = s_curve(ry0);
return Mathf.Lerp(a, b, sy);

}

...