Структура игры: отражение

Продолжаем разбирать устройство игр с небольшими вкраплениями практики. Сегодня на повестке — отражение в зеркале. Нет, не свое собственное, а отражение в зеркальных поверхностях внутри 3D-движков, в частности — в играх. Разберем, какие бывают отражения, как они реализуются и как именно сделать отражение в редакторах движка.
Интро
| В прошлый раз я упоминала, что Unity — дистиллированный движок, тогда как Unreal Engine хоть и тяжеловесный, но обладает огромным количеством настроек, которые не нужно придумывать самому. |
Это можно сравнить с детскими площадками:
- UE это продвинутая игровая зона во дворе дорогого жилого комплекса, где для вашего удовольствия есть десяток снарядов различного рода, назначения, дизайна, разукрашенных цветными картинками. Хочешь — иди качайся на качельке одного из трех видов. Хочешь — играй в песочнице с идеальным мелким песком и грибочком. Хочешь — выбирай себе горку по высоте, цвету и направлению.
- Unity представляет собой старую советскую площадку, в которой песочница — гора песка из пустыни Сахара с диаметром песчинок в полсантиметра и гранитной крошкой из карьера. Горка там ржавая, и кататься на ней можно только на специальной благословленной фанерке, а вместо снарядов — пара турников в лучшем случае. Но удовольствие можно получить на обеих, если найти правильный подход. К первой подход «для казуалов» — зашел и играйся. Ко второй надо подготовиться, собрать друзей и набить шишки самостоятельно.
| Это касается абсолютно всего, что вы хотите сделать на этих движках. Конечный результат при правильном методе будет очень схож, но затраченные усилия различны. Создание отражений — не исключение. |
Ты — всего лишь отражение…
Для начала разберемся, какие отражения в играх мы встречаем. Ибо проблема с ними довольно острая.
| Проблема отражения присутствует в играх практически с момента их появления. В пиксельных 2D-играх сделать настоящее отражение было невозможно по вполне прозаичной причине: сами по себе пиксели не отражают. Их невозможно «отполировать». Было невозможно. Сейчас подход к пиксельной графике немного изменился, по крайней мере, в рамках крупных движков. По-настоящему олдскульные пиксель-арт игры, где каждая точка на экране контролируется кодом напрямую, а не является частью отдельного изображения или текстуры, все еще выходят (оригинальная Dwarf Fortress, например), но большая часть игр работает со спрайтами-картинками различной степени самостоятельности. Но сейчас не об этом. |
Там, где это было сюжетно необходимо, отражения в играх рисовали вручную. Как правило, это были кат-сцены (постановочные ролики и заставки, зачастую пререндеренные заранее) или заскриптованные моменты, где у игрока отнимают управление, что технически почти одно и то же.
Но вот выходят первые 3D-игры. И чем лучше становилась графика, тем острее становился вопрос: а как сделать отражения?

| Отражение — это не только морда героя, стоящего перед зеркалом. Это блики на поверхности воды, отполированном полу, керамической броне высокотехнологичных роботов, мокрой коже эльфийки под дождем и даже листе железа, заменяющем кирасу какому-нибудь отшельнику, которые моделирует сама игра |
Звучит уже серьезнее, не правда ли?
Стоит сказать, что и в традиционном художестве отражения тоже нелегко сделать: в некоторых случаях обучению отрисовки бликов света посвящают отдельный курс, чтобы научить людей расставлять пятна света на вазах в натюрмортах.
Чем больше в сеттинге игры (условиях мира) отражающих поверхностей, тем сильнее необходимость решения проблемы. Какое-то время индустрия со своими стрелялками и стратегиями в режиме «око бога» (вид сверху от третьего лица, изометрия) игнорировала это. Но потом стали выходить камерные хорроры. Графические движки стали достаточно мощными, чтобы делать игры от третьего лица с камерой из-за плеча или просто близкой к персонажу, проработанными интерьерами и прочим. Поэтому стали появляться различные ухищрения.
Имитация отражений
Имитация отражений и имитация света на предметах идут рука об руку. Поначалу все, что могли себе позволить разработчики, это нарисовать тень и свет там, где они бы располагались большую часть времени в реальности. Например, нарисовать тень под карманами, нарисовать блики на кожаной куртке и стволе оружия. С металлическими аксессуарами проделывали то же самое — пара полосок более светлого цвета, чем остальная текстура.
| Рисование отражения. Этот способ до сих пор используют во многих играх со стилизованной и полуреалистичной графикой, особенно от студий поменьше. В играх с реалистичной графикой, как правило, такой подход используют только на волосах и отдельных деталях. |

