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

image
Автор, биотехнолог Людмила Хигерович. Зам. руководителя сообщества Фанерострой

▍ Поговорим о нормальных картах

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

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

▍ Что нормально, а что нет?


Обычный набор текстур босса из Bloodborne:

Если Вы интересуетесь 3D-моделированием, то наверняка хотя бы раз сталкивались с понятием карт (map). Причём слово «карта» имеет очень много дополнительных уточнений: диффузная карта, карта наложения, нормальная карта, карта смещения, карта высот, карта цвета, альфа-карта, карта шейдера, карта свечения, карта блеска, карта света, карта подповерхностного рассеивания и т.п.

Всё это — дополнительные элементы модели, так или иначе, улучшающие её внешний вид. По сути своей, текстурные карты — графические файлы («картинки») с соответствующими расширениями (bmp, png, tga, jpg, dds и т.п.), в слоях или строках которых зашифрован не только цвет, но и какая-либо дополнительная информация (наличие и сила альфа-канала, проще говоря, прозрачности; отклонения света, сила блеска, насыщенность и т.п.).

Для того чтобы потом не отвлекаться, проведём краткий экскурс по картам. А чтобы Вы не теряли время, засунем их под спойлер.
СПОЙЛЕР: Карты бывают разные - синие, белые, красные
Карт в 3D-моделировании великое множество, и в каждом графическом движке они имеют свои виды и особенности. Поэтому мы постараемся кратко пояснить, что какая карта делает. Но имейте в виду, что в Вашем конкретном движке карты и соответствующие им кнопки могут незначительно отличаться по названию и функции.

Самая важная карта — карта наложения или UV-map. Она определяет как именно текстура будет ложиться на Вашу модель и какие полигоны будут соответствовать «островам» на текстуре. UV-карта и информация о наложении хранится в файле самой модели (обычно), и изредка в специальных форматах библиотек наложения или программных информационных файлах, а в редких случаях — ещё и в составе алгоритма шейдера (программного сценария графической визуализации). 


UV-развертка и модель снаряжения. Сделано мной.

Диффузная карта (diffuse map/ color map) — это карта цвета или раскраска модели. Она пришла на смену объектной заливке и раскрашиванию полигонов моделей напрямую. Долгое время это была единственная карта, применимая к модели (помимо UV), и до сих пор многие игры (особенно мобильные, где максимально важна экономия пространства памяти и вычислительных ресурсов) обходятся только ею. Умелая работа с диффузной картой действительно способна заменить в какой-то степени другие карты, но всё же её часто бывает недостаточно.


Diffuse map сама по себе и на снаряжении. Моё.

Альфа-карта, просто альфа или карта прозрачности (alpha / transparent map) — карта, отвечающая за чтение прозрачности на текстуре. В игровых движках эту функцию на себя часто берёт диффузная карта, в которую встроен альфа-канал (наверняка Вы видели эту кнопку в фотошопе). Он может быть как действительно прозрачным (png файлы), так и просто нести информацию о прозрачности (dds и tga форматы), не отображаясь в файловой системе компьютера, как прозрачный.

В некоторых программах (например, в Keyshot или Daz studio) Вам иногда потребуется альфа-карта как отдельный файл (для сложных текстур, например, волос и ресниц). В таком случае Ваша карта будет выглядеть чёрно-белой, где чёрный цвет означает 100% прозрачность, а белый — 100% непрозрачность. Причём для Даза и Кейшота даже необязательно наличие именно альфа-канала на альфа-карте, главное соблюсти цветовую пропорцию, да, всё сложно. А как Вы хотели?


Альфа-карта прозрачности для волос. Моё.

Карта блеска (specular map) — карта, ответственная за силу и иногда цвет блеска. Как нетрудно догадаться, чёрный цвет означает отсутствие блеска, белый — его максимум (в некоторых движках может потребоваться вмешательство альфа-канала, но в общем случае это не нужно). Кроме оттенков чёрного и белого спекуляры могут нести и другие цвета. Например, Разверстый дракон в игре Dark souls блестит оттенками синего и фиолетового (если Вы его успеете рассмотреть, конечно).


Карта блеска (specular) и её действие в кейшоте (тоже моё).


Цветной спекуляр разверстого дракона из Dark souls 3.

