Наконец закончил интеграцию системы обработки и вывода настроек геймпада в T-Reload на стороне меню. Не прошло и 2-х месяцев...
На картинке представлены геймпады для T-Reload, которые собраны в блендере.Основным требованием к моделям было: минимальная полигональность. У моделей выше около 6к полигонов.
Стояла задача разработать систему, которая позволила бы с минимальными усилиями подключить к игре новый геймпад. То есть новый геймпад должен подключаться примерно так:
- создается модель геймпада с якорными точками всех кнопок и оформляется в префаб
- в редакторе расставялются линии с примерным положением подписей к каждой кнопке
- префабу геймпада задается ID и сопоставляется набор иконок, которые символизируют кнопки геймпада
На начальном этапе система геймпадов должна уметь:
- вращать геймпад в зависимости от того, что игрок настраивает
- поддержка геймпадов xBox, PS4, PS5, NintendoSwitchPro
- поддержка нераспознанных геймпадов
- разработать гибкую систему, которая позволяет подключать новые геймпады путем их добавления в редакторе Unity
Так как модели будут интегрированы в игру, еще нужно принять во внимание стилизационные особенности T-Reload. Но для дизайнеров (разработчиков) это обычное дело, как и вообще все, что ниже будет написано.
Процесс переделки меню под геймпад
Работу начал с анализа того, что было создано другими разработчиками:
Здесь, конечно, очень малая часть того что было изучено, но даже по этим картинкам можно сделать некоторые выводы.
Следующим шагом было разработать свою версию меню с геймпадом.
Первым делом была разработана система линий, которые подключаются к разным элементам геймпада и которые можно настраивать прямо в редакторе:
Первое время пытался протянуть линию к каждой кнопке, но быстро понял, что запутанный паук из кучи линий - это не то, что радует глаз. "Паук" выглядел примерно так:
Потому решил придержаться того подхода, который использовали другие разработчики (группировка кнопок):
Согласитесь, муравей с усиками выглядит лаконичнее :)
Процесс проб и ошибок был достаточно долгим, пришлось исписать много страниц А4 по нескольку:
Разработка моделей
Каждый геймпад должен иметь свою модель. Цена вроде как визуально приемлимых моделей еще вчера составляла около $20. С курсом доллара сегодня это стало дороже в 2 раза.
Но все эти модели достаточно высокополигональные: около 200к полигонов. Самое минимальное, что удалось найти - это 100к полигонов.
По этой причине геймпады пришлось моделить и текстурироовать самостоятельно. Результаты работы приведены на первой картинке статьи.
Последний геймпад - это геймад для случая, когда геймпад не распознан. Внешний вид этого геймпада не принципиален. Потому модель была сделана на основе нескольких реальных геймпадов. В конце, прикидывая то как придется рисовать иконки кнопок, все же пришлось переделать треугольную кнопку. Другие геймпады сильно менять нельзя.
Далее скачал SubstancePainter, создал карты материалов, маски:
А вот и протекстурированные модели:
Модели выше еще были откорректированы (в основном материалы, шейдеры) так как нужно их стилизовать под T-Reload.
Вот модель геймпада xBox в игре:
Геймад от Nintendo заставил немного понервничать. Дело в том, что у меня его нет и по фотографиям из сети я не мог понять, что у него за линии на корпусе. Позже пришел к тому, что корпус геймпада немного прозрачный, а линии - это конструктивные внутренние элементы, которые просвечиваются через пластик.
Так выгдядит редактор наших геймпадов:
А здесь геймпад PS5 и xBox непосредственно в T-Reload:
Завершение
На данный момент мы провели несколько тестов того как люди взаимодействуют с системой настройки управления. Все недочеты исправлены. Переходим к доработке системы вывода иконок помощи в процессе игры :)
Не хотелось бы чтобы у игроков были технические проблемы при прохождении нашей головоломки. По этой причине мы решили провести небольшой тест работоспособности базового функционала нашего проекта под техназванием T-Drones. Пока доступны Windows & OSX версии сборок. Позже, возможно, появится Linux.
Тест направлен на проверку работоспособности настойки управления клавиатуры и геймпадов, заодно проверим:
- работоспособность игры
- графику
- игровое меню в целом
Если после запуска T-Drones появился персонаж, есть возможность им управлять и экран выглядит примерно как на рис. ниже, то грфическая часть успешно работает:
Доступ к настройкам можно получить по нажатию на клавишу ESC.
Друзья! Тест частично автоматизирован, в случае каких-либо проблем вышлет разработчикам соответствуюшие логи. Если Вы заметите неадекватное поведение управления (клавиатура / геймпад), то, пожалуйста, уведомите нас об этом.
Привет всем! Хочется немного поделиться своим опытом по части разработки, интеграции шрифта и локализации нашей игры, которую мы разрабатываем на Unity.
Поиски бесплатного шрифта
Месяцев 7 назад мне пришлось работать над шрифтом. Ранее не доводилось работать со шрифтами (в шрифтах не специалист), так что создавал всё путем поиска наиболее подходящих, на мой взгляд, образцов. За основу нашего шрифта был взят шрифт, которым написано слово "МОЛОКО":
Далее проводились бесконечные попытки начертания глифов в тетради в клетку и их перенос в растровый формат. Перенос глифов в растровый формат - это моя большая ошибка. Правильнее было бы сразу все делать в векторе. Ниже прилагаю сохранившийся материал из процесса работы над некоторыми глифами (первые наброски):
Финальные тесты в Unity:
Перенос шрифта с бумаги в png-файл:
Пример стилизованного символа "Q" :
Так выглядят текстуры наших финальных кириллических и латинских глифов/символов (растровый вариант):
Поддержка языков, проблемы
Предполагалось, что система локализации должна быть максимально гибкой. То есть должна быть возможность добавления новых шрифтов "без проблем".
Разработка шрифта стала для меня большим проектом. Кроме разработки и переноса шрифта в старой системе шрифтов Unity, нужно было вручную разметить участки текстуры, которые отвечали за символы:
Позже возникла необходимость добавить немецкий язык. Пришлось вспомнить о том, как сложно создавать растровые шрифты, а потом настраивать их развёртки. Вся эта работа превращалась в бесконечный ад, который склонял к использованию чего угодно, помимо имеющейся системы шрифтов.
Позже выяснилось, что ручной подход настройки отображения шрифтов изначально был негибким, не учитывали кучу особенностей символов. Основная особенность - в разных алфавитах разное количество букв. А ещё бывают весьма экзотические буквы, которые либо значительно сокращают место на карте текстуры шрифта, либо требуют особой настройки отображения из-за отличающихся габаритных размеров. Например, лигатуры и "умлауты (umlauts)":
Лигатуры - это символы, которые состоят из нескольких склеенных символов (как на рис. выше).
К счастью, в Unity появился бесплатный TextMesh Pro. Это очень хороший плагин, который автоматизирует процесс переноса шрифтов из ttf-формата в текстуру с настроенными параметрами отображения. Часы работы по настройке отображения каждого глифа, задания расстояний и прочего сократились до пары щелчков мышкой. Фантастика!
Зачем нам свой шрифт, когда можно взять бесплатный?
На самом деле, зачем он и для чего? Очень часто у многих встаёт такой вопрос. В сети нередко возникают споры между дизайнерами и остальными разработчиками по поводу того, что на шрифтах можно здорово сэкономить.
К слову, в сети очень часто высказываются в пользу минимизации времени работы над шрифтами, так как многие предполагают, что шрифт вносит незначительный вклад в восприятие игры и в геймплей в целом. Часто предлагают: "не заморачиваться и использовать что-то попроще".
На самом деле есть доля правды в отсутствии необходимости проработки шрифтов. Согласно моему опыту, все зависит от конечного продукта, от его качества, от того, что дизайнеру необходимо передать (в том числе и с помощью шрифта).
Для дизайнера шрифт - это не просто обезличенные символы, это нечто намного большее. Это способ общения с человеком, это качество общения, качество сервиса, эмоции, способ восприятия информации, нарратива. Это целая вселенная.
Сам по себе шрифт - это мощнейший инструмент, который нужно уметь использовать. Подобрав неверный шрифт, можно не то чтобы испортить атмосферу игры, можно просто сделать игру бессмысленной, непонятной, противоречивой.
Давайте рассмотрим следующий пример.
Допустим, у нас игра для детей 7-10 лет, без насилия. В игре есть милые NPC, которые здороваются с вами, сажают овощи, желают хорошего дня, вечера и так далее. Что-то типа игры про весёлую ферму.
И, допустим, в этой игре дизайнер принял решение писать пожелания и все остальные фразы милого зайки-NPC красным цветом и таким шрифтом потому, что шрифт бесплатный и не было времени работать над собственным шрифтом:
Вы прочувствовали всю доброту пожеланий?
Или вот ещё варианты передачи фраз добродушного зайчика посредством шрифта:
Наверно очевидно, что шрифт решает многое и он, часто, крайне важен. Одна и та же фраза может передавать абсолютно разную информацию. И эта информация заложена в контексте, в данном случае в шрифте.
Пример с зайчиком, конечно, утрирован, но он хорошо показывает мощь и возможности передачи огромной информации с помощью такого, на первый взгляд, незаметного инструмента как шрифт.
Бесплатные шрифты
Согласно моему опыту, у бесплатных шрифтов есть большие недостатки. Во-пепвых бесплатных шрифтов очень много (тысячи). Во-вторых лично мне не удалось найти в этой разнообразной тьме что-то подходящее для нашего проекта. Убив значительное время на поиски, я изрядно замучался и был поражён скудностью огромного разнообразия в бесплатном.
Среди платных шрифтов мне попалась пара подходящих вариантов. Но в этих вариантах отсутствовали либо кириллические символы, либо латинские. Цена использования каждого из таких шрифтов в коммерческих проектах (приложения) была в диапазоне по 90 - 120 тыс. руб за шрифт. Для использования на сайте цена была ниже. Ну а для личного приватного использования плата вовсе не взымалась.
Перед разработчиками стоит непростая проблема: - либо нужно вложить 2x * много денежных средств на приобретение шрифта - либо нужно вложить много сил и создать свой шрифт
Для нас выбор был очевиден - придётся работать и создавать свой шрифт.
Создание векторного шрифта
Начну сразу с платного ПО, которое использовал. Birdfont - замечательная программа за $5 на которой мы остановили свой выбор. Программа позволила быстро перенести растровый шрифт в векторный формат.
Достоинства: - очень дешёвая лицензия - достаточно удобная (когда освоишься) Недостатки: - тормозит, есть баги, недоработки - интуитивно непонятный интерфейс и горячие клавиши
Возможно есть ещё какие-то недостатки, которые видны профессионалам, но меня пока все устроило (особенно цена).
Тонкости создания глифов
Birdfont сильно упростил процесс создания векторных глифов и мы расширили поддержку алфавита. Добавили поддержку следующих языков (кроме английского и русского): - немецкий - французский - испанский - итальянский - польский - чешский - венгерский Кажется ничего не упустил.
В процессе работы над глифами обнаружил, что играл со шрифтами и сильно проиграл.
Ситилизация шрифтов - головная боль для дизайнера.Как можно играть с дизайном глифов и проиграть.
Дело в том, что мы пытались стилизовать шрифты других стран без глубокого понимания того, что можно делать, а что нельзя: упрощали, перерисовывали части глифов на свое усмотрение. Ниже представлены примеры глифов, которые ранее стилизовали неверно:
В конце мы передали свой шрифт друзьям-лингвистам из бюро переводов Code-Switcher, чтобы похвастаться они все проверили. У них, в основном, трудятся переводчики-носители языка, они-то точно должны адекватно оценить нашу работу. Те, в свою очередь, посмотрели и отправили в ответ пренеприятное известие примерно такого содержания:
Ваши символы "A", "B", "C" стилизованы не совсем верно. Символы "D", "E", "F" содержат серьёзные проблемы.
Далее следовало уточнение о том, что неверно и почему. В целом наш шрифт вызывал бы неприязнь, отторжение у носителей языка. Забраковали работу :(
Особо отмечу, что сильно забраковали эти два символа, которые похожи на "А" и "С". Вот они:
Заметили мелкие крючки на конце? Крючки, точки, кружки с отверстием, вопросительный знак перевернутый вверх ногами - неучтенные мною глифы, которые оказались серьёзной болью при дальнейшем расширении языковой поддержки. Ребята из кодсвичера доходчиво объяснили, что наши дизайнеры слабо разбираются в шрифтах и нам необходимо ввести дополнительные символы вопроса и восклицания для испанского языка.
Дело в том, что испанцы сперва ставят перевернутый знак вопроса / восклицания, далее идёт предложение, а в конце ставятся обычные знаки вопроса / восклицания. И без перевернутых знаков в начале предложения никак не обойтись, просто вот совсем никак, вынь да положь.
В итоге мы учли всю критику от ребят из бюро переводов и добавили полную поддержку перечисленных выше языков.
Теперь попробуем сравнить текст на немецком и английском (наш шрифт) и текст на русском (точно не помню какой именно шрифт в примере):
Наверно заметили, что здесь что-то не то с кириллическим русским текстом. Да, это так. Разный шрифт - разный дизайн.
Кажется, что текст выделяется из-за того, что шрифт очень широкий. И все можно исправить простым сжатие глифов. На самом деле проблем больше и простым ужатием шрифта по горизонтали не обойтись.
Штош, что только не сделаешь, чтобы конечный продукт выглядел неразношорстно, в одном стиле. Наш финальный результат:
Надеюсь мой пост был полезен и интересен. Всем хорошего дня :)
Привет всем! Какой-то художник сказал мне, что если бросить карандаш на работу, то она сразу станет лучше.
А еще говорят "уникальная механика игры\хорошая идея - пол успеха", "если назвать игру правильно, то сильно возрастает шанс попасть в топ" или "правильное название фирмы - пол дела".
А я в это все не верю. Терпение и адский труд - вот ингридиенты хорошего продукта.
Шрифт до сих пор просит себя доработать, исправить, стилизовать:
Стим пока что-то тормозит с документами. Ссылки где мы публикуем обновления по игре:
Продолжение статьи о том как работают провода в TOTAL RELOAD.
Предупреждение: эта статья не является инструкцией, также, скорее всего, она не будет полезна профессиональным программистам, которые имеют опыт работы с процедурной генерацией мешей. Статья содержит картинки, видео и обобщенные объяснения разработанный нами системы генерации проводов.
SSAO тени и провода
При разработке проводов, которые поддерживают тесселяцию, мы столкнулись с проблемой: SSAO из Post Processing V2 работал неверно с проводами в режиме Forward. В результате этого все провода имели неверный эффект затемнения. Если задать произвольный “RenderType”, то провода выглядели примерно так:
Так же провода имели проблемы здесь:
Нужно было добиться такого результата:
Все это из-за того, что SSAO, при расчете затемнения, использует _CameraDepthNormalsTexture - текстуру. Провод использовал встроенный RenderType (или использовал наш, который не переопределен) и в результате _CameraDepthNormalsTexture выглядела так (провода здесь нет):
_CameraDepthNormalsTexture - текстура формируется “Internal-DepthNormalsTexture”-шейдером. Чтобы все работало как надо, для режима Forward этот шейдер придется переопределить. Провод после переопределения:
Но это еще не все! Переопределить встроенный шейдер нужно так, чтобы он учитывал тесселяцию. Иначе при расчете карты нормалей будет использована низкополигональная модель провода и тени будут выглядеть криво. Карта нормалей, сформированная без учета тесселяции:
Так «гладко» и красиво выглядит финальный вариант:
Он же без тесселяции (для сравнения):
Главное, при расчетах, меньше ошибаться. Иначе можно получать вот такие вот макароны-спиральки:
Эффект виртуальности мира
Игровой мир является частично виртуальным и мы всячески подчеркиваем это. Провода - это одна из вещей, которая будет намекать игроку о особенности мира. Для этого было решено показать виртуальность мира через небольшую дезинтеграцию проводов в области их пересечения с игроком или другими предметами, которые наделены энергией.
Итого: провод делится на равные сегменты, которые заносятся в Octree.
В области пересечения провода и игрока в шейдере рисуется отверстие:
Далее: если дистанция меньше определенного радиуса, то делается ‘clip’. Кроме этого по периметру clip рисуется подсветка.
dist - the distance from the pixel to the object
Также нужно рисовать отверстие и при формировании _CameraDepthNormalsTexture. Иначе SSAO будет неверно затемнять провод.
Кроме этого нужно рисовать отверстие и при формировании _CameraDepthTexture. Иначе тени будут рисоваться там, где провод дематериализовался.
В результате тени и SSAO работают так:
А здесь провод дезинтегрировался (внимание на тень):
Внутренность провода
Результат работы над внутренностью тонкого провода выглядит вот так:
Дематериализованный толстый провод:
Как это работает
Провод создается на основе сплайна:
берутся необходимые модели (части провода)
изгибаются вдоль сплайна
финальная модель запекается в “Asset” и используется в игре
Так же сплайн, на основе которого был построен провод, используется для отрисовки внутренней части провода:
определяется ближайший подвижный объект и его проекция на сплайн
строится изогнутый вдоль сплайна участок дематериализованных “кубиков”
Если оболочка провода запекается один раз и алгоритм запекания не требует оптимизации, то внутренняя часть провода (дематериализованные кубики) требует оптимизацию. Изгибание модели кубиков вдоль сплайна на процессоре - это тяжелая вычислительная задача:
Было принято решение: гнуть кубики вдоль сплайна на GPU. После этого нагрузка на процессор составила почти 0!
печем параметры (position, rotation, scale) участков сплайна (с эмпирически подобранным шагом N) в текстуру
декодируем матрицы на видеокарте и смещаем вершины
радуемся результату
Оптимизация и поддержка слабеньких видеокарт
Когда вы счастливый обладатель хорошей видеокарты, а именно: ваша видеокарта поддерживает тесселяцию, то все замечательно! Провод будет выглядеть высокополигональным и невидимые части кубиков дематериализации будут качественно скрыты внутри провода (в местах изгиба провода).
А что, если вы не такой уж и счастливый обладатель видеокарты и имеете что-то относительно неновое? Тогда ваш провод во-первых будет смотреться как низкополигональный параллелепипед, а во-вторых он будет проявлять (в областях изгиба) кубики дематериализации. Например, этот изгиб проявит кубики дематериализации так как оболочка провода сильно отступает от создающего его сплайна:
А если еще сильнее низкополигонизировать участки провода (зеленая линия имитирует более низкополигональную версию), то будет ужас. Очевидно, что в местах сильного изгиба провода кубики всегда будут предательски торчать:
Решение: просчитать тангенсы и на основе отклонений подменять участки проводов на более/менее полигональные. Просто же, правда?:) Визуализация тангенсов:
В результате создание модели провода работает так: в зависимости от кривизны участка, выбирается соответствующая модель провода (высокой/низкой или средней полигональности). В результате, данный провод способен скрывать (в местах изгиба) внутренние кубики даже на слабых видеокартах.
Модели разной полигональности, которые используются при построении провода:
Да заболел, работать не получается, голова гудит как аэродинамическая труба. Ни спать, ни думать. Недавно закончил работу над мат.моделью черной дыры для нашей игры TOTAL RELOAD:
Кинематографичный раурс №1
Cкрин из нашей группы из нескольких разработчиков. Все интенсивно кидают результаты своих работ, наброски, идеи:
Скрины процесса разработки
В процессе разработки вдохновение черпал везде где только можно. В основном из Interstellar, референсы и матмодели других разработчиков. Сразу приведу некоторые ссылки: youtube.com/watch?v=g-iw2DDNDeY (реализация без когда, полезно чтобы понять в общих чертах как сделать черную дыру)
А вот этот парень большой молодец (на мой взгляд):
Он подробнее рассказал на пальцах как сделать черную дыру и с какими проблемами можно столкнуться. Да, в его версии черной дыры есть артефакты, но видео достаточно полезное. А еще он не забывл упомянуть "того лысого чувака", который очень подробно объясняет рейматчинг :)
А это мой вариант "Б" на случай если у меня не получилось бы сделать черну дыру приблизительно как в Интерстелларе. Такую версию дыры точно можно сделать:
Разработка
Процесс разработки начался с изучения того что из себя представляет черная дыра и того как она выглядит. Какие ожидания относительно внешнего вида имеются у игроков, как ее видят дизайнеры. То есть все началось с референсов дизайнеров и матнаработок других разработчиков.
Все что попадает (свет, материя) в область воздействия черной дыры, притягивается и сжимается в идеальную точку. Именно из-за этого черная дыра и выглядит так как ее показали в Интерстелларе:
Как оказалось, многие дизайнеры имеют свое видение черной дыры и оно часто рознится с описанием математиков. Привожу ниже разные референсы:
Некоторые рефренсы черной дыры, которые нашел в сети
Структура черной дыры, некотороые попытки воссоздания
В целом черная дыра состоит из ядра (то что находится в центре) и диска (его называют аккреционным диском).
Моей первой идеей была следующая: а что если сделать черну дыру в виде модели сферы и модели диска? Мой напарник Александр к тому времени уже сделал версию черной дыры в Blender, записал клип и он много месяцев лежал в папке, я попробовал воссоздать что-то похожее, но полностью в Unity.
Версия черной дыры Александра
Ортографическая камера, разная толщина линий обода, кольца вокруг черной дыры, плоский аккреционый диск с перетянутой(? или в блендере mipmap неверный задается) на краях ткустурой, звезды одного размера, цвета и яркости. Непонятно что с звездным небом. То и из-за распределения, то ли из-за одинаковой яркости небо какое-то странное. А может мне кажется? Ваше мнение? В итоге все это привело к тому что качество картинки сцен с черной дырой пришлось доработать.
Сразу отмечу, что звезды имеют разный размер (в том числе и из-за разной яркости свечения), цвет, неравномерное распределение на небе и ко всему к этому они еще и мигают (какие-то больше, а какие-то почти нет).
Пикабу не умеет вставлять форматированный код, потому прилагаю фото кода
После того как немного пошаманил, получилось создать процедурное небо:
Минимальное количество звезд
Увеличил яркость звезд
Уменьшил яркость звезд
Что мне нравится в компьютерной графике и к чему всегда стремлюсь - это автоматизация процесса. Взгляните, количество звезд, яркость, частота мигания и прочие параметры могут быть заданы через несколько ползунков. Можно в реальном времени настраивать параметры звезного неба и смотреть устраивает оно или нет... Круто, правда?
Черная дыра
Но а дальше пошли пляски с бубном. Мне категорический, крайне не хотелось возиться с рейматчингом. Потому что рейматчинг: - тяжел для графической карты - у меня небольшой опыт работы с ним - чтобы что-то сделать в рейматчинге - это нужно реально разобраться и сделать математически. То есть там реальная математика и если где-то будет проблема, то ты ее не найдешь отладкой. Нужно сидеть и разбираться что к чему.
В общем мой подход "ВСЕ ЧТО УГОДНО, НО НЕ РЕЙМАТЧИНГ" привел меня к таком результату:
ну хоть небо на небо похоже
Здесь две модели: диск и сфера. Ну поехали критиковать: - облака на диске плоские как лист бумаги - облака диска не похожи на облака - плавного перехода между облаками диска и космосом нет (в этой версии, но это не спасет все равно) - дыра не искажает пространство - облака с аккреционого диска не наползают на черную дыру и текстура там без перехода - текстура газов или что это там - одноцветная какая-то, серая что ли + слева есть засвет от энергии, это плюс, есть как бы намек на соответствие с матмоделью
Я еще долго игрался с моделью дыры пока не понял, что пора завязывать с этими убогими потугами что ничего дельного из этого не выйдет:
Попытка улучшить аккреционный диск
Какой-то объект на фоне предполагаемой черной дыры
Аккреционный диск, попытка улучшить №100500
Попытка настроить\сделать карты нормалей для кинематографичного искажения неба
Да, можно показать дыру под определенным ракурсом, на определенном расстоянии и на определенное время. Но тут слишком много слова "определенное". Нужно чтобы можно было показывать как хочешь, со всех сторон и с разного расстояния. Рейматч короче. Ну что, поехали, небольшое видео о том чего можно добиться рейматчингом:
Хотя облака диска у нас реализованы не на 100% так как показано на видео, посмотрел это видео чтобы погрустить на тему того, что придется много-много-много пробовать, экспериментировать.
Рейматч
Первым делом создал объемную сферу, тор и сжал тор по высоте чтобы выглядел как дск. Здесь одна из версий тора и сферы:
Одна из версий черной дыры
Далее работаем с диском, добавляем ему шум с помощью облаков, используем полярные координаты и видим артефакт:
Шов в области перехода облаков
Шов в области облаков устранен
Артефакт, в данном случае, - это как бы "шов" от замыкания облаков. Здесь показал изменение координат полярной системе. Шов находится в области резкого перехода красного в желтый. Если смажем переход (путем интерполяции), то шва не будет:
Полярные координаты в виде цветов
Скрина с текстурой облаков без шва не осталось. После этого нужно было разобраться с текстурой глубины. Обьекты, которые попадают в диск и дыру должны пересекаться корректно. Сделано, здесь показано как палка свеху не пересекается облаками, а снизу облака перекрывают палку. Делается это так: если значение буддера глубины больше чем глубина облака, то считаем, что объект находится за облаками и рисуем облака. Иначе рисуем обьект. Результат:
Облака без цвета (один сплошной красный)
Нужно менять прозрачность в зависимости расстояния между облаками и палкой. Это нужно для того чтобы облака были похожи на обака. В данном случае облако перекрывает палку, но мы дополнительно изучаем расстояние между облаком и палкой. И в зависимости от расстояния мы задаем прозрачность облака:
Палку (ее часть, которая в облаках) немного нужно было исказить. Для этого использовал GrabPass. То есть делается фото всего экрана, помещается в текстуру и в шейдре обрабатывается текстура (вернее область палки). Так же добавим искажение звездам:
Ну что, получили артефакт в виде второй палки, которая возникла из-за искажения текстуры GrabPass. Чтобы устранить этот артефакт используем текстуру глубины и обрабатываем ситуацию, когда палка не должна рисоваться. Позже отказался от использования искажения (его незаметно), то есть GrabPass не используется .
Результат
Кинематографичный раурс №2
Выводы
Рейматчинг довольно мощный инструмент. Да и в целом, как оказалось, математика - это достаточно мощная штука когда умеешь ее использовать :) Экспериментировать пришлось не так и много. Во всяком случае меньше чем люди, которые разрабатывали облака для мультиков пиксар.
В результате нам удалось сделать: + теперь облака на диске объемные и выглядят как обака с разных углов. Потому что они реальные математические облака :) + облака диска стали похожи на облака + сделан плавный переход между облаками диска и космосом + дыра очень хорошо искажает пространство и звезды + облака с аккреционого диска наползают на черную дыру, все как надо + текстура газов диска цветная, объемная (цвет и плотность облаков меняются в зависимости от расстояния до ядра) - убрал яркий засвет в правой части аккреционного диска, пока он не нужен + звезды похожи на звезды: разного размера, цвета, яркости, мигают
Ссылки на нас
У нас уже есть страничка в стим, трейлер, скрины из игры :)
Готовы рассказать о процедурной генерации проводов и о том как она устроена в TOTAL RELOAD. Всего проводам будет посвящено 2 статьи (2 части). Выше приведен скриншот из игры на котором представлены финальные провода.
ВАЖНО: материалы, которые будут представлены ниже, следует рассматривать в качестве материалов из технических этапов разработки, которые не передают геймплей, атмосферу, историю игры, а только дополняют текст статьи.
Предупреждение: эта статья не является инструкцией, также, скорее всего, она не будет полезна профессиональным программистам, которые имеют опыт работы с процедурной генерацией мешей. Статья содержит картинки, видео и обобщенные объяснения разработанной нами системы генерации проводов и обобщенный ответ на вопрос «что же такое меш (mesh)?» Итак, поехали!
Часть 1. Процедурная генерация проводов
Механика нашей игры связана с проводами, от них зависит восприятие игры, то как игроку будет комфортно играть. В процессе разработки игры, было реализовано и опробовано несколько различных вариантов системы проводов. По мере развития проекта мы постоянно их модернизировали.
Версия провода № 1
В самом начале разработки игры было принято решение не пытаться вытянуть качество графики до уровня ААА – проекта. Причины такого решения просты:
команда состояла (и состоит) из 2-х человек, которым задач и так хватало
не было уверенности, что все окупится
Итак, в первое время мы разработали «2D» систему проводов, которые были плоскими. Я думал, плоская – это хорошо в плане того, что меньше полигонов и объем проводам можно картами нормалей придать (если потребуется). Ниже представлен первый вариант системы проводов:
Как работала система проводов:
имеется набор вложенных gameObjects – узлы проводов
родительский объект создает процедурный mesh с UV. Mesh и UV создаются в зависимости от позиции узлов проводов.
Система позволяла выполнять поставленные задачи:
отображала соединения объектов
относительно гибко настраивалась
генерируемый провод соответствовал первому минималистичному стилю
Меш провода генерировался процедурно по точкам. Здесь видно конечный результат (вариант провода №1):
Провод менял свою геометрию тогда, когда одна из точек меняла свою позицию. Провод мог гнуться на углы +/-90 градусов относительно родительского объекта. Еще одно видео:
Так планировалось прокладывать провод в уровне:
Технически, провод имеет начало и конец, он автоматически должен соединять разные элементы уровня. Это было реализовано процедурно. Имитация соединения элементов по какому-то событию показана на видео:
И вроде как все были довольны этой системой проводов, но…
Но тут, по мере анализа уровней, быстро пришло понимание: «это не то, чего мы хотели добиться». Конечно, смотрится неплохо, лучше чем ничего и даже лучше чем некоторые дизайнерские решения. Но минималистичный стиль присутствует повсеместно и в очень многих инди-проектах. В общем, в очередной раз понесли мы свои результаты к эффективному менеджеру Сове. Сова к этому времени была порядочно раздражена нашими глупыми решениями, но приняла нас. Вот что мы принесли ей напоказ:
У Совы, насколько мы знаем, брови изначально (наверно с рождения) повернуты под 90 градусов. А после всего того, что мы показали, они у нее просто вывернулись на все 360.
Провода нужно было переделывать.
Что не устроило Сову:
Обыденность и минималистичность: где-то она уже видела этот провод;
Скрытность: он плоский, сбоку его вообще не видно;
Повороты кратны 90 градусам: уровень будет иметь углы только кратные 90 градусам, это снижает возможности разработчика уровней до… лучше не думать, даже некоторые первые в мире игры имели стены, которые располагались под произвольными углами.
По проводу все осталось в общем по-старому, только в ТЗ добавилось 4 требования:
провод должен гнуться не только на 90 градусов;
провод должен быть объемным, так как плоский визуально сливается с полом;
текстура должна тайлиться, а не растягиваться;
уникальность проводу нужно придать моделью + материалом.
Пара слов о генерации меша
Хотелось бы чтобы статья содержала больше полезной информации чем просто результаты нашей работы.
Немного глубже затронем тему процедурной генерации мешей.
Что такое меш (mesh)?
Меш – это, условно, модель, которая крепится к компоненту «MeshFilter», который, в свою очередь, принадлежит «GameObject». MeshFilter берет меш из ассетов и передает его в MeshRenderer, последний участвует в рендере меша на экране.
Способы создания моделей для игр:
в редакторах моделей (например: Blender, Maya, 3ds Max и другие);
процедурно
можно редактировать существующий меш (в общем-то это процедурная генерация меша)
Процедурное создание полезно в ряде случаев. В основном все случаи сводятся к тому, что мы не знаем какую модель нужно создать и модель создается в редакторе или в процессе игры. Это может модель помещения, модель каких-то объектов, которые нельзя построить заранее. Что касается нашего случая, то как вы уже наверно догадались, это модели проводов.
При создании меша, во-первых, относительно локального (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), не будем на них останавливаться.
Вот как выглядит настройка провода:
Особое внимание уделено шейдеру. Он поддерживает тесселяцию, что позволяет экономить на полигональности модели. Здесь сверху провод с тесселяцией, обратите внимание на то, что он гладкий. Внизу провод без тесселяции, угловатый:
Все провода имеют один общий материал, особенности всех проводов закодированы в вершинах мешей.
Здесь версия проводов ближе к финальной (на концах установлены вилки, заданы текстуры, доработаны модели):