{ "author_name": "Андрей Верещагин", "author_type": "self", "tags": ["\u043e\u043f\u044b\u0442"], "comments": 23, "likes": 76, "favorites": 59, "is_advertisement": false, "section_name": "gamedev", "id": "12843", "is_wide": "" }
Андрей Верещагин
10 460
Gamedev

Наполнение открытого мира

Быстрое создание красивых и правдоподобных локаций.

Поделиться

В избранное

В избранном

Сотрудник студии Flying Wild Hog Кжижтов Нарковиц (Krzysztof Narkowicz) в блоге на сайте Gamasutra рассказал о создании инструмента, который позволяет наполнять игровые локации растительностью и объектами в короткие сроки.

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

Их создание поднимает вполне закономерный вопрос: как же эффективно их наполнить? Конечно, никто не хочет вручную расставлять каждое деревце, особенно небольшие команды. Когда мы смотрим на типичный открытый игровой мир, мы видим принцип Парето в действии — лишь 20% контента находятся на маршруте следования пользователя, а остальные 80% — это просто фон.

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

После того, как Flying Wild Hog закончили работу над Shadow Warrior 2, у команды появилось время для того, чтобы опробовать новые идеи. Разработчики решили потратить его на создание нового инструмента для размещения объектов. Они знали о том, как создавать базовую карту высот (basic heightmap) в World Machine. Вопрос был в том, как превратить эту карту в красивый пейзаж, не загнав при этом до смерти дизайнеров уровней.

Есть несколько способов: процедурное размещение (procedural placement), размещение, основанное на физике (physics based placement) и размещение на основе карт цвета (painted color maps based placement).

Первый предполагает генерацию контента на основе заранее заданных правил. Они, в свою очередь, могут быть разделены на методы, которые симулируют физические процессы (телеологические) и методы, которые симулируют конечный результат (онтогенетические). Примером использования телеологического метода могут быть леса в третьем «Ведьмаке», созданные с учётом того, как близко и в каком объёме находятся водные ресурсы и как много солнечного света получают растения. Ещё один пример такого подхода — UE4 procedural foliage tool. Этот инструмент моделирует рост нескольких поколений растительности.

Примером онтогенетического метода может быть процедурная генерация, основанная на Houdini. В таком случае художники отдельно прописывают все правила. Метод использовался в Ghost Recon Wildlands.

Размещение, основанное на физике — интересный способ. Объекты будто падают с некоторой высоты и рассеиваются по уровню. Такой метод включён в Object Placement Tool для Unity.

Размещение на основе карт цвета предполагает конвертацию вручную раскрашенных карт цвета в ассеты на основе определённого набора правил. Примером такого подхода может быть инструмент, использованный разработчиками Horizon Zero Dawn.

Первый инструмент Flying Wild Hog был основан на физике. Он использовался в шутере Hard Reset. Его события разворачивались в мрачных городах, выполненных в стилистике киберпанка, поэтому разработчики сделали инструмент, который просто разбрасывал мусор по улицам. Если результат их устраивал, они могли нажать клавишу «сохранить», а в противном случае процедура «разброса» повторялась. Тем не менее, у такого инструмента было много ограничений. Конечный результат тяжело было контролировать, к тому же необходимость раз за разом повторять симуляцию лишь замедляла процесс разработки.

В Shadow Warrior были открытые пространства, на которых росли трава и деревья, поэтому создатели игры сделали инструмент размещения на основе карт цвета. Базовые меши уровня создавались в 3ds Max. Затем художники разукрашивали вертексы (vertex paint) этих мешей, а во время импорта уровня эти вершины конвертировались в набор точек появления растительности.

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

Меш уровня Shadow Warrior