Карта свечения (emission map/ glowing map) — карта, название которой прямо отображает её функции. Как нетрудно догадаться, чёрный цвет означает отсутствие свечения, чисто белый — максимальное свечение. Но большинство игровых движков читают не только силу белого, но и все доступные оттенки цветовых каналов, позволяя раскрасить условного дракона во все цвета радуги. При этом некоторые графические движки позволяют читать карту свечения как источник света — то есть, создавать от него блики на других частях модели и других моделях (например, тот же Кейшот или движок Скетчфаба).


Карты свечения и их действие на примере Стража древних богов из Bloodborne.

Карта пространственного отражения (environmental map/ metallicity map). Этот термин имеет два значения: карта наложения отражения (отвечает за то, какие участки модели будут иметь это свойство) и собственно текстура отражения (также environment map/ cubemap/ metallmap/ sphere map и т.п.). В первом случае существуют разные подходы к её осуществлению, обычно используют очень любимый нами альфа-канал, добавляя его к различным другим текстурам. Например, альфа-канал нормали в Скайриме отвечает за наложение этого самого отражения, если в настройках nif-модели прикрепить соответствующий металлик или отражение. При этом сила блеска отражения берётся с карты — пометка _m (metalicity). 


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

Что-то подобное есть и в Dark souls 3, где в альфа-канале нормали закодированы участки металлического блеска и карты окружения, а в аномально светлом спекуляре — сила и оттенок этого блеска.


Карты для кирасы рыцарского сета из Dark Souls 3 (сверху вниз: диффузная, карта нормалей и спекуляр). Сбоку карта окружения (с фрагментом неба) и её отражение на кирасе. Отметим, что карты окружения в DS3 динамические, и сменяют друг друга по мере продвижения по локации. 

Карта подповерхностного рассеяния и просвечивания (translucent map) — немного схожи с предыдущими картами. Эти карты отвечают за то, как модель будет выглядеть «на просвет». Если Вам кажется, что это какая-то бесполезная функция или вообще аналог прозрачности, то вы ошибаетесь. Посмотрите через свою руку на просвет (на лампу или солнце) и Вы увидите, что пальцы и перепонки у их основания словно светятся, просвечивают. То же самое и с полупрозрачными минералами (кварц, яшма, янтарь и т.п.), с частями тела людей и даже листьями. 


Карта подсвечивания для женских персонажей и карта просвечивания для крыла драконов в TES V: Skyrim.

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

Карта света и карта оттенка (lightmap/ambient occlusion map/ tintmap) — карта, отвечающая за то, как Ваша модель будет реагировать на свет. Некоторые движки читают эти карты подобно картам рассеяния, придавая эффект просвечивания, некоторые просто читают её как маску, добавляя оттенки и световые блики к диффузной карте. Изначально эта карта служила для создания светотени, создавая эффекты затенения и освещённости на модели для экономии ресурсов. 


Честно говоря, я не очень помню, откуда эта модель, так как предоставил её друг, для наглядности. Кажется, из Bless online. Слева модель без карт света, справа — с ними, отображаемые тени от лайтмапа делают стилизованную модельку реалистичнее и приятнее глазу.

Сейчас для этого иногда используют более продвинутую версию — карту пространственного освещения (ambient occlusion map), которая, по сути, является гибридом спекуляра и лайтмапа, имитируя свет, тень и блики. Однако, в отличие от лайтмапа, АО не заменяет собой эффект освещения, а читается графическим движком вместе с тенями от источника света, придавая глубину теням для экономии производительности в больших сценах.

В некоторых случаях карта оттенка имеет вид сине-красно-зеленых пятен (как, например, в Witcher 3 или Raid Shadow legends) и сочетает в себе карту оттенков, карту блеска и карту наложения пространственного отражения, закодированные в разных цветах.


Слева: карта Ambient occlusion для сцены боя из игры Raid: Shadow legends, справа вверху: рендер внутриигровым движком (на базе Unity), справа внизу — рендер без окклюзии. Хорошо видно, что карта света и тени из АО создаёт эффект объёма и придаёт живости рендеру. Хочу заметить, что для сцен окружения эта игра использует только диффуз и окклюзию, экономя место и производительность.

Карта смещения (displacement map): чёрно-белая карта, которую графический движок игры или редактора читает, как искажение поверхности модели. В отличие от нормалмапа, дисплейс-карты не имитируют объём, а непосредственно «показывают» движку, как именно должна выглядеть модель, благодаря чему на финальном рендере модель действительно будет иметь объём, а не его иллюзию. Но работая с дисплейс-картами важно учитывать множество нюансов, начиная от того что каждый движок читает их силу и соотношение цветов по-своему, и заканчивая тем, что дисплейс-карты — это векторная информация, и изменение размера модели или положения её в пространстве могут значительно исказить финальный вид.


