Google DeepMind представила модель Genie 2 для создания интерактивных 3D миров 🔔 В сгенерированных сценах можно бегать, плавать, стрелять и взаимодействовать с неигровыми персонажами. #софт@cgitems
Понятие Normal. Функции Cage и Average Normal. Для чего они применяются

Мы уже касались темы нормалей в статье Hard и Soft edges. Группы сглаживания в которой разобрались, как vertex normal (нормаль вертекса) влияет на внешний вид вашей модели. Теперь давайте немного углубимся и разберемся с тем, как именно работают нормали в целом. Коснемся таких тем как baking (запекание) и normal map (карта нормалей). Мы не будем чрезмерно углубляться в эти понятия, на эту тему будут отдельные статьи, но на их основе сможем лучше понять что такое нормали и как они работают. В результате, мы разберемся как взаимодействовать с нормалями при запекании, рассмотрим понятие Average normal. Для наглядности будем использовать программу Marmoset Toolbag, так как она проста, удобна в применении, имеет ряд современных и простых в управлении функций и решает подавляющее большинство задач, связанных с запеканием. По факту, вся базовая теория одинакова для любой программы, отличаются только методы и некоторые способы работы с ними.

Vertex Normal и Face Normal

Average_Normals_cgitems.ru_1-1.png

Зайдем издалека и вспомним, что такое нормаль - это вектор перпендикулярный к точке, из которой он выходит. Нормаль применяется для расчёта света на меше. Face normal указывает общее направление полигона, а vertex normal - направление вертексов.

Average_Normals_cgitems.ru_1-2.png

Теперь вспомним такие понятия как Hard edge и Soft edge. Hard edge - это ребро, которое имеет четыре нормали, по две на смежный полигон. Также, вам может встретится понятие “split normal” - разделенные нормали. Это позволяет отобразить полигоны как две отдельные плоскости. Соответственно, при просчете света на таком участке будет “скачок” - разрыв плоскостей, запомним этот момент, мы еще вернемся к нему в дальнейшем.

Average_Normals_cgitems.ru_1-3.png Soft edge - это ребро, которое имеет усредненные нормали и отображается как плавный переход между полигонами. Average_Normals_cgitems.ru_1-4.png

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

Итак, мы вспомнили что такое нормали и теперь можем идти дальше. Для чего все это затевалось - нормали важны в процессе запекания, так как именно они влияют на качество карт нормалей, а следовательно - на финальный вид вашей модели. Чем лучше вы будете понимать как они работают, тем лучше будете понимать от чего зависит результат, полученный после запекания.

Запекание Normal Map

Возьмем простую high-poly модель и запечем ее на плоскость. По сути, мы возьмем информацию о нормалях high-poly и с ее помощью воздействуем на нормали low-poly - передадим информацию о направлении падения света на разных участках. Да, звучит несколько сложно, но сейчас мы во всем разберемся.

На первых двух примерах вы можете наблюдать High-Poly модель с включенным отображением нормалей полигонов. Они показывают движкам, под каким углом на них должен падать свет.

Наша задача - перенести эти значения на low-poly модель. В нашем случае это будет плоскость (Low-Poly). В результате мы получим поверхность, которая будет визуально передавать объем, но при этом не иметь огромного количества полигонов.

Average_Normals_cgitems.ru_2.png High-Poly модель, с которой мы берём информацию Average_Normals_cgitems.ru_3.png Каждый из множества полигонов имеет свое направление, которое было присвоено ему в процессе построения топологии Average_Normals_cgitems.ru_4.png Low-Poly модель, представляющая собой плоскость - один полигон, который примет на себя информацию от High-Poly Average_Normals_cgitems.ru_5.png Итак, мы подготовили UV-развертку, и запекли все это дело в Marmoset toolbag. Что вышло в результате.

Как видите, результат неплох - информация была передана весьма точно и объем передается вполне достоверно. Безусловно видно, что это имитация объема, именно по этой причине всегда надо заранее прикидывать - какие элементы модели будут запечены, а какие переданы геометрией. Но речь сейчас не об этом. Давайте разберемся, как именно работает этот процесс. Для этого в общих чертах коснемся того, как устроена карта нормалей.

Average_Normals_cgitems.ru_6.png

Это, собственно, карта нормалей которую мы только что получили. Для ее создания программа для запекания берет low-poly модель и проецирует лучи по направлению ее нормалей. Длина этих лучей ограничена, чтобы не зацепить дальние грани и не исказить результат.

