TOTAL RELOAD : процедурная генерация проводов (часть 1)

TOTAL RELOAD : процедурная генерация проводов (часть 1) Gamedev, Unity, Инди игра, Разработка, Инди, Программирование, Видео, Без звука, Длиннопост

Готовы рассказать о процедурной генерации проводов и о том как она устроена в TOTAL RELOAD. Всего проводам будет посвящено 2 статьи (2 части). Выше приведен скриншот из игры на котором представлены финальные провода.

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

Предупреждение: эта статья не является инструкцией, также, скорее всего, она не будет полезна профессиональным программистам, которые имеют опыт работы с процедурной генерацией мешей. Статья содержит картинки, видео и обобщенные объяснения разработанной нами системы генерации проводов и обобщенный ответ на вопрос «что же такое меш (mesh)?» Итак, поехали!

Часть 1. Процедурная генерация проводов

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

Версия провода № 1

В самом начале разработки игры было принято решение не пытаться вытянуть качество графики до уровня ААА – проекта. Причины такого решения просты:

  • команда состояла (и состоит) из 2-х человек, которым задач и так хватало

  • не было уверенности, что все окупится

Итак, в первое время мы разработали «2D» систему проводов, которые были плоскими. Я думал, плоская – это хорошо в плане того, что меньше полигонов и объем проводам можно картами нормалей придать (если потребуется). Ниже представлен первый вариант системы проводов:

TOTAL RELOAD : процедурная генерация проводов (часть 1) Gamedev, Unity, Инди игра, Разработка, Инди, Программирование, Видео, Без звука, Длиннопост

Как работала система проводов:

  • имеется набор вложенных gameObjects – узлы проводов

  • родительский объект создает процедурный mesh с UV. Mesh и UV создаются в зависимости от позиции узлов проводов.

Система позволяла выполнять поставленные задачи:

  • отображала соединения объектов

  • относительно гибко настраивалась

  • генерируемый провод соответствовал первому минималистичному стилю

Меш провода генерировался процедурно по точкам. Здесь видно конечный результат (вариант провода №1):

Провод менял свою геометрию тогда, когда одна из точек меняла свою позицию. Провод мог гнуться на углы +/-90 градусов относительно родительского объекта. Еще одно видео:

Так планировалось прокладывать провод в уровне:

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

И вроде как все были довольны этой системой проводов, но…

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

TOTAL RELOAD : процедурная генерация проводов (часть 1) Gamedev, Unity, Инди игра, Разработка, Инди, Программирование, Видео, Без звука, Длиннопост
TOTAL RELOAD : процедурная генерация проводов (часть 1) Gamedev, Unity, Инди игра, Разработка, Инди, Программирование, Видео, Без звука, Длиннопост
TOTAL RELOAD : процедурная генерация проводов (часть 1) Gamedev, Unity, Инди игра, Разработка, Инди, Программирование, Видео, Без звука, Длиннопост
TOTAL RELOAD : процедурная генерация проводов (часть 1) Gamedev, Unity, Инди игра, Разработка, Инди, Программирование, Видео, Без звука, Длиннопост

У Совы, насколько мы знаем, брови изначально (наверно с рождения) повернуты под 90 градусов. А после всего того, что мы показали, они у нее просто вывернулись на все 360.

Провода нужно было переделывать.

Что не устроило Сову:

  • Обыденность и минималистичность: где-то она уже видела этот провод;

  • Скрытность: он плоский, сбоку его вообще не видно;

  • Повороты кратны 90 градусам: уровень будет иметь углы только кратные 90 градусам, это снижает возможности разработчика уровней до… лучше не думать, даже некоторые первые в мире игры имели стены, которые располагались под произвольными углами.

По проводу все осталось в общем по-старому, только в ТЗ добавилось 4 требования:

  • провод должен гнуться не только на 90 градусов;

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

  • текстура должна тайлиться, а не растягиваться;

  • уникальность проводу нужно придать моделью + материалом.

Пара слов о генерации меша

Хотелось бы чтобы статья содержала больше полезной информации чем просто результаты нашей работы.

Немного глубже затронем тему процедурной генерации мешей.

Что такое меш (mesh)?

Меш – это, условно, модель, которая крепится к компоненту «MeshFilter», который, в свою очередь, принадлежит «GameObject». MeshFilter берет меш из ассетов и передает его в MeshRenderer, последний участвует в рендере меша на экране.

Способы создания моделей для игр:

  • в редакторах моделей (например: Blender, Maya, 3ds Max и другие);

  • процедурно

  • можно редактировать существующий меш (в общем-то это процедурная генерация меша)

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

О том как создавать меши уже написано столько всего, что мне остается дать одну из ссылок на материалы и обьяснить, в общем виде, как все работает. Ссылка на то как сгенерировать меш в Unity3D: http://www.martin-ritter.com/2019/02/unity-simple-mesh-generation/