Слева — тестовый рендер с включёнными displacement и emission картами, справа — рабочий режим без дополнительных карт (только с диффузной). Робот мой.

Карта высоты (bumpmap) — первый предшественник дисплейс-карт и карт нормалей. Чёрно-белая текстура, в которой сила белого определяет силу «выдавливания» объёма на поверхности модели. Сейчас бампмапы как таковые почти не используют (разве что в единичных проектах или в составе шейдера), предпочитая им более продвинутые карты смещения и нормалей, так что сам термин bumpmap сейчас употребляют часто как синонимичный displacement и normalmap, хотя это и не совсем верно.

Нормальная карта (правильнее говорить «карта нормалей», normal map) — карта, имитирующая объём. Она создаёт видимость неровной поверхности за счёт переходов света и тени. Подробнее о тонкостях отображения нормалей мы поговорим позже. 
  • Что такое нормали?
  • В отличие от повседневной жизни, в математике нормаль определяется отнюдь не общественным сознанием.
  • Нормаль в 3D-моделировании — это перпендикуляр к поверхности модели (обычно к вершине многоугольника, но на самом деле к любой точке поверхности). Если Вы помните школьный курс геометрии, то должны знать, что есть такое понятие, как касательная (линия или плоскость). Так вот, если провести касательную плоскость к поверхности модели в выбранной точке, а потом в этой же точке опустить перпендикуляр к поверхности касательной, это и будет нормаль.
  • Запомните касательные! Они нам ещё пригодятся!




В 3D-моделировании вектор нормали проводится к каждой точке поверхности модели (в зависимости от работы движка: к каждой вершине, каждому отдельно взятому полигону или каждой точке меша в пространстве. Последнее сейчас наиболее распространено, но затратно по ресурсам вычислительной техники). Совокупность направлений этих векторов визуализируется как перепады поверхности модели: выступы, впадины и заломы. Если разница между направлениями двух соседних векторов большая, то и перепад будет казаться более резким. Соответственно, чем больше полигонов и вершин, и чем больше разница в векторах нормалей, тем подробнее поверхность модели и тем разнообразнее детализация.


Нормали к поверхности на основе вершин в высокополигональной модели. Да, это Клавикус Вайл (мое).
Примечание: в современных графических движках есть такая функция как «сглаживание» (smoothing). Она отвечает за то, насколько «грубо» читается переход от одной нормали к другой (от одного полигона к другому или насколько сильно искажён полигон). 


Иногда для лучшего сглаживания моделей придется разбивать полигоны на треугольники.

При низком сглаживании модель кажется рубленной или мятой, при высоком замыленной. Единый меш (кусок модели с объединёнными вершинами полигонов), к которому применено сглаживание с заданными настройками, называется группой сглаживания (smoothing group):


Более сглаженная и менее сглаженная геометрия лапки. Моделька моя.

При этом важно понимать, что вычисляется переход между нормалями только соседних вершин в составе меша (единого куска поверхности модели) или группы сглаживания:


Сглаженная и не сглаженная сферы.

Если вершины полигонов в меше («теле» модели) не объединены, то есть, каждый полигон сам по себе, то для каждой вершины каждого отдельного меша нормаль считается отдельно, из-за чего модель также кажется рубленой и грубой.

Однако если сейчас многие киностудии и даже игроделы могут себе позволить сделать модель с парой миллионов полигонов и не сжечь при этом видеокарту (хотя некоторые игры от Square enix всё-таки сожгут), то на заре игропрома такой роскошью не могли похвастаться даже крупные студии. Да и сейчас такое выглядит не слишком-то разумно и экономично. Как выходили из положения тогда?

▍ Намальна? Намальна!


Если нормали к поверхности модели определяют, как на нее ложится свет, то нельзя ли обмануть визуализацию?

Можно. Причём для этого существует великое множество способов — начиная с обмана зрения с помощью карт цвета и заканчивая специальными программными алгоритмами пост-обработки (шейдерами). Но сегодня мы ограничимся картами нормалей.
Точно не известно, кто именно был пионером применения техники создания карт нормалей в играх (хотя точно известно, что распространение эта технология получила благодаря приставке Sega Dreamcast, первой игровой консоли со специальными алгоритмами чтения карт). 