Итак, эти лучи сталкиваются с high-poly моделью и берут информацию уже о направлении ее нормалей. Происходит расчет результатов движения и направления лучей, на их основе создаётся карта нормалей. Давайте посмотрим на обобщенной схеме.

Average_Normals_cgitems.ru_7.png

Мы получили некую карту в приятных глазу оттенках (если цвет значительно отличается, значит вы смотрите либо не на карту нормалей, либо это иной тип карты для других задач, либо в работе были допущены ошибки). Почему она таких цветов и как эта карта способна выдать результат, вроде того что на примере выше. Суть в том, что любая карта имеет стандартные цветовые каналы, которые наверняка не раз попадались вам в разных ситуациях - RGB (red, green, blue). Каждый из этих каналов содержит в себе информацию. В случае с картой нормалей это информация о нормалях (внезапно) - а именно о направлении падения света. По сути, это набор из трех текстур в оттенках серого, каждая из них указывает свое направление нормалей. Да, из этого следует то, что каналы RGB могут содержать информацию разных типов.

Average_Normals_cgitems.ru_8.png Три изображения распределяются по каналам RGB, и вместе формируют карту нормалей

Красный канал содержит информацию о падении света справа налево, зеленый - о падении света сверху вниз, синий отвечает за освещение спереди - фронтальное. Для болеё легкого понимания Normal Map можно воспринимать как оси XYZ в трехмерном пространстве. Все вместе они дают движку информацию о том, как модель реагирует на освещение с разных сторон, а их сочетание дает вот такой сиреневый оттенок.

Собственно, изначально полученные при моделировании нормали и их направление позволяют собрать и распределить эту информацию по каналам посредством запекания.

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

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

Нормали как инструмент для запекания

Давайте рассмотрим несколько примеров. В процессе мы используем одну и ту же модель, но при этом рассмотрим несколько функций, которые повлияют на результат.

Average_Normals_cgitems.ru_9.png Average_Normals_cgitems.ru_10.png Average_Normals_cgitems.ru_11.png Average_Normals_cgitems.ru_12.png Как видите, в каждом случае что то пошло не так. Каждый из примеров - результат того, как программа запекания взаимодействовала с нормалями. Давайте рассмотрим их подробнее и разберемся, каким образом это произошло.

Функция Cage и управление нормалями с ее помощью

В marmoset toolbag есть такой инструмент как Cage (клетка), он имеет ряд параметров, которые позволяют вручную повлиять на то, как программа будет работать с нормалями вашей модели. В его основе лежит стандартный для всех программ запекания принцип - это клетка, оболочка, которая обволакивает вашу модели и внутри нее происходит то самое запекание при помощи лучей, которые считывают направление нормалей. Размеры и форма этой клетки определяются при помощи нормалей вашей low-poly.

Average_Normals_cgitems.ru_13.png Таким образом cage выглядит в marmoset toolbag на нашем примере

На примере видно, что она построена по вертекс нормалям куба, который используется в качестве Low-Poly модели. Cage имеет некоторый отступ, который определяет длину лучей для запекания. Этот момент подводит нас к примеру 1. От высоты выступающих объектов на high-poly будет зависеть, хватит ли длины лучей (габаритов cage) чтобы спроецировать все эти объекты и перенести на карту нормалей корректно.

Параметр Offset. Baking distance

Average_Normals_cgitems.ru_14.png

В нашем примере круглые элементы на кубе, назовем их заклепки, имеют высоту. По умолчанию дистанции cage не хватает, чтобы считать их полностью. Разумеется, можно увеличить размер Low-Poly, но это повлечет за собой некоторые проблемы при запекании. Можно уменьшить высоту заклепок. Но далеко не всегда это выход, так как размеры элементов это важная часть визуальной составляющей вашей модели, и подобные элементы не стоит делать слишком мелкими и плоскими. В этой ситуации нам поможет увеличение размеров cage.

Увеличивая значение мы, по сути, увеличим длину лучей и они смогут считать всю информацию о нормалях High-Poly.

Average_Normals_cgitems.ru_15.png Как видите, проблема решена. Размер cage стал больше, и он начала включать в себя выступающие элементы целиком. Работая с размерами cage стоит помнить о том, что также он может зацепить соседние элементы, если у вас более сложная модель. Понимание того как работает cage требует некоторой практики, но зная общий принцип ее работы вы поймете как избегать этого.

