Раз нормально, два нормально… Или имитация объема в плоскости

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

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

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

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

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

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

Обычный набор текстур босса из 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 рублей.


 

Источник

Читайте также