Одна из текстур обуви Resident Evil 6. На кожаных ботинках складки подчеркиваются бликами
То же самое делали с зеркалами: размытый образ плюс металлический блеск, который сначала задавался настройками материала модели, а позже обзавелся собственной текстурой.
| Текстуры отражения: блеск. Когда появилась возможность использовать две и более текстуры на одном меше (участке модели), первым делом стали использовать бампмапы — текстуры рельефа. Позднее они почти целиком были вытеснены нормалмапами — картами нормалей, имитирующий объем за счет искажения падающего на модель света. Это относилось к непосредственному отрисовыванию «правильных» теней и бликов, но также влияло и на блеск модели, хотя и не так сильно. Исключение — normal map в TES V: Skyrim. Они объединяют в себе карты нормалей и карты блеска. Сине-розовая часть канала цвета регулирует рельеф, а альфа-канал — силу и место блеска. |
Следом за нормалями изобрели текстуры блеска (shine map/specular map, иногда metalnes map). Как правило, это черно-белая текстура, где абсолютно черный это отсутствие блеска, а абсолютно белый — максимальный блеск. Иногда эти текстуры сохранялись с активным альфа-каналом, так как не все движки адекватно отображали переходы цвета. Кстати, до сих пор в некоторых случаях средства визуализации плохо воспринимают чисто белый цвет в системе RGB, и художники по текстурам стараются его избежать.
| По началу добавлять одновременно нормалмап и спекуляр мап на один кусок модели было нельзя — движок не имел такой возможности — и разработчикам приходилось выбирать. Однако сейчас существует как минимум десяток способов объединить текстуры и свойства: от комплексных разноцветных карт, как в Ведьмаке 3, до процедурных цепочек мультиматериалов. |
Сферические карты, кубмапы. Время шло, модельки продвигались, средства отображения становились все лучше, а игрокам хотелось все большего. Простые текстуры блеска уже не удовлетворяли потребности в «хочу красиво». Если для кожи, волос и шерсти все еще годились спекуляры в сочетании с нормалмапами, то на металле и стекле такое уже не прокатывало. Но отрисовывать честные отражения в реальном времени все еще не было возможности.
И тогда в дело вступила фантазия: зачем нам честное отражение в игре, где 99% времени игрок не видит отражающую поверхность вблизи? Нам достаточно пары гуляющих бликов! И желательно, чтобы не приходилось каждый раз лезть в настройки модели. Тогда на помощь пришли первые сферические карты (sphere map) или кубические карты (cubemap).
| Несмотря на разницу в названии, принцип работы у них схожий: представляется среда, в которой находится модель (помещение, участок под открытым небом, лес и т.п.), какие в нем могут быть источники света и основные цветовые акценты, а после… А после два варианта: простой и сложный. |
Простой вариант подразумевает рисование примерной карты бликов вручную с максимально возможным приближением к бесшовной tiled map. Такое прокатывает в случае с маленькими картами, созданными исключительно для блеска не очень хорошо отполированных поверхностей без 100% отражения.
Таково большинство сферических карт и кубмапов в играх. Характерный пример: кубмапы TESV, которые создают эффект блеска на доспехах разного материала. Для каждого материала имеется своя мини-карта 32х32 пикселя.

Увеличенные в 2,5 раза кубмапы материалов из TES V. Эти текстуры используются для имитации серебра, золота, ртути, зеленого эльфийского стекла, бронзы, льда, масла, опала, железа, стали и т. п.
В некоторых случаях эти карты меняются в зависимости от того, в каком помещении находится объект: специальный скрипт просто заменяет путь к одному кубмапу на путь к другому. Таковы кубмапы Dark Souls III и некоторые специальные кубмапы Скайрима.

Сложные и простые (внизу слева) кубмапы TES V: Skyrim. 9 больших изображений — карты парагонских порталов. Группа карт внизу слева — кубмапы помещений. Внизу справа — увеличенные текстуры специальных эффектов (жидкого ужаса Апокрифа, две карты для отражения света неба днем и ночью и для отражения света факела в темных пещерах).

Кубмапы Dark Souls III. Их около 30-40 на каждый биом (регион). Зачем так много? Просто они сменяются по мере продвижения игрока, плавно изменяя отражения на его доспехе. Текстуры на примере приведены не подряд из двух связанных переходом регионов. К каждому такому набору в соседней папке идет градуированная линейка для плавного изменения интенсивности текстур.
Сложный вариант подразумевает создание сцены окружения в 3D-пространстве движка, добавление в него камеры-зонда (lightprobe camera) и снятие панорамного рендера этой камерой. В результате получается что-то вроде HDR-карты, которую при желании можно натянуть на сферу и превратить в скайдом (skydome) или лайтдом (lightdome) — купол фона или освещения в сцене.
Рендер производится на этапе разработки (обычно ближе к концу) в редакторе на базе движка или даже в стороннем ПО.
| Этот рендер преобразуют в текстуру и накладывают как обычный кубмап. Плюс в том, что отражения окружения получаются достоверными для помещения, где рендер был сделан. Минус: для каждой сцены и для перемещения каждого предмета (не только предмета, на который наложена карта, но и любого отражающегося в нем предмета) придется делать новую пробу света. Мы к этому еще вернемся. |
Дубликат мешей. Оригинальный способ создания отражения впервые встретился мне в одном из первых Resident Evil в злосчастном поместье. Думаю, игравшие в ту часть помнят шикарный холл с лестницей и надраенными до зеркального блеска полами. Это было чертовски эффектно и впечатлило меня как мелкого и неопытного игрока. Не менее впечатляющим оказалось и то, что я узнала позднее — отражение на полу зала было полной копией зала оригинального.