Итак, мы запекли все элементы, но осталась еще одна проблема - заклепки стягиваются к центру поверхности. Это подводит нас к примеру 2 и на его основе мы разберем еще одну функцию cage - управление нормалями.

Функция Paint skew. Исправление перекосов при запекании Normal Map

Одна из особенностей cage заключается в том, что он может брать направление нормалей Low-Poly модели и корректировать их. Он не воздействует непосредственно на модель а, скажем так, копирует нормали на себя и добавляет их значения к значениям нормалей модели, либо заменяет. Об этом и поговорим.

По умолчанию на cage включена функция Average normal. То есть усреднение нормалей. В marmoset toolbag эта функция называется Smooth cage, но о ней чуть позже.

Average_Normals_cgitems.ru_16.png Если в настройках cage вы нажмете кнопку Paint skew, то включите отображение нормалей cage.

Как уже было сказано выше - он берет их с Low-Poly, но при этом усредняет, стягивает от центра полигона к ребрам. Это позволяет равномерно распределить свет и его переход по поверхностям, и запечь корректные фаски. Но у этого есть обратная сторона - все элементы на плоскости также будут стянуты, так как усредненные нормали определяют финальный вид запеченных элементов. Именно по этой причине заклепки скосило - каждая из них смещена в сторону смещения нормалей. Как это решить?

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

Average_Normals_cgitems.ru_17.png Как видно на примере - мы точечно воздействуем кистью на нормали, и те из них что выпрямились окрашиваются в красный цвет. Участки вне кисти остаются незатронутыми и отмечены зеленым. Average_Normals_cgitems.ru_18.png Результат - чистое запекание без искажений. Почему это так работает? Потому что на меш влияет функция Average Normal, в Marmoset Toolbag за это отвечает параметр Smooth cage. И это подводит нас к примеру 3.

Average normal, smooth cage.

Усреднение нормалей и смягчение переходов между полигонами

Итак, мы прошли довольно долгий путь и разобрались с тем, как все таки функционируют нормали, и почему стоит понимать как они работают. По сути, нормали это ключ к тому, как движок будет реагировать на ваши поверхности модели, а именно - распределять по ним освещение. Мы уже знаем, что мягкие и жесткие ребра, это результат работы нормалей - их усреднения, либо разделения. Наш пример с кубом наглядно показывает влияние Average normal на то, как будут выглядеть стыки полигонов под 90 градусов и насколько хорошо на них будут запечены фаски.

Как мы помним - если на стыке стоит hard edge, то в этом месте образуется скачок при обработке - переход с одной грани на другую. И этот скачок надо сгладить, иначе он будет запечен на карту нормалей как полоса пикселей, а визуально это будет выглядеть как темная линия. Именно эта задача лежит на функции Average normal.

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

Average_Normals_cgitems.ru_19.png Будет вот так

Как видите - поверхности запеклись строго по направлению плоскостей low-poly модели, и если вглядеться то видно, что вдоль краев идет фаска запечённая с high-poly, но она разбивается по центру, так как граница перехода между гранями никак не скомпенсирована.

Average_Normals_cgitems.ru_20.png Если включить Paint skew, то мы увидим что нормали cage направлены строго под 90 градусов относительно своих плоскостей, вспомните пример выше - разница очевидна.

В этом случае cage взял параметры нормалей с плоскостей low-poly без компенсации. В чем плюс ситуации? За счет того, что нормали по умолчанию перпендикулярны плоскости - заклепки запеклись без смещений.

Примечание: существует способ как обойти это. Запекаются две карты - одна с Average normal, другая без. Далее они совмещаются в photoshop и получается карта нормалей с правильными фасками и ровными выступающими элементами. И в этом плюс Marmoset Toolbag - он позволяет легко и быстро обойти этот момент за счет возможности вручную редактировать нормали отдельным набором функций. По сути это совмещение двух карт Normal Map, только они сразу применяются на модель и в нужном месте мы просто делаем их совмещение через инструментарий Marmoset Toolbag.

Пожалуй, самое время подытожить:

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

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

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

Average_Normals_cgitems.ru_нормально.png
Ваша заявка отправлена!
Если во входящих на почте: нет письма, проверьте папку спам или напишите нам в телеграм