Огромные процедурно порожденные миры дикой природы

76

Я уверен, что вы все знаете о таких играх, как Dwarf Fortress - массивная, процедурно созданная пустыня и земля. Как то так, взято из этой очень полезной статьи.

Однако мне было интересно, как я могу применить это в гораздо большем масштабе; приходит на ум масштаб Minecraft (не так ли это, как 8-кратный размер земной поверхности?). Псевдо-бесконечный, я думаю, лучшим термином будет.

: D

В статье рассказывается о фрактальном перлин-шуме. Я ни в коем случае не эксперт в этом, но я понимаю общую идею (это какой-то случайно генерируемый шум, который является полукогерентным, а не просто случайными значениями пикселей).

Я мог бы просто определить области X по размеру X, добавить некоторые вещи типа загрузки областей и иметь один бит шума, генерирующий область. Но это привело бы к огромному количеству островов.

С другой стороны, я не думаю, что смогу действительно создать сверхмассивный лист перлин-шума. Думаю, это будет один большой остров.

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

Коммунистическая утка
источник
9
«приведет к огромному количеству островов» - или он генерирует землю с озерами, если вы просто поменяете местами землю / воду.
3
Тем не менее, вы получите большое количество озер по довольно стандартной схеме.
Коммунистическая Утка
3
@Kylotan: Mincraft бесконечного размера (ну, не совсем, но он действительно большой ... общий объем = long.MaxValue x 128 x long.MaxValue). Следовательно, он не генерирует весь мир за один раз и не сохраняет всю карту в памяти. Он генерирует области блоков 16x128x16 асинхронно, если они не посещались ранее, в противном случае он загружает их с диска.
Зфедоран
2
@ Коммунистическая утка: Да, это правда, в игре, подобной майнкрафт, можно использовать от 2 до 4 байтов данных на блок, но нужно сохранить только один байт, когда он больше не виден (один байт описывает тип блока другие байты описывают освещение и другие данные, которые могут быть пересчитаны позже). Вот где это становится интересным, вы можете использовать RLE, чтобы радикально уменьшить хранимый размер до нескольких байтов, поскольку блоки, как вы упомянули, несколько согласованы.
Зфедоран
4
«Действительно большой» не то же самое, что бесконечное, и вы не можете использовать эти два термина взаимозаменяемо. Если вы увеличиваете карту по мере того, как и когда она обнаруживается, это конечный размер, который увеличивается по требованию - совсем другое предложение, нежели бесконечность. Каждый бит роста может быть создан по мере необходимости. Данные о местности в Minecraft очень легко поддаются обычному сжатию, поскольку между данными существует высокая степень согласованности. (например, RLE, как уже упоминалось.)
Kylotan

Ответы:

35

Я думаю, что я лучше понимаю, что вы спрашиваете сейчас.

Шум не случайный - он выглядит случайным образом, но полностью основан на математической формуле и повторяется. Вся информация закодирована в формуле. Это означает, что вы можете иметь формулу, которая потенциально покрывает бесконечную область, и просто использовать формулу для координат нужной области. Когда вам нужна смежная область, вы просто повторно используете формулу для новых координат, и, поскольку формула выдает непрерывные значения, области будут объединяться без проблем.

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

Формула это: height(x,y) = sin(x/20)

Игра начинается, и мы генерируем высоты для близлежащей области, т.е. (0,0) - (9,0):

[0.0, 0.05, 0.10, 0.15, 0.20, 0.25, 0.30, 0.34, 0.39, 0.43]

У нас есть холм, поднимающийся вправо. Допустим, мы подошли к концу и теперь должны сгенерировать значения от (10,0 до 19,0):

[0.48, 0.52, 0.56, 0.61, 0.64, 0.68, 0.72, 0.75, 0.78, 0.81]

Обратите внимание, что холм неуклонно растет, и что значение в (10,0) хорошо следует из значения в (9,0). Это потому, что функция синуса непрерывна, что означает, что если вы введете в нее 2 соседних числа, вы получите 2 соседних результата - для определенного определения смежных. Поэтому, если вы используете свои мировые координаты в качестве параметров для функции, которая определяет ваш мир, вы получите непрерывный ландшафт, который объединяется независимо от того, сколько или мало его вы генерируете одновременно. Когда вы генерируете новые детали, они автоматически перетекают из существующих деталей, потому что высота уже задана.

Если мир не изменится, вам даже не нужно ничего хранить, поскольку вы можете точно рассчитать, какова высота в любой заданной точке из формулы. Очевидно, что с чем-то вроде Minecraft мир полностью деформируется, так что вы просто сохраняете каждый кусок, когда создаете его. Учитывая, что существует высокая степень согласованности между соседними блоками (т. Е. Если 1 блок - это трава, скорее всего, что блок рядом с ним будет тоже травой), вы можете сжимать данные очень эффективно - будет работать кодировка длины прогона хорошо, но тогда так будет почти любой стандартный алгоритм сжатия.

В то время как я говорил о высоте как о наиболее очевидном значении, вы можете использовать ту же систему для создания любой характеристики, которую вы хотите. Используйте математическую функцию с непрерывными свойствами, и в качестве входных данных используются ваши мировые координаты, которые могут определять наличие наземных ориентиров, месторождений полезных ископаемых, точек появления и т.д. (Очевидно, что значения в одной формуле могут повлиять на другую - нет смысла размещать залежи угля в воздухе, поэтому вы генерируете карту высот мира, а затем вычисляете возможности угля только для блоков, которые находятся достаточно глубоко под землей.)