| И я не про картинку — это буквально была отраженная по вертикали модель зала. Герои, заходившие в него, также дублировались, а их анимации отражались. Сам пол был полупрозрачным ровно настолько, чтобы имитировать эффект полированного мрамора. Как потом оказалось, не только в этом зале и не только в этой игре применялся подобный ход. |
Так, отражения в зеркалах, например, были дубликатами комнат с копиями моделек персонажей, копирующих все анимации оригиналов. В одной из Devil May Cry, в DOOM3, во многих японских хоррорах, в некоторых RPG, этот метод встречается до сих пор. Однако он более ресурсоемкий, и когда у вас в модели три сотни тысяч полигонов и 4к-текстуры на каждом из шестнадцати мешей персонажа (как в последних Final Fantasy), делать их дубликаты означает убить видеокарту. Нечто подобное
Честные» отражения
Сделать настоящее отражение в игровом движке космически сложно, почти невозможно. Но приблизиться к этому — вполне реально, хотя и потребует вычислительных мощностей компьютера, на котором впоследствии будет запускаться игра.
| Зонд (probe). Первый способ мы уже частично разобрали — создается дополнительная камера-зонд (reflection probe), и рендерит окружающее пространство. Только в отличие от кубмапа, полученная текстура не сохраняется на компьютер отдельным файлом, а сразу накладывается на объект, на котором нужно получить отражение. Делается это благодаря специальному скрипту (сценарию), который пишется отдельно и привязывается к зонду и объекту. Рендер происходит не в редакторе у разработчика, а в режиме реального времени на устройстве, на котором игра запущена. Само собой, это кушает вычислительные ресурсы компьютера (или консоли, или мобилки), поэтому применяют этот способ редко. |
В зависимости от целевого объекта (от того, на что наложено отражение) зонд делает либо рендер-панораму, либо рендер-сферу, либо рендер-сектор. Для ваз и других объемных объектов предпочтительнее сфера или широкая панорама, для зеркал и окон обычно хватает узкого сектора. В последнем случае камера закрепляется непосредственно перед зеркалом или за зеркалом так, чтобы в ее «поле зрения» попадал соответствующий участок сцены.


Скайдом (Skydome) и панорама
Зонд снимает и рендерит окружение в режиме реального времени. В некоторых движках это делается покадрово (зонд сохраняет отдельные кадры с заданным интервалом), в некоторых непрерывно или в соответствии с частотой обновления экрана (FPS соответствует основному FPS игры на данном устройстве). Поскольку технически игра рендерит данную сцену дважды и дважды выводит рендер, этот способ съедает очень много вычислительной мощности и видеопамяти.
Отраженная камера. Некоторые движки поддерживают создание дубликата камеры, которая учитывает движения основной камеры и проецирует отраженный рендер на статическое зеркало. Как правило, берут только плоские зеркала, иначе неизбежны искажения.
Трассировка лучей. Второй способ — т. н. «трассировка лучей» или отслеживание путей лучей. Как правило, это относится только к лучам света и их отражениям, но не очень хорошо отражает физические объекты.
Шейдеры.Чтобы не настраивать камеру и отражение каждый раз, можно сделать шейдер. Шейдер — это программная настройка материала с сохраненными параметрами. Чаще всего, выглядит как небольшой сценарий, зачастую с прилагающимися к нему текстурными картами разной степени сложности. В том числе есть шейдеры с рефлекторами, как в виде простых кубмапов, так и с настройками отраженных камер. Эти шейдеры можно сделать самому, а можно найти в платных и бесплатных библиотеках для каждого движка отдельно
Итого
Сделать даже простое отражение в 3D-движке задачка нетривиальная. Большую часть времени вам не придется думать об этом, достаточно будет простых текстур наподобие кубмапа. Но если отражение для вас важно — придется раскошелиться на время создания зеркала и мириться с просадками производительности.
С вами была Людмила Хигерович. На сегодня у меня все. Всего хорошего и не болейте!
НЛО прилетело и оставило здесь промокод для читателей нашего блога:
— 15% на заказ любого VDS (кроме тарифа Прогрев) — HABRFIRSTVDS
Авторы мультсериала «Аватар: Семь убежищ» показали новый трейлер и объявили о более раннем релизе проекта
Зак Креггер рассказал об изменениях в «Обители зла» после тестовых показов
Новый анимационный фильм по «Наруто» могут представить 10 октября
Ремейк Resident Evil 2 установил новый рекорд для Capcom
Until Dawn 2 получила неожиданно низкую цену от Sony
Sega работает над новой частью Crazy Taxi
Phantom Blade Zero удивит игроков возможностью получить платиновый трофей за одно прохождение
Анонсирована CarX Rally, которая может стать конкурентом Assetto Corsa Rally