Что такое динамические декали
Этапные декали. Подчеркните своё мастерство!
Читайте также
Вы провели тысячи зрелищных сражений в World of Tanks, неоднократно демонстрируя своё мастерство и опыт на поле боя. Вы исследовали десятки машин и можете экспертно рассказать о каждой из них. Вы — настоящие профессионалы!
И, чтобы подчеркнуть ваши достижения, мы вводим особые знаки отличия — н астало время показать всем, чего вы стоите!
Пускай все знают о ваших достижениях!
В обновлении 1.9.1 мы добавим в игру новые этапные декали практически для всех существующих стилей и техники. Это не только новые элементы внешнего вида техники, но и свидетельства вашего мастерства и опыта, которые позволят остальным узнать о ваших игровых заслугах.
Эти особые отметки будут внушать уважение противнику, а товарищам по команде покажут, что вы — надёжный союзник!
Как получить новые декали?
Каждая этапная декаль состоит из 3 или 5 уровней (этапов) с возрастающей сложностью. Выполнение условий достижения первого этапа приносит вам одну соответствующую декаль. Потом, по мере выполнения условий, становятся доступными декали следующих этапов.
Как только вы достигнете следующего уровня, этап вашей декали автоматически повысится, а внешний вид — изменится. Уведомление о новом достижении придёт после боя, когда техника появится в Ангаре.
Decal (декаль)
Декали (decal с англ.: бирка, ярлык, клеймо) это особый вид геометрии, который позволяет повышать детализированность игровых окружений без надобности запекать мелкие детали в текстуры, что может быть просто невозможным в ситуациях, когда множество поверхностей используют одинаковый материал. Обычно декали используют для отрисовки дырок от пуль, пятен крови или гари от взрывов, но в некоторых случаях использование уходит за пределы таких вещей. К тому же декали можно создавать не только в динамике, но и во время изготовления уровня.
Можно представить себе игровой уровень с большим количеством зданий. С помощью декалей стены этих зданий можно уникально «украсить» оборванными плакатами, трещинами или пятнами краски, здесь фантазия не ограничена. При наложении можно применять различные методы блендинга для достижения подходящего результата.
Для улучшения восприятия таких деталей можно использовать стандартные техники освещения, такие как bump mapping, parallax mapping и другие. Параллакс особенно хорошо выглядит, так как придаёт намного больше объёма и позволяет таким вещам, как дыркам от пуль «углубляться» в геометрию.
Создавать декали в динамике можно разными способами. Существует упрощённое решение, дающее во многих ситуациях неверные решения, так и более точное, требующее от двух и более треугольников под декаль.
Одно из простых решений, которое можно смело применять для создания «дырок» от выстрелов, заключается в поиске точки пересечения луча с треугольниками игрового уровня (тут нужны различные оптимизации, для того чтобы не проверять каждый треугольник и расчёт места пересечения занимал мало времени). Затем мы берём найденную точку, и используя бинормаль и тангент в этой точке создаём два треугольника, образующих квад. Если информации о бинормали и тангенте нету, можно просто взять два случайных перпендикулярных единичных вектора, расположенных в плоскости поверхности и строить квад по ним. Нормаль поверхности следует использовать как нормали в точках декаля для правильного освещения. Для избежания проблем с z-fighting’ом, который возникает на плоскостях расположенных близко друг к другу следует использовать Polygon Offset/Depth Bias. Текстурные координаты тоже можно находить разными способами, например, для дырок от выстрелов можно использовать координаты углов квада. А вот, например, для пятен крови, которые должны «размазываться» по направлению движения можно рассчитать текстурные координаты методами eye linear\object linear.
Но это простое решение может плохо работать для тех же пятен крови, имеющих большую площадь поверхности. Для таких декалей нужно рассчитывать не центральную точку пересечения, а находить треугольники попадающие в зону покрытия, и создавать множество геометрии на всех этих поверхностях.
Существует также метод при котором детали отрисовываются в текстуру, но это имеет ряд проблем, например требуется уникальность изменяемой текстуры (она должна использоваться только на одном объекте, иначе добавленные детали появятся на всех объектах, использующих изменяемую текстуру), а также страдает скорость из-за постоянных обновлений текстуры (если генерируются мип-уровни, то это будет занимать значительное количество времени).
Текстуры, используемые для декалей лучше хранить в одном текстурном атласе. В таком случае для огромного количества декалей на уровне можно будет использовать один вершинный и индексный буфера, и рисовать всю их геометрию за один вызов функции DrawIndexedPrimitive\glDrawElements.
Пропсы и декали в геймдеве
Полнота погружения пользователя в геймплей во многом зависит от детальной проработки игрового окружения. Чтобы создать иллюзию большого, впечатляющего и реалистичного мира, дизайнеры уровней используют самые разные элементы структурной геометрии, проще говоря “пропсы” и “декали”. Создание деталей игрового окружения — не менее важная задача, чем дизайн уровней, написание сценария, звука и кода.
В этой статье преподаватели Высшей школы бизнес-информатики НИУ ВШЭ, профессиональные левел-дизайнеры и авторы образовательных программ “Менеджмент игровых проектов” и “Основы создания игр”, поделятся опытом создания атмосферных уровней и расскажут, как правильно расставлять акценты на локации.
Какие бывают пропсы
Пропсы в геймдеве — это своего рода бутафория, позволяющая игроку ощутить атмосферу и оценить обстановку в окружающем мире. Все пропсы подразделяются на три основных типа:
Как использовать пропсы и декали
На «необработанную» структурную геометрию накладываются пропсы различных габаритов. Чтобы у игрока не возникло ощущения “обмана”, при ближайшем рассмотрении объектов должно четко читаться количество полигонов, текстура, комплексность и качество материалов. Это особенно важно для объектов на первом плане.
Не меньшую роль в создании реалистичной картинки играют декали. Эти специальные изображения накладываются на поверхности, создавая на них различные эффекты. Например, можно поместить на стену декаль с потеками, трещинами и граффити. Добавить к дому изображения окон, вентиляционных люков и рекламных объявлений. И, наконец, просто создать реалистичное дорожное полотно с разметкой, лужами, решетками ливневок и мусором на обочине.
Как создаются детали игрового окружения
Как правило, игровые объекты (особенно крупные) компонуются из нескольких готовых моделей. Если на high-poly моделях должны присутствовать более мелкие детали (узоры, сколы, трещины), используется технология скульптинга, основанная на принципах классической лепки.
Важно учитывать правильность отрисовки света и его взаимодействия с различными материалами. При проработке освещенности и текстуры пропсов используются различные специальные текстурные карты (кривизны и шероховатости, дополнительные эффекты и фото-текстуры). Работа со светом позволяет добиться максимально реалистичного качества графики.
Где научиться создавать реалистичное окружение в играх
Узнать подробнее, как создаются детали игрового окружения можно, пройдя обучение по программам “Основы создания игр” и “Менеджмент игровых проектов” в ВШБИ НИУ ВШЭ. Вы освоите навыки проработки реалистичного игрового мира, который необходим для создания уникальной атмосферы в игре. А помогут вам в этом профессиональные разработчики, за плечами который не один успешный продукт!
Еще больше информации вы найдете на канале МИП ВШБИ на YouTube. Подписывайтесь и не пропускайте свежие записи с открытых мероприятий ВШБИ НИУ ВШЭ.
Этапные декали в обновлении 1.9.1 World of Tanks
@Игроки в отсутствии контента 3 года назад находят новое развлечение с отметками на технике (классно же)
@Просят разработчиков развить данную тему
@Разработчики: отметки это что (Who?)
@В игру вводятся: ненужные этапные декали
@Разработчики: держите, мы Вас услышали
Вы провели тысячи зрелищных сражений в World of Tanks, неоднократно демонстрируя своё мастерство и опыт на поле боя. Вы исследовали десятки машин и можете экспертно рассказать о каждой из них. Вы — настоящие профессионалы!
И, чтобы подчеркнуть ваши достижения в World of Tanks, мы вводим особые знаки отличия — настало время показать всем, чего вы стоите!
Пускай все знают о ваших достижениях!
В обновлении 1.9.1 мы добавим в игру новые этапные декали практически для всех существующих стилей и техники. Это не только новые элементы внешнего вида техники, но и свидетельства вашего мастерства и опыта, которые позволят остальным узнать о ваших игровых заслугах.
Эти особые отметки будут внушать уважение противнику, а товарищам по команде покажут, что вы — надёжный союзник!
Как получить новые декали?
Заработать новые декали можно, играя в случайных боях после выхода обновления 1.9.1. Для технике в игре есть пять различных наборов условий. Выполняйте их и получайте этапную декаль.
Каждая этапная декаль состоит из 3 или 5 уровней (этапов) с возрастающей сложностью. Выполнение условий достижения первого этапа приносит вам одну соответствующую декаль. Потом, по мере выполнения условий, становятся доступными декали следующих этапов.
Как только вы достигнете следующего уровня, этап вашей декали автоматически повысится, а внешний вид — изменится. Уведомление о новом достижении придёт после боя, когда техника появится в Ангаре.
* Найти информацию об этапных декалях можно в разделе «Внешний вид», где в нижней левой части экрана появится новая вкладка «Этапные элементы». Здесь будут находиться данные о прогрессе выбранного танка по всем этапным декалям.
Можно ли нанести декаль на стиль?
Наносить этапные декали можно так, как и любые другие декали в игре. Но, в отличие от обычных, этапные декали можно применять к большей части стилей, в том числе 3D, за исключением партнёрских машин с неизменяемым стилем:
Для быстрого поиска этапных декалей можно использовать специальный фильтр на панели декалей. Все этапные декали привязываются к машинам, на которые они были нанесены, и прогресс будет учитываться только для этой конкретной техники.
Этапные декали недоступны для машин с неизменяемым специальным стилем:
Всего на одну единицу техники можно установить три декали. Первую декаль игрок получит бесплатно после выполнения всех условий во время сражений в случайных боях. Ещё две декали того же этапа можно приобрести за золото в клиенте игры.
Декали пройденных этапов не пропадут — они останутся в разделе декалей. На танк или САУ можно одновременно нанести декали разных этапов.
Подчеркните своё мастерство!
Этапные декали — эксклюзивные элементы внешнего вида техники в World of Tanks, и они заметно отличаются от обычных декалей. Яркие цвета, объёмные эффекты, завораживающий блеск на солнце. С ними ваша машина всегда будет выделяться. Декали высоких этапов выглядят особенно эффектно и обязательно привлекут внимание других игроков.
Другие новости «Обновление 1.9.1 World of Tanks»
Понравилась новость? Тогда поставь ей лайк, и не забудь оставить свой комментарий.
А так же, добавь наш сайт в закладки (нажми Ctrl+D), не теряй нас.
2D магия в деталях. Часть третья. Глобальное освещение
Глобальное освещение, динамический свет и декали (да, есть такое слово 🙂 ) в действии.
Я очень люблю смотреть на белые предметы без текстуры. Недавно в художественном магазине я долго рассматривал гипсовые фигуры, которые художники используют в качестве модельных объектов. Очень приятно видеть все эти плавные переходы света и мягкие тени. Позже, когда я вернулся домой и открыл Unity3D, пришло понимание, что свет в моём проекте по-прежнему скучный и нереалистичный.
С этого момента началась история глобального освещения, которую я сегодня расскажу.
Предыдущие статьи
Оглавление
Как делать процедурно генерируемые эффекты
Самый первый комментарий к начальной статье этого цикла звучал так: «Магия! И прямые руки.» Не уверен в полной прямоте моих рук (в конце предыдущей статьи — визуальные баги, которые это подтверждают), но никакой магии тут нет. Поделюсь секретом процедурных эффектов:
Минимум треть работы уже сделана, как только вам в голову пришла идея сделать процедурно генерируемый контент. Это может быть что угодно: пятна на крыльях бабочек или атмосфера планеты, деревья и кусты и т.д. Иногда, особенно со светом, сразу понятно, как происходит «генерация» в реальном мире. Чаще всего алгоритм сводится к: «пустить бесконечно много лучей в бесконечное количество направлений и получить реалистичную картинку».
И это вторая треть — написать подобный алгоритм (с учетом того, что бесконечность хорошо аппроксимируется тысячей). Он получается простой, как «hello world», но медленный. Руки сразу тянутся что-нибудь оптимизировать, но, поверьте, не стоит. Лучше запустить его в редакторе и пойти пить чай. А после чая понять, что придуманный метод не даст красивой картинки и всё переделать. Если планируется единожды предрассчитать какую-то картинку в редакторе, и потом использовать её в билде — на этом можно остановится.
И, наконец, последняя треть — придумать алгоритм, который даст визуально близкий результат, но будет работать быстрее. Обычно тут пригождается знание всяких интересных контейнеров, алгоритмов, деревьев и т.д. За один из таких алгоритмов — большое спасибо Dionis_mgn, который когда-то рассказал, как сделать классные двумерные тени.
Планета из предыдущего проекта.
Например, небо для планет в одном из проектов предрассчитывалось так: для каждого пикселя неба выпускались по 20-30 лучей до разных частей Солнца, считалось, сколько лучей пересекается с самой планетой, какую часть пути луч прошел в атмосфере (для подобия рассеивания Рэлея). С хорошим качеством расчеты для одной планеты длились около 30-40 секунд и давали на выходе разнообразные атмосферы в зависимости от удаленности Солнца, «состава» и плотности атмосферы. А еще этому алгоритму удавались неплохие закаты.
Вся звёздная система.
Что такое глобальное освещение?
Необходимость что-то делать с освещением я заметил, когда добавил в демку смену дня и ночи. Лучи света от солнца и луны красиво освещали стены замков, но вот внутри помещений творилось что-то странное: как только рассветные лучи касались верхушек башен, в самых глубоких казематах становилось светло, простите за каламбур, как днём. Конечно, причина не в источнике света «defaultSun»: при смене дня и ночи менялись цвет и яркость неба. Вот они и влияли на каждый пиксель, в не зависимости того, был ли это пиксель травинки на старой крыше или камня в мрачной пещере.
Давайте определимся, какую картинку мы вообще хотим получить. «На свету светло, в темноте — темно» — звучит неплохо для отправной точки. Как в реальном мире: в шкафу темно, в коридоре светлее, в комнате еще светлее, а на крыше совсем ярко. Переформулируем: элементы фона, персонажи и прочие объекты должны получать столько света, сколько фотонов смогло добраться до них от небесной сферы (в нашем 2D случае — небесной окружности). Понятно, что лучше направлять наши «фотоны» не с неба, как в реальном мире, а наоборот, из освещаемой точки в небо: в противном случае нам понадобится слишком много бросков, да и то, многие уйдут «в молоко».
Ещё одно из условий: рассчитываем глобальное освещение только для статических объектов: стен, земли. Так мы сможем запускать его при загрузке и пользоваться результатами весь уровень (без влияния на fps).
Кусочек сцены. На самом деле, расчеты идут для всей сцены целиком.
Прямое освещение
Сказано — сделано. Создаём текстуру размером со всё игровое поле. Пробегаемся по каждому пикселю и смотрим, как много прямых лучей можно протянуть от этой точки до «неба». Лучи будем бросать с равными углами по всей окружности, а «небом» считаем ближайшую точку за пределами карты (вполне хватит расстояния диагонали описывающего карту прямоугольника).
Итого, алгоритм прямого освещения:
Напрашивается оптимизация: бросать лучи только в верхнюю полуплоскость. И только для непрямого освещения работать со всей плоскостью целиком. К сожалению, оптимизации (об этом ниже) не позволяют использовать разное количество лучей для прямого и непрямого освещения.
Демонстрация освещения одного пикселя.
Чтобы ускорить процесс, будем работать не с текстурой, а с одномерным массивом яркостей. Да и не обязательно обрабатывать каждый пиксель: введем коэффициент scale, при scale=4 будем работать с каждым четвёртым пикселем. Размер текстуры и скорость работы вырастет в scale^2 раз. Кроме того, нам не нужно обрабатывать «твёрдые» пиксели стен, но они нам понадобятся в дальнейшем. Заведём для них отдельный массив с булевыми значениями «твёрдости».
При 25и лучах получаем такую текстуру.
Помните, в прошлой части был раздел про Region tree? С его помощью бросать raycast’ы через всю карту оказывается достаточно быстрым делом.
Я не использую цикл по всей текстуре, так как больше половины пикселей принадлежат стенам. Вместо этого итерация производится по массиву индексов «нетвёрдых пикселей».
Непрямое освещение
Прямых лучей явно недостаточно: слишком темно будет в комнатах замка, да и резкие границы хорошо видны. Вспоминаем умные слова, вроде raytracing’а, и понимаем, как много времени займёт применение этих умных слов. С другой стороны — ведь любой переотраженный луч приходит откуда-то с карты, а всё прямое освещение мы только что построили! Расширяем массив и храним там целую структуру:
Переделаем алгоритм прямого освещения, добавляя данные о коллизиях:
* Нормали нужны по простой причине: точка пересечения, возвращаемая raycast’ом — в стене. Нам нужно отступить в сторону, чтобы получить координаты ближайшего к стене пикселя.
* Метод raycast’а для region tree я найти не смог, поэтому делюсь своими наработками:
1. Берем узел (изначально — корневой) и находим пересечение с ним с помощью алгоритма Лианга-Барски;
2. Из четверых узлов потомков находим тот, которому принадлежит ближайшая точка пересечения;
2.1. Если узел — твёрдый лист, возвращаем координаты точки пересечения и нормали;
2.2. Если узел не является листом, спускаемся ниже, начиная с шага 1;
3. Находим дальнюю точку пересечения прямой с узлом потомком (тот же алгоритм Лианга-Барски). Находим еще одного потомка, которому принадлежит эта точка (т.е., если мы сначала попали в верхний левый узел, а прямая — вертикальна, то теперь это будет нижний левый угол). Продолжаем с шага 2.1.
Если проще, мы проверяем пересечения отрезка с квадратами, начиная от самого большого и до самого мелкого, причем сортируем их по близости к началу луча, до тех пор, пока не наткнёмся на твердый узел.
Теперь у нас достаточно информации, чтобы рассчитать любое количество отражений: если
луч ушел в небо, получаем прямое освещение, в противном случае — непрямое из точки пересечения.
Так получается алгоритм непрямого освещения:
Демонстрация непрямого освещения. Собираем из коллизий уже рассчитанное прямое освещение.
Самое главное, что теперь вместо операции raycast’а по region tree нам достаточно взять значение яркости в массиве: так мы получим одно отражение. Конечно, этот метод подходит только для pixelart’a: не нужно учитывать нормали или заботиться о возникающих артефактах.
Посмотрите, какие результаты даёт этот алгоритм:
Готовый результат для фоновых стен.
Довольно шумная картинка получается. На самом деле, после применения такого освещения к реальным текстурированным объектам шумы почти не заметны. К тому же высокочастотный шум исчезнет при использовании scale > 1.
Освещение стен
Вот только стены в текущей текстуре чёрные. «Конечно», возразит зануда, далёкий от геймдева, пиксельарта и чувства прекрасного — «Ведь это не стены, а срез трехмерных стен в двумерном пространстве. А внутри стен, как известно, темно.». Поблагодарим зануду и продолжим эксперименты. Попробуем вообще не затемнять стены:
Стены без применения освещения.
В первом случае результат красиво смотрелся только под землёй, во втором — на поверхности. Нужно адаптивно менять яркость стен в зависимости от окружения.
А теперь история одного фейла. После многочасовых размышлений и прогулок в мне голову пришел исключительной красоты алгоритм, включающий в себя добавление новых методов в region tree, поиск ближайшей точки, не принадлежащей стене и прочее, прочее. Я реализовал этот код, потратив на него все выходные, оптимизировал, как только мог. Этот монстр вычислялся около минуты и всё равно выглядел не идеально. В какой-то момент я решил скрыть огрехи алгоритма, немного размыв по Гауссу результат. Это было идеально! Я ещё некоторое время вносил правки и небольшие изменения. Пока не наткнулся на ошибку в условии, из которой следовало, что результаты моего чудесного алгоритма отправлялись прямиком в garbage collector, а на финальные пиксели влияло только размытие. А вот картинка оставалась такой же красивой.
Зато теперь это самый быстрый этап всего глобального освещения. 🙂
Переведём наши массивы в текстуру, где в одном канале будет яркость пикселя, а другом — принадлежность стене. Размоем пиксели стены на GPU с помощью простого шейдера (простое среднее арифметическое с соседями) в цикле.
Размытые стены (scale = 2).
Вот такое недоразумение получится, если применить освещение.
В первой статье цикла я рассказывал про основы пиксельарта. Дополню еще одной важной аксиомой: никаких градиентов в духе photoshop’а! Это превращает аккуратную картинку в мыло и пластилин. На фоне градиенты не так бросаются в глаза, как на стенах. Пройдемся по текстуре с еще одним шейдером: для каждого пикселя стены с помощью простого округления (с коэффициентом из параметров шейдера) получим несколько градаций яркости. Конечно, полученные переходы далеки от идеала — рука художника не двигала пиксели, убирая кривые лесенки, но нам подойдет.
Световая маска с низкой дискретизацией (scale = 2).
Результат применения маски.
Результат применения маски при использовании реальных текстур.
Обратите внимание, как хорошо скрываются шумы и недочеты освещения, когда мы применяем его к реальным текстурам. Если бы глобальное освещение было динамическим, человеческий мозг, отлично распознающий движение, сразу же нашел бы косяки.
Итак, у нас есть глобальное освещение!
Плюсы этого алгоритма:
Декали
Хотя основная тема статьи раскрыта, это ещё не повод заканчивать стучать по клавишам. Скорее всего, это последняя статья про освещение. А значит, есть смысл рассказать про некоторые новые фишки, которые были добавлены после рефакторинга игры.
Декали («decal» — «переводная картинка»), это отличный способ сделать игру более живой, не сильно жертвуя производительностью. Идея проста: на определенную поверхность (стена, пол и т.д) накладывается прямоугольник с текстурой, как настоящая переводная картинка. Это может быть след от пули, какой-нибудь мусор, надпись, что угодно.
Но мы будем использовать декали немного иначе: в качестве источников света произвольной формы. Раз уж мы генерируем текстуру с освещением, мы можем добавлять в неё объекты произвольной формы. И эти объекты сразу же начнут светиться! Так можно легко реализовать эффекты люминесценции, теплового излучения.
Но есть два важных момента:
По сути, алгоритм простой:
Разделим все декали (например, с помощью тегов Unity3D) на декали переднего и заднего планов:
На примере будет понятнее:
Находим старый спрайт травы.
Позиционируем «траву» так, чтобы она закрывала кончики стен.
Рендерим спрайт только в текстуру освещения.
Добавляем свечение на стены.
Добавляем свечение на фон.
И получаем интересную радиоактивную плесень.
А еще можно делать раскаленные стены, уникальные светящиеся предметы и многое другое.
Стена светится от счастья.
Доработки динамического освещения
Это очень короткий раздел и весь от первого лица. Наконец-то добрались руки сделать рендеринг только видимых источников света. Все источники, которые не попадают в камеру, не отрисовываются и не кушают драгоценный fps.
Более того, оказалось, что источники света составляют отличную иерархию:
1. SkyLight. Фоновое освещение, где важны яркость и цвет;
2. SunLight. Точечный источник света без затухания. Важны яркость, цвет и позиция;
3. PointLight. Точечный источник света c затуханием. Важны яркость, цвет, позиция и радиус;
4. FlashLight. Фонарик с коническим лучом. Важны яркость, цвет, позиция, радиус, угол поворота и ширина луча.
А еще появилась возможность создавать любые другие источники света, наследуясь от базовых.
Вышеописанные источники света.
Заключение
Теперь в нашем проекте есть реалистичный свет, эффекты светимости и обновленные динамические источники света. Сравните с изображением из первой статьи, не так уж мало различий, правда?
Изображение из начала этой статьи.
Изображение из первой части цикла.
И самое интересное: теперь когда готово освещение и произведен рефакторинг алгоритмов и структуры проекта, пришло время написать про воду!
Спасибо за чтение и комментарии к прошлым частям и до следующей статьи!