Однако известно, что первым подобный алгоритм описал Джеймс Ф. Блин в 1978 году (эксперт по компьютерной графике лаборатории НАСА). Позднее его идею развили Кришнамурти и Левой, представив свою идею на ежегодной выставке-конференции SIGGRAPH в 1996 году. Там они впервые представили практический способ построения карт смещения в NURBS (неравномерный рациональный базисный сплайн, проще говоря — математическая модель, состоящая из совокупности кривых). Но практически применили перенос детализации с высокополигональной модели на низкополигональную болванку только спустя два года, когда почти одновременно вышли статьи Коэна и Сигнони (не уверена, как правильно читается фамилия), описывающие процесс хранения данных о детализации поверхности в текстурной карте и собственно процесс «запекания» и проекции деталей с высокополигональной сетки на низкополигональную. Тогда же и был придуман алгоритм, которым пользуются до сих пор: кодирование отклонения векторов нормали в цвет.
Карта нормалей или normal map — специфическая текстурная карта, благодаря которой свет в 3D-программе или графическом движке игры понимает, под каким углом ему нужно отражаться от поверхности модели. 

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


Карта нормалей моего мимика из предыдущего поста.

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


Mid-poly модель и её High-poly версия. Моё.

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

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

Аналогично и с картами развертки, на которые будут ориентированы диффузные и нормальные карты: участки «повышенного внимания» делаем большими островами, чем те, кто нам не очень важны.


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

Далее ищем себе программу, в которой будет удобно работать (для меня это Zbrush, для Вас может быть удобен Substance painter, Marmoset toolbag, Blender или Maya Autodesk), и совмещаем обе наших модели так, чтобы они как можно лучше совпадали, но высокополигональная не проваливалась сквозь низкополигональную. Это важно, так как в противном случае, Ваши нормали будут вывернуты, и Вы получите артефакты отображения карты (а в перспективе вылет на рабочий стол при генерации).

Но нужно помнить, что карта нормалей не делает Вашу модель объёмнее. Она только создаёт иллюзию объёма, сама модель так и останется плоской болванкой.

▍ Нормальные алгоритмы


Существует несколько алгоритмов, позволяющих рассчитывать отклонения нормалей и проецировать их с помощью текстурных карт. Самый распространённый способ называется Dot3, и представляет собой кодирование направления вектора нормали по трём осям пространства в соответствующие цвета RGB каналов цвета, причём отклонения осей XYZ соответствуют RGB. То есть, красный канал отвечает за отклонение от 0 (нормали к поверхности) вправо-влево (по оси X), зелёный — вверх-вниз (по оси Y), а синий — по оси Z. А вот дальше начинаются особенности.
Откуда взялась традиция отмечать красным именно ось X, жёлто-зелёным Y, а синим Z, мне найти не удалось. Но абсолютное большинство 3D-программ придерживаются именно такой цветовой схемы в построении осей координат.
Дело в том, что каждый графический движок считывает координаты отклонения векторов нормали по-своему, а значит и результаты отображения будут различаться. Более того, Вы заметите сильные различия, даже если сгенерируете нормалмапы с одной и той же модели в разных программах. 

Вот, например, одна и та же модель, но зарендеренная в разных движках:


Рыцарь собора (cathedral knight) из Dark souls 3.

Существует несколько распространённых подходов к генерации. Кратко расскажем о каждом из них.
Самый общий и простой из них — построение нормалей через пространство касательных или Tangent space. Помните, мы просили запомнить касательные? Вот они и пригодились.

В данной системе координат касательная плоскость к поверхности модели определяется осями X и Y, а ось нормали — Z-ось. Поэтому нормали, сгенерированные по принципу tangent space обычно выглядят синими — основная ось отклонения (выпуклость поверхности) это Z-ось, соответствующая B-каналу RGB-системы:


Карта касательных (мое).

Но и здесь возможны проблемы. При генерации нормалей касательных в одной программе и рендеринге в другой Вы иногда можете столкнуться с тем, что тени на Ваших моделях лежат немного не так, как было изначально. В таком случае проверьте инверсию осей отображения нормалей — благо большинство графических 3D-редакторов имеют для этого отдельную кнопку. Если такой кнопки нет — откройте фотошоп и инвертируйте изображение в одном из каналов. У меня бывали случаи, когда приходилось инвертировать два канала — красный и зелёный.