При работе над новым инструментом команда Flying Wild Hog хотела, чтобы конечный результата удовлетворял нескольким критериям:

  • быстрое прототипирование. Это позволит в короткие сроки создавать грубые наброски уровней. Художники, как минимум, должны были иметь возможность указывать, какие из локаций — это лес, а какие — пустыня;

  • простые и безопасные итерации. Разработчикам нужно было иметь возможность вносить какие-то изменения в последнюю минуту так, чтобы не надо было «перестраивать» весь мир;

  • возможность для роста. Небольшие студии не могут позволить себе запланировать разработку в один год, создать ассеты во второй, разместить их и выпустить игру — в третий. Компаниям нужна возможность работать над ассетами на протяжении всего процесса создания игры. Кроме того, необходимо, чтобы разработчики могли безболезненно менять и добавлять их в игру;

  • бесшовная интеграция с контентом, размещаемым вручную.

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

Разработчики хотели по нескольку раз использовать карты цвета биома для того, чтобы ускорить прототипирование. Для этого в основу новой системы легли две карты цвета: тип биома (лес, пустыня, вода и так далее) и влияние (пышность). Низкие значения последних генерировали почти пустую землю, в то время как при высоких параметрах создавались участки с густой растительностью и множеством препятствий.

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

Чтобы возможность для итераций сохранилась, нужно было свести влияние правил к минимуму. Для этого в основе всего легли заранее заданные точки генерации и случайные числа. Например, нужно изменить точки генерации деревьев. Когда вы настраиваете плотность их размещения, появляются новые деревья, но большая часть леса остаётся нетронутой.

После нескольких тестов разработчики решили, что им потребуется процедурная генерация растительности, чтобы «разбавить» повторение паттернов. Эта проблема решилась введением очень низкой плотности размещения особых объектов вроде упавших деревьев.

Правила биома

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

Правила текстурирования достаточно просты:

  • диапазон влияния биома с пользовательским уменьшением;

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

  • диапазон наклона рельефа с пользовательским уменьшением;

  • плотность.

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

Правила размещения объектов несколько сложнее:

  • все указанные выше правила текстур;

  • выравнивание по земле или вертикальной оси. Например, деревья выравниваются по вертикальной оси (потому что они обычно растут вверх), а камни — по земле;

  • случайные смещения по оси выравнивания, которые позволяют избежать повторений;

  • случайное вращение по оси выравнивания;

  • случайное масштабирование;

  • смещение вдоль оси выравнивания;

  • следы (радиус коллизии объекта).

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

Пример распределения влияния для лесного биома

Интеграция биома

Разработчики хотели интегрировать своё решение вместе с объектами, размещёнными вручную и другими инструментами. В случае инструментов, основанных на сплайнах, вроде тех, которые помогают создавать реки или дороги, разработчики аналитически рассчитывали расстояние от сплайна. Полученные данные позволяли автоматически убирать все размещённые объекты с дорог или рек. Более того, плотность биома вокруг сплайнов снижается. Таким образом, растительность у дороги, пролегающей сквозь лесную чащу, будет не такой густой, как в других местах.

Так инструмент создания дорог работает с биомами

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

Рабочий процесс

Он начался с World Machine, в которой разработчики сгенерировали изначальную карту высоты. Следующим шагом стала грубая итерация карт цвета биома в Substance Designer. Система поддерживает автоматический ре-импорт карт, поэтому когда художник нажимает кнопку «сохранить» в Substance Designer, новая карта биома сама импортируется в редактор, и сразу можно увидеть изменения.

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

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

Реализация

Алгоритм размещения объектов сводится к зацикливанию заранее просчитанных точек появления, выборке данных мира в каждой из точек, расчёту плотности на основе правил появления (spawn rules) и сравнении этой информации с заранее рассчитанной минимальной плотностью в той или иной точке. На основе полученных данных принимается решение, нужно ли помещать какой-то объект в эту точку. Под объектами понимаются префабы, то есть сюда могут попасть как деревья, так и триггеры, звуки или спецэффекты, вроде светлячков.

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

  • размещение должно быть настолько плотным, насколько это возможно;

  • между точками должно сохраняться указанное минимальное расстояние;

  • близлежащие объекты не должны располагаться на одной прямой, так как это нарушит иллюзию правдоподобия;

  • вышеуказанные параметры должны быть актуальными и при снижении плотности.

