Создание ландшафта с использованием маршевых кубов

Я искал в Интернете, но не нашел ничего, что могло бы мне помочь, поэтому я прошу здесь.

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

https://www.dropbox.com/s/w99lvynrfra2a5v/question.JPG

Как вы можете видеть на этом снимке экрана, все испорчено.

Это проблема с функцией шума? Я использую простую функцию шума Perlin. Как я могу получить такой результат:

http://www.youtube.com/watch?v=-hJkrr5Slv8

Если проблема связана с шумом, что мне нужно изменить для достижения этого? Я хочу создать естественную местность с холмами, горами, равнинами и т. Д.

(Я использую Unity3D, но я не думаю, что это имеет значение.)

5 голосов | спросил Sammael 3 Mayam13 2013, 03:06:59

2 ответа


2

Я предлагаю уменьшать вертикальную составляющую точки выборки перед выборкой функции шума.

Начальная точка местности воксела в видео выглядит как карта высот, поэтому они могут умножить компонент на 0.

Кроме того, вы должны добавить вертикальный компонент к функции поля.

, поэтому ваша полевая функция должна выглядеть примерно так:

const float noise_vertical_scale = 0.2;
const float field_vertical_scale = 0.01;
const float iso_surface = 0.5;

/*
 * returns field at point (pos):
 *     negative = inside
 *     0 = surface
 *     positive = outside
 */
float sampleField(vector3 pos)
{
    vector3 sample_pos = pos;
    sample_pos.y *= scale;
    return noise3D(sample_pos) + pos.y * field_height_scale - iso_surface;
}

Надеюсь, что это поможет.

ответил DaleyPaley 3 Mayam13 2013, 04:51:29
3

Хорошая новость: ваш алгоритм Marching Cubes выглядит просто отлично! Эта трехмерная реконструкция выглядит великолепно. Если вы привержены принципу, основанному на вокселе, с визуальной визуализацией поверхности, вы прекратите свое начало.

Проблема в том, что 3D-шум в этой форме действительно не подходит для использования с алгоритмом маршевого кубического типа для местности. Если вы хотите, чтобы у вас была возможность сделать модификацию ландшафта, на которую, по вашему мнению, указывает демоверсия, я бы предположил, что нужно построить высоту first , а затем построить ваши объемные данные на основе карты высот.

Построение карты высот в первую очередь относительно прямолинейно; Я бы просто использовал один из классических фрактальных методов. Вы можете использовать такой подход, как смещение средней точки с квадратным алмазом (возможно, наиболее распространенное), но я бы рекомендовал подход, основанный на Фурье, потому что он должен позволить вам намного больше контролировать, как «перекатывать» ваш ландшафт (и вы всегда можете «postfilter», применяя эффект гамма-типа, например, устанавливая h (x, y) -> c * h (x, y) ^ 3 или h (x, y) -> c * sqrt (h (x, y)), чтобы сделать рельеф более или менее зазубренным - если вы посмотрите на ранние статьи по фрактальной местности, вы увидите многое из этого).

Как только вы получите данные о карте высот, существует множество различных процедур для преобразования этой информации в объемные данные. Для простоты я предполагаю, что данные вашей карты высот были сохранены с более высоким разрешением, чем у ваших воксельных данных; это имеет большой смысл, поскольку 3D-массив с тем же разрешением XY (очевидно) должен быть намного больше, чем карта высот 2d. Самый простой способ сделать это так же просто, как

for (0 < vx < VOXEL_X_RES) {
  for (0 < vy < VOXEL_Y_RES) {
    pick the closest point (x,y) on the heightmap corresponding to (vx,vy) 
    (e.g. x = HEIGHTMAP_X_RES*vx/VOXEL_X_RES, etc)
    find the z value of the heightmap at (x,y) (and convert it to a voxel-space value vz)
    fill every value below (vx, vy, vz) with 1 to indicate it's in the terrain
    fill every value above (vx, vy, vz) with 0
  }
}

Поскольку это заполняет массив вокселей только 0 и 1, это может означать, что интерполяция маршевых кубов вдоль ребер выглядит слишком «регулярной» и приводит к поверхностям со слишком большим количеством одинаковых наклонов. Вместо этого вы можете захотеть «подвыбрать» карту высот, чтобы построить массив вокселей, используя что-то вроде:

for (0 < vx < VOXEL_X_RES) {
  for (0 < vy < VOXEL_Y_RES) {
    find all 'pixels' on the heightmap corresponding to (vx,vy)
    for ( 0 < vz < VOXEL_Z_RES) {
      compute how many of the pixels in the set above have z > vz
      set the value of the voxel array at (vx, vy, vz) to the proportion of pixels with z > vz
    }
  }
}

Набор пикселей на карте высот для этой второй версии может быть любым из прямой подвыборки сетки (т. е. найти hxmin = HEIGHTMAP_X_RES*vx/VOXEL_X_RES и ---- +: = 3 =: + ----, аналогично для hxmax = HEIGHTMAP_X_RES*(vx+1)/VOXEL_X_RES и hymin и рассмотрим все пиксели hymax с помощью (hx, hy) и (hxmin <= hx < hxmax)) к подходу с перекрывающимися образцами где вы смотрите на каждый пиксель высотой в круге, сосредоточенном вокруг, где (vx, vy) отображается на карте высот; вы даже можете подвыражать свою карту высот и интерполировать между пикселями высотной карты для более тонких деталей.

Одно из основных предостережений с этим целым подходом заключается в том, что фрактальная местность на самом деле не очень «ориентирована на местности» - она ​​знает высоту, но ничего не знает о функциях : она не действительно знать, что такое река или ее влияние на окружающую географию; он не может легко различать между «старой» и «новой» географией; и т. д. Если вы хотите по-настоящему реалистичную местность, то вам следует рассмотреть некоторые из более симуляционных подходов, но они, как правило, напрямую противоречат видам модификаций ландшафта, которые показывают связанное видео, поэтому, если реализм является вашей целью, тогда, возможно, стоит переосмыслить voxel полностью.

ответил Steven Stadnicki 3 Mayam13 2013, 05:12:18

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132