Плюсы генерации нормалей по принципу tangent space в том, что они универсальны. Например, если вы сгенерировали карту нормалей для плоской кирпичной стены, Вы можете применить эту же карту нормалей на любую другую плоскую стену (или любой «плоскатик») с такой же UV-картой и практически ничего при этом не потерять. Модель с картой пространства касательных можно деформировать, и графический движок будет пытаться вычислять нормали соответственно Вашей деформации. Другими словами, стену можно сломать, но отдельные её куски всё так же будут изображать кирпичную кладку, хоть и с искажениями. При желании, Вы можете натянуть текстуру кирпичной стены на яйцо динозавра, и ничего от этого не потерять. Перекраска стены тоже особой роли не сыграет. 



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


Слева — карта в разрешении 1028х1028, справа — 4к. Визуальной разницы ни в движке, ни в папке незаметно.

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

Несколько иначе генерируются модели по методу пространства объекта (object space/ local space/ model space). В ней основной точкой отсчёта, координат отклонения нормалей, считается не касательная к поверхности каждого отдельного элемента рельефа, а центр масс модели относительно всего пространства координат. По цвету такие карты обычно выглядят как серо-буро-малиновое месиво с усилением оттенков красного, синего и зелёного по углам карты и с резкими градиентами по всей текстуре. При этом сила и оттенок цвета будет соответствовать тому, в какую сторону направлена Ваша геометрия относительно глобальных координат модели (также RGB~XYZ по общему правилу). 


Объектная карта нормалей (мое).

Плюсы: высокая точность геометрии, «красивое» отображение деталей при динамическом освещении, низкая чувствительность к грубым граням и группам сглаживания, более быстрое чтение карты:


Нормали local space на разных объектах.

Минусы: объект не рекомендуется деформировать, так как любое изменение положения вершины в модели относительно всей сетки приведёт к артефактам отображения, нельзя (вернее, не рекомендуется) отражать карту или использовать её на модели с кардинально другой геометрией, плохо поддаются сжатию (буквально каждый пиксель содержит информацию о цветовом, а значит, геометрическом переходе). Более того, из-за особенностей чтения такой карты при изменении цвета модели через diffuse map может потребоваться дополнительно использовать карту АО (ambient occlusion) для коррекции отображения поверхности, а также набор специальных скриптов и шейдеров:


Local (object) space normals в разных местах относительно источника света и оси координат. Одна и та же карта читается по-разному.


Тангенциальные нормали vs объектные нормали.

Нормали пространства камеры (camera space) — вещь настолько редко используемая, что я и сама не слишком много о ней знаю. Могу сказать только, что её иногда используют для создания HDR-пространств и карт окружения (environment map), а также для запекания специфического типа нормалей для рендеринга украшений.