Разработчики пытались сгенерировать расположение точек на основе распределения Пуассона, с дополнительным ограничением — точки не могут быть выровнены по одной прямой. Они остановились на координатной сетке, искривленной набором функций sin и cos. Кроме того, к каждой точке было привязано своё значение влияния, которое просто «размывало» алгоритм, так что параметры сохраняли свою актуальную, когда некоторые точки удалялись из-за снижения плотности появления объектов.

При размещении объектов на земле важно использовать не оригинальную карту высоты, но ту, у которой уже есть пользовательские меши. Для коллизий у разработчиков был двумерный Bitmap, и форма каждого объекта растрировалась под него до размещения.

#опыт

Популярные материалы
Показать еще
{ "is_needs_advanced_access": false }

Комментарии Комм.

Популярные

По порядку

0

Прямой эфир

Узнавайте первым важные новости

Подписаться
[ { "id": 1, "label": "100%×150_Branding_desktop", "provider": "adfox", "adaptive": [ "desktop", "tablet" ], "auto_reload": true, "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "clmf", "p2": "ezfl" } } }, { "id": 2, "label": "1200х400", "provider": "adfox", "adaptive": [ "phone" ], "auto_reload": true, "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "clmf", "p2": "ezfn" } } }, { "id": 3, "label": "240х200 _ТГБ_desktop", "provider": "adfox", "adaptive": [ "desktop" ], "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "clmf", "p2": "fizc" } } }, { "id": 4, "label": "240х200_mobile", "provider": "adfox", "adaptive": [ "phone" ], "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "clmf", "p2": "flbq" } } }, { "id": 5, "label": "300x500_desktop", "provider": "adfox", "adaptive": [ "desktop" ], "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "clmf", "p2": "ezfk" } } }, { "id": 6, "label": "1180х250_Interpool_баннер над комментариями_Desktop", "provider": "adfox", "adaptive": [ "desktop", "tablet" ], "adfox": { "ownerId": 228129, "params": { "pp": "h", "ps": "clmf", "p2": "ffyh" } } }, { "id": 7, "label": "Article Footer 100%_desktop_mobile", "provider": "adfox", "adaptive": [ "desktop", "tablet", "phone" ], "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "clmf", "p2": "fjxb" } } }, { "id": 8, "label": "Fullscreen Desktop", "provider": "adfox", "adaptive": [ "desktop", "tablet" ], "auto_reload": true, "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "clmf", "p2": "fjoh" } } }, { "id": 9, "label": "Fullscreen Mobile", "provider": "adfox", "adaptive": [ "phone" ], "auto_reload": true, "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "clmf", "p2": "fjog" } } }, { "id": 10, "label": "Native Partner Desktop", "provider": "adfox", "adaptive": [ "desktop", "tablet" ], "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "clmf", "p2": "fmyb" } } }, { "id": 11, "label": "Native Partner Mobile", "provider": "adfox", "adaptive": [ "phone" ], "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "clmf", "p2": "fmyc" } } }, { "id": 12, "label": "Кнопка в шапке", "provider": "adfox", "adaptive": [ "desktop", "tablet" ], "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "clmf", "p2": "fdhx" } } }, { "id": 13, "label": "DM InPage Video PartnerCode", "provider": "adfox", "adaptive": [ "desktop", "tablet", "phone" ], "adfox_method": "create", "adfox": { "ownerId": 228129, "params": { "pp": "h", "ps": "clmf", "p2": "flvn" } } }, { "id": 14, "label": "Yandex context video banner", "provider": "yandex", "yandex": { "block_id": "VI-250597-0", "render_to": "inpage_VI-250597-0-549065259", "adfox_url": "//ads.adfox.ru/228129/getCode?p1=bxeub&p2=fpjw&puid1=&puid2=&puid3=&puid4=&puid8=&puid9=&puid21=&puid22=&puid31=&puid32=&fmt=1&pr=" } }, { "id": 15, "label": "Плашка на главной", "provider": "adfox", "adaptive": [ "desktop", "tablet", "phone" ], "adfox": { "ownerId": 228129, "params": { "p1": "byudo", "p2": "ftjf" } } } ]