Обтекание 2D перлин-шума - PullRequest
       17

Обтекание 2D перлин-шума

11 голосов
/ 08 апреля 2011

Я работаю с Perlin Noise для алгоритма генерации карты высот, я хотел бы сделать так, чтобы он был обернут вокруг краев, чтобы его можно было рассматривать как непрерывное ... Есть ли простой способ или хитрость сделать это? Я думаю, что мне нужно что-то вроде сферического шума, чтобы горизонтально или вертикально он обвился вокруг. Я был бы счастлив также только с 1 осью обертывания, но две были бы лучше.

Сейчас я использую классический алгоритм, в котором вы можете установить, сколько октав вы хотите добавить и какие множители используются для изменения амплитуды и частоты волн между каждой последующей октавой.

Заранее спасибо!

1 Ответ

8 голосов
/ 08 апреля 2011

Шум Перлина получается как сумма сигналов. Сигналы получают путем интерполяции случайных значений, и сигналы более высоких октав имеют меньшие коэффициенты масштабирования, тогда как интерполированные случайные значения ближе друг к другу. Чтобы это обернуть, вам просто нужно правильно интерполировать вокруг осей Y и X обычным тороидальным образом, т.е. если ваша ось X простирается от x_min до x_max, а крайняя левая случайная точка (которая интерполируется) равна в x0 и в крайнем правом положении в x1 (x_min

Здесь псевдокод для одной из октав с использованием линейной интерполяции. Предполагается, что матрица 256 x 256, где размер сетки шума Перлина представляет собой степень двух пикселей ... просто для того, чтобы сделать ее читаемой. Представьте себе, например, размер == 16:

 wrappable_perlin_octave(grid, size):
   for (x=0;x<256;x+=size):
     for (y=0;y<256;y+=size):
       grid[x][y] = random()
   for (x=0;x<256;x+=size):
     for (y=0;y<256;y+=size):
       if (x % size != 0 || y % size != 0): # interpolate
         ax = x - x % size
         bx = (ax + size) % 256 # wrap-around
         ay = y - y % size
         by = (ay + size) % 256 # wrap-around
         h = (x % size) / size # horizontal balance, floating-point calculation
         v = (y % size) / size # vertical balance, floating-point calculation
         grid[x][y] = grid[ax][ay] * (1-h) * (1-v) +
                      grid[bx][ay] * h * (1-v) +
                      grid[ax][by] * (1-h) * v +
                      grid[bx][by] * h * v
...