Kylotan
источник
Вы определенно помогли прояснить ситуацию, спасибо. :) Но что-то вроде шумовой функции не будет непрерывным. И AFAICS, если это будет продолжаться, я не получу «случайный» мир. Или я что-то здесь упускаю?
Коммунистическая утка
Извините за двойной комментарий, но я чувствую, что выше это отдельно от этого. Когда вы говорите «используйте мировые координаты для шума перлина», будет ли это такой же эффект, как при генерации «огромного» листа шума, но по частям? Сегодня я чувствую себя немного медленно.
Коммунистическая утка
Что ж, генерация вашего шума, безусловно, может быть непрерывной, и обычно это происходит, потому что вы сглаживаете ее. Чтобы сгладить границы, вам может потребоваться немного прочитать границы, но принцип остается тем же. Если рассматриваемый шум требует псевдослучайных данных, то вы генерируете его из известных величин - т.е. хэш координат вашего мира. Выходные данные тогда предсказуемы.
Kylotan
2
Что касается случайности, у каждого мира может быть свое собственное начальное значение, которое используется в вычислениях. например. грех (х + семя) вместо греха (х), в моем примере выше. Каждое другое семя создаст другой мир. А что касается огромного листа ... Я не уверен, какое отношение это имеет. Неважно, сколько или мало вы генерируете или когда вы это делаете. Начальное состояние мира определяется математической формулой, и вы просто используете эту формулу, чтобы обнаружить это состояние по мере необходимости.
Kylotan
32

Этот урок, который я написал несколько лет назад, может дать вам нечто похожее на то, что вы хотите:

альтернативный текст

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

необычайно щедрый
источник
7
Великолепные визуализации!
Зфедоран
3
Я помню, как использовал этот учебник, когда делал магистерскую диссертацию по моделированию природных явлений. Я использовал пример "холма", чтобы создать небесный купол над своим трехмерным миром. Отличное введение в концепцию генерации местности.
C.McAtackney
1
Сумасшедший, это круто! Я не знал, что кто-нибудь когда-либо действительно использовал это.
Великолепно
1
О, МОЙ БОГ !!! Я тоже использовал это в предыдущем проекте ... самый простой способ создания ландшафта, с которым я когда-либо сталкивался !!!
война
15

Чтобы создать большой остров, вам не нужно создавать его все сразу. Я бы строил регионы асинхронно, когда вы их посещаете.

Вместо того чтобы использовать маску для создания острова, как описано в статье, одну вещь, которую вы можете сделать, это поиграть с длинами волн октанового шума, чтобы добиться желаемого вида. Обычно первая октава описывает общую форму местности. Все октавы после него просто добавляют более мелкую зернистость. Поэтому играйте с длиной волны первой октавы, чтобы контролировать, насколько большими будут ваши земные массы. Если вы хотите, чтобы суша находилась в центре, вы можете просто уменьшить карту высот по мере удаления от центра, а затем нормализовать шум. Например, представьте, что можете объединить эти два элемента для создания своего острова:

первая октава подробности

Эта статья должна помочь: http://freespace.virgin.net/hugo.elias/models/m_perlin.htm

Если вы хотите узнать о бесконечных трехмерных мирах и о различных хитростях, которые вы можете использовать, чтобы изменить внешний вид ландшафта, играя с входным и выходным шумом, загляните в эту статью: http://http.developer.nvidia.com /GPUGems3/gpugems3_ch01.html

Это может быть немного трудно читать, если вы не знакомы с графическим конвейером и шейдерным программированием.

zfedoran
источник
Эффект, которого я хочу достичь, это что-то вроде 2d сверху вниз карты Майнкрафта (а не игры) ... если бы я использовал меньше октав, разве мне не нужно было бы генерировать огромный лист перлин-шума? Или я мог бы как-то сгенерировать очень-очень маленькое его количество?
Коммунистическая утка
Я думаю, вы все еще можете быть немного озадачены тем, как работает перлин-шум. Вы можете генерировать отдельные блоки размером 16x16, отправив функции смещения координат x и y для шума перлина. Обратите внимание, как функция PerlinNoise_2D (float x, float y) принимает координаты x и y. Другими словами, он генерирует шум для некоторой (x, y) позиции. Кроме того, генерирование меньшего количества октав не то же самое, что изменение длины волны октав. Меньше октав => Менее мелкая зернистость. Более
длинная волна
Кроме того, вот статья с кодом, который показывает вам, как реализовать увеличение / увеличение длины волны: dreamincode.net/forums/topic/66480-perlin-noise
zfedoran
7

Шум Перлина и друзья - хорошая отправная точка, но вы, вероятно, хотите сделать еще один шаг вперед. Большинство популярных генераторов на основе шума дадут вам довольно неинтересные результаты. Чтобы сделать ландшафт реалистичным, вы должны взглянуть на алгоритмы, эмулирующие эффекты эрозии. Один из самых продвинутых симуляторов игрового мира - Dwarf Fortress - делает симуляцию эрозии одним из этапов построения мира.

Одно из довольно крутых решений, которые я видел, было описано в статье «Усовершенствованное осаждение частиц» в Game Programming Gems 7. В Интернете доступно много других, поэтому есть много ресурсов, из которых можно извлечь (например, 1 или 2 ). ,

Доминик Д
источник