При создании меша, во-первых, относительно локального (0,0,0) создается геометрия. Геометрия – это набор вершин (точек), которые соединены между собой. Потом идет массив «triangles». Этот массив содержит порядок точек. Тут стоит совсем немного пояснить:

  • видеокарте нельзя просто дать точки на отрисовку треугольника без указания порядка. Почему? В основном потому, что есть оптимизация. Треугольник имеет две стороны и если бы видеокарта всегда бы рендерила его две стороны, то она бы неоправданно расходовала ресурс. Порядок передачи точек связан с тем куда нужно направить нормаль полигона.

  • видеокарта может рисовать только несколько примитивов: точку, прямую и треугольник. Все остальное создается из примитивов.

Итак, этого в общем-то достаточно для рендера геометрии, но недостаточно для наложения текстур на геометрию. Для наложения текстур нужно создать массив UV – координат. Эти координаты показывают в какую область текстуры проецируется каждая вершина геометрии/модели. Обычно UV принимают значения из диапазона [0,1]. Где (0,0) – нижний левый угол текстуры, (1,1) – правый верхний. В некоторых случаях UV могут принимать значения больше 1 и меньше 0. Это зависит от задачи, которую поставили перед «shader-artist» и его конкретной реализации шейдера.

Кроме vertex и uv, меш может содержать и другие данные:
- uv2, uv3…, uv9 (не знаю чем определяется предел uv[i], наверно платформой)

  • tangents

  • normal

  • color

И да, чуть не забыл, нужно создать AABB. AABB – это axis-aligned bounding box. То есть это «коробка», которая позволяет движку быстро исключать игровые объекты из процесса отрисовки на основе попадания их AABB в область видимости камеры.

Зачем? Это сделано для того, чтобы быстро отбрасывать объекты, которые за спиной игрока, чтобы они даже не пытались подаваться на графический конвейер. Оптимизация! :)

Версия провода 2

В основу этой версии легли сплайновые кривые, а вернее, деформация модели вдоль сплайновой кривой. Что такое сплайн и как он работает? Это достаточно базовая математика, в сети есть даже готовые примеры проектов со сплайнами, детальный разбор того как все работает (не буду повторять то, что замечательно расписано здесь: catlikecoding.com), не будем на них останавливаться.

Вот как выглядит настройка провода:

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

TOTAL RELOAD : процедурная генерация проводов (часть 1) Gamedev, Unity, Инди игра, Разработка, Инди, Программирование, Видео, Без звука, Длиннопост

Все провода имеют один общий материал, особенности всех проводов закодированы в вершинах мешей.

Здесь версия проводов ближе к финальной (на концах установлены вилки, заданы текстуры, доработаны модели):

TOTAL RELOAD : процедурная генерация проводов (часть 1) Gamedev, Unity, Инди игра, Разработка, Инди, Программирование, Видео, Без звука, Длиннопост
TOTAL RELOAD : процедурная генерация проводов (часть 1) Gamedev, Unity, Инди игра, Разработка, Инди, Программирование, Видео, Без звука, Длиннопост

Ссылки на нас:
TORSHOCK.RU / VK / DTF / Twitter / FB

Лига Разработчиков Видеоигр

6.8K поста22.2K подписчиков

Добавить пост

Правила сообщества

ОБЩИЕ ПРАВИЛА:

- Уважайте чужой труд и используйте конструктивную критику

- Не занимайтесь саморекламой, пишите качественные и интересные посты

- Никакой политики


СТОИТ ПУБЛИКОВАТЬ:

- Посты о Вашей игре с историей её разработки и описанием полученного опыта

- Обучающие материалы, туториалы

- Интервью с опытными разработчиками

- Анонсы бесплатных мероприятий для разработчиков и истории их посещения;
- Ваши работы, если Вы художник/композитор и хотите поделиться ими на безвозмездной основе

НЕ СТОИТ ПУБЛИКОВАТЬ:

- Посты, содержащие только вопрос или просьбу помочь
- Посты, содержащие только идею игры

- Посты, единственная цель которых - набор команды для разработки игры

- Посты, не относящиеся к тематике сообщества

Подобные посты по решению администрации могут быть перемещены из сообщества в общую ленту.

ЗАПРЕЩЕНО:

- Публиковать бессодержательные посты с рекламой Вашего проекта (см. следующий пункт), а также все прочие посты, содержащие рекламу/рекламные интеграции

- Выдавать чужой труд за свой

Подобные посты будут перемещены из сообщества в общую ленту, а их авторы по решению администрации могут быть внесены в игнор-лист сообщества.


О РАЗМЕЩЕНИИ ССЫЛОК:

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

- Пост должен быть содержательным и интересным для пользователей, нести пользу для сообщества

- Ссылка должна размещаться непосредственно в начале или конце поста и только один раз

- Cсылка размещается в формате: "Страница игры в Steam: URL"