Надо сказать, что в игропроме нет какой-то четкой привязки к тому, какие именно нормали использовать и в каком случае — это строго индивидуальный и технический вопрос, не лишённый толики вкусовщины и экспериментаторства. В одной игре может использоваться сразу 2-3 типа генерации нормалей (например, большая часть моделей в Скайриме «нормализованы» по принципу tangent space, но модели тела и лица персонажей типа «гуманоид» включая аргониан и каджитов имеют запечку object space и прилагающиеся к ним tintmap и шейдеры для коррекции отображения. К тому же тамошние модели инвертированы относительно оси Z наперекор большинству программ. Спрашивается, ну и зачем такой гемор?


Разные виды нормалей в Скайриме.

Во многих играх комбинируют не только нормали разного типа генерации, но и разные типы имитации объёма. Так, в Bloodborne и Dark souls 3 у некоторых боссов до 6 типов карт, включающих диффузную карту с альфа-каналом прозрачности, карту нормалей с альфа-каналом металлика, спекуляр с силой и цветом металлика, металлик (environment), карта свечения и карта шейдера (шерсти или эффекта). Но игровой движок From software не может поддерживать более 4 текстур на одном меше одновременно, так что модели разбиты на полигруппы (меши) так, чтобы не перегружать движок, но при этом обеспечить максимально плавный переход между соседними мешами с разными текстурами. Быть может, поэтому некоторые участки и арены с боссами в играх «фромов» выглядят достаточно тёмными.


Tangent space normals Dark Souls 3, инвертированные по синему. Тангенциальные карты DS3 и некоторых моделей подземных чудовищ Sekiro, Bloodborne и Elden ring выглядят зелёно-красными. Пусть это Вас не слишком пугает, они всё ещё сделаны в пространстве касательных, но с инвертированным каналом относительно Z (и иногда X, особенно в архивах из вырезанного контента. Видимо, осталось со времен подбора настроек движка).

Кроме того, порой Вы и не поймёте, какого именно типа нормалмап перед Вами, если залезете в архивы игры и сможете-таки распаковать специфическое сжатие текстурных файлов. Так, мы уже говорили о том, что карты нормалей Скайрима содержат дополнительный альфа-канал для карт окружения и металлического блеска, из-за чего они выглядят не лилово-голубыми, как положено тангенциальным картам, а чёрно-синими. При этом, в большинстве своём обычные лилово-голубые карты движок Скайрима (по крайней мере, LE)  вполне переваривает и даже отображает, но вот с наложением металлика на такие модели могут возникнуть проблемы (моддер с 10-летним стажем детектед). 

Да и в самом игровом движке наличие некоторых карт и их качество может вызывать артефакты и даже приводить к вылетам игры. Так, одновременное наличие карты отражения, свечения и наложение шейдера с прикручиванием эффекта искр к Маледикту из Doom 3: RE в Скайриме привело к крашу игры, хотя в окне редактора всё было в полном порядке.


Вполне видимый горелый Меледикт в редакторе моделей Скайрима (Nifskope), в Creation kit тоже нареканий не вызывал. Но когда он появляется в игре, то все.

Особенное впечатление производят нормалмапы от некоторых студий. Например, ранние карты нормалей от Ubisoft (создателей Ассассинской саги) выглядят розово-красными. Инверсия каналов цвета при этом не слишком помогает, так что для исправления отображения этих карт приходится перегенерировать их или прогонять через конвертеры, инвертирующие RGB.

Кроме того, есть и другая градация нормалей -  эксплицитные (explicit) и усреднённые (averaged). Подробно я на них останавливаться не буду, так как это слишком тонкий вопрос. Скажу только, что в общих случаях обычно применяют explicit normals, так как он более лоялен к искажению деталей, хотя и может выдавать артефакты на краях жёстких граней и в местах разрезов UV, тогда как averaged normals выглядит хорошо на границах, но может сильно искажать высоко выступающие детали, стягивая их к центру меша.

▍ Генерируем. Нормально


Для тех, кто дожил до этого места и не сломал себе моск (или ещё не захотел прибить автора статьи за неточности в описании процессов), приведём несколько практических способов генерации нормалей. Начнём с самого требовательного — с генерации нормалей из хайполи геометрии.

Для этого нам понадобятся: 

  • Лоуполи модель (желательно в формате obj) (низкополигональная болванка, если нет, то сделаем)
  • Хайполи модель (если её нет, сделаем в процессе)
  • ZBrush, желательно R21, так как я чаще всего пользуюсь именно им и он наиболее стабилен и максимально лоялен к нулевому скиллу в запекании.

1. Для начала импортируем нашу обж-шку в зибраш. Жмякаем на панели справа (по умолчанию именно там находится панель Tools) на большую кнопку Import и находим нужную модель. Либо довольствуемся базовой сферой (Sphere 3D), выбрав её на той же панельке (главное, не перепутать с ZSphere, специальным инструментом рига и ретопологии):



После загрузки нашей модели вверху слева жмём на иконку Edit, чтобы активировать режим редактирования, и сразу жмём Make Рoly Мesh 3D рядом с кнопкой импорта, чтобы избежать дальнейших проблем.

2. Если у Вашей болванки заранее была создана UV-карта, переходим к следующему пункту.
Если нет, то всё необходимое у нас под рукой: открываем в верхнем меню ZPlugin — UV-master. Далее нужно проверить несколько пунктов.

Для экономии места и времени поместим их под спойлер.
ТЫК
  • Если модель симметричная, то жмём кнопку symmetry, чтобы генератор развёртки попытался расположить острова симметрично. 



  • Если в Вашей болванке несколько мешей и Вы хотите, чтобы каждому из них соответствовал свой «остров» на текстуре, то переходите на панель Tool, найдите свиток Polygroup и нажмите Auto Group. Зибраш автоматически определит границы мешей и назначит их в полигруппы по местам разрывов. Посмотреть свои полигруппы можно по нажатию иконки PolyF справа от рабочей области.



  • Если в процессе импорта Ваша модель «развалилась» (то есть, вершины полигонов в группе сглаживания вдруг отсоединились друг от друга. Да, так бывает и весьма часто), то идём в Tool — Geometry — Modify topology и ищем там пункт Weld points. В большинстве случаев, этого достаточно. 



  • Если в Вашей модели обнаружились непредусмотренные дыры, то рядом с Weld points ищем кнопку Close Holes. Обычно этого хватает, но иногда в моделях со сложной геометрией эта кнопка начинает «выстилать» модель дополнительным слоем полигонов изнутри. Точного правила для такого эффекта нет, так что каждый случай проверяйте отдельно. Отмена действия в зибраше такая же, как и везде: Ctrl+Z или по ползунку действий над рабочим полем с моделью.

  • Если у Вашей модели нет полигрупп, но очень хочется их сделать, да ещё и ровными, то тогда замаскируйте куски модели (зажмите Ctrl и поводите кистью по поверхности либо зажмите Ctrl и потяните из пустой области рабочего поля), перейдите по уже знакомому пути Tools — Polygroup и найдите внизу кнопку Group masked (после этого можно нажать Clear mask или провести с зажатым Ctrl по пустой области). Если хотите разбить ещё больше, щелкните ЛКМ по новообразованной группе с зажатым Ctrl+Shift и повторите процедуру с маскированием и нажатием Group masked. Отменить скрытие групп можно, щелкнув Ctrl+Shift+ЛКМ в пустом месте.



  • Если полигруппы Вас не устраивают, и Вы вручную хотите назначить места разрезов на UV-карте, тогда переходите во вкладку Zplugin — UV master и активируйте кнопку Enable control painting. Тогда Вам станут доступны ещё три кнопки — Protect, Attract, Erase (защитить/оставить без разрезов, разрезать по линии и стереть марки соответственно). Ими и раскрашивайте Вашу модель, обозначая красным зоны, которые должны оставаться нетронутыми, синим места разъединения и предпочитаемые швы. Главное, не сильно увлекаться: слишком близко расположенные марки могут сбить программу с толку, а слишком большое или недостаточное количество разрезов приведёт к искажению сетки на карте.
После проверки всех вышеперечисленных пунктов (или проигнорировав оные) жмякаем кнопку Unwrap («развернуть»). Программа на какое-то время «зависнет», под верхними вкладками поясняя, какой именно этап создания развёртки сейчас происходит. Развёртка лоуполи моделей в среднем занимает от полуминуты до нескольких минут в зависимости от сложности модели и количества полигрупп. Иногда по неизвестной причине плагин может зависнуть, и тогда придется нажимать кнопку «развернуть» заново.



Проверить и поправить свою развёртку можно, нажав на панели UVmaster кнопку Flatten. Здесь с развёрткой можно работать как с обычной моделью теми же инструментами. Если развёртка устраивает, возвращаемся к обычному виду с помощью кнопки Unflatten.

3. Лоу-поли болванку с готовой развёрткой теперь нужно обеспечить подробными деталями. Для этого копируем нашу модель (Subtool — duplicate), чтобы сохранить лоу-поли болванку, увеличим плотность сетки с помощью инструмента Tool — Divide (или Ctrl+D). Это поднимет полигонаж примерно в 4 раза за каждое нажатие кнопки (каждый четырёхугольник разбивается на 4 части), количество уровней подразбиения будет записано вверху над ползунком SDiv (subdivides — подразбиения), где вы в любой момент можете переключаться между уровнями детализации. Теперь можно лепить объёмные детали поверх болванки.


Примечания: 

  • Если в процессе подразбиения появляются дыры, отмените действие и  перейдите в Geometry — Weld points.
  • Чтобы сохранить резкость граней, нужно отключить кнопку Smt рядом с кнопкой Divide.
  • На слабых компьютерах не рекомендуется делать больше 4-6 млн полигонов (как только вы перешагиваете порог в 1,5 млн, программа уведомит Вас в строке над ползунком истории действий)
  • В Зибраше Вы можете одновременно рисовать цветом и выдавливать объем. Для этого на верхней панели нужно активировать кнопки Mrgb или Rgb (рисование материалом и цветом или только цветом) и Zadd/Zsub. Рисование с зажатой кнопкой Alt переключит с режима выдавливания на вдавливание и наоборот, а также заменит цвет на альтернативный (посмотреть выбранные цвета можно под палитрой слева).
  • В зибраше есть возможность выбора узора кисти через загрузку альфа-кисти (панель слева — Alpha). Можно выбрать готовую, скачать или сделать самому в фотошопе, нарисовав чёрно-белый узор (черный — нет эффекта, белый — максимальный объем). Работать с альфа-каналом в файле изображения не обязательно, зибраш и без него хорошо читает интенсивность белого.
4. Как только Вы наигрались с лепкой или решили, что детализации у Вашей модели достаточно, переходим к генерации карт.
Если в процессе Вы вдруг удалили самые низкие подразбиения — не страшно. Проверьте «слой» с лоу-поли моделью (которую мы советовали дублировать) на панели Subtool, переместите этот слой вниз (можно просто перетаскиванием строки) и убедитесь, что оба слоя в видимом режиме. Увеличьте подразбиения на лоу-поли модели на такое же количество уровней на панели Geometry. Теперь на панели Tools разверните строку Project, активируйте кнопки Geometry и Color и нажмите Project all. В общих случаях этого должно хватить, в редких надо будет поиграться с ползунками Dist и Mean.



Первой генерируем текстурную диффузную карту (цвет). Для этого идём на панель Tool — Texture map и нажимаем Create — New from polypaint. Текстура запечётся на модели, а вам станет доступна кнопка Clone. Смело жмите её и жмём на появившемся её клоне слева, затем Export. Текстурная карта готова.

Теперь идём на панель Geometry и опускаем все сабдивы до нуля (но не удаляем их!). Снова спускаемся вниз по боковой панели, находим кнопку Normal map и жмём Create normal map. 



По умолчанию в браше активна кнопка Tangent и карта нормалей генерируется по принципу касательных. Её можно отключить, и Вы получите объектную карту нормалей.


Слева — сгенерированная карта по принципу tangent space, слева — object space.

Все. Наша нормаль запеклась. Повторяем нажатие кнопки Clone и Export.Здесь же можем выбрать способ запечения нормалей (тангенциальный или адаптивный), а также сгладить или отразить нормали или переключить вектора XY. 

▍ Хитрость — это нормально!


Бывает так, что уже после запечения карты на модели Вы заметили, что чего-то не хватает. Или в последний день пришли правки, в которых заказчик потребовал в срочном порядке налепить или замазать лишнюю заклёпку на корпусе или добавить царапин на кирасу. А нормального компа под рукой нет, да и перегенерировать десяток карт не очень-то хочется. Есть ли какой-то выход из положения? Конечно, есть!

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


Слева направо: запечённая в ZBrush карта нормали мятой кирасы, сгенерированная в PS карта из диффузной, объединённая и отредактированная конечная карта.

Главный и самый близкий друг любого моделлера — Photoshop. В нем Вы сможете не только подправить цветовую карту, но и подработать карту нормалей.

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


Отредактированные в фотошопе нормали кирасы. Моё.

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


Nvidia normal map фильтр для фотошопа.

Кроме того, сейчас есть хороший плагин-фильтр для фотошопа (а также самостоятельная программа): Nvidia Tools (новая версия с официального сайта). Он позволяет кроме прочего генерировать карты нормалей весьма хорошего качества исходя из соотношения света, тени и яркости диффузной карты или карты высот. При этом каждая неровность будет отображена на нормалмапе. В плагин встроено множество настроек и режимов, включая инвертирование по цветовым каналам, учитывание слоёв изображения, настройку силы и резкости выдавливаний и конверсию каналов и всей карты нормалей в карту высот:



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

Нечто похожее в плане самостоятельных программ — ShaderMap Pro. В него встроен целый ряд настроек генерации карт, включая карту нормалей, дисплейс карту и спекуляры, а также настройку глубины, инверсию осей и перегенерацию новой карты нормалей на основе загруженной.



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

Существует также целый ряд бесплатных программ и сайтов с автоматической генерацией карт.
В первую очередь, вам поможет бесплатный сайт. Сюда Вы сможете загрузить изображение условной гайки или шестерёнки и получить на выходе normal и/или displacement карту.



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


Сайт не очень удобно отображает текстуры (в реальном разрешении, без подгонки), так что работать с настройками бывает проблематично.

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

Зато точно могу сказать, что какого-то единого идеального правила или универсального алгоритма создания и работы с картами нормалей до сих пор не существует, поэтому не стесняйтесь экспериментировать и пробовать что-то новенькое, даже если оно покажется Вам совершенно безумным.
Конкурс статей от RUVDS.COM. Три денежные номинации. Главный приз — 100 000 рублей.

Комментарии (0)