Гайд по бейкингу. Важная теория: часть 2
В продолжение теории бейкинга. Теперь разберемся с картами нормалей, их типами и назначением. Но прежде всего определимся с понятиями нормали, кейджа и битности, чтобы в будущем избежать недопонимания.
Если просто, то это перпендикуляр к поверхности. По нему движок определяет, как от поверхности будет отражаться свет.
Луч света отражается от поверхности симметрично. Если луч падает под углом 45 градусов слева, он отразится под таким же углом и продолжит свое движение вправо.
Еще одна деталь: если две сшитых плоскости находятся под углом относительно друг друга, и их нормали смотрят строго перпендикулярно по отношению к плоскости — их стык будет жестким. Условно говоря, они будут выглядеть как две отдельные поверхности.
Еще нормали можно редактировать для достижения разных эффектов. Например, если изменить угол наклона вектора нормали определенным образом, жесткую грань на стыке двух плоскостей можно превратить в плавный угол.
Так, с помощью редактирования нормалей, можно симулировать трехмерные эффекты на плоскости. На этом принципе редактирования информации о нормалях объекта устроена работа normal map. Только в этом случае данные записываются в RGB текстуру и наносится на объект через материал.
Информация в карты нормалей перепекается с детализированного high poly объекта. Для этого нужны low poly версия модели и её high poly аналог. High poly зачастую отличается сглаженными углами и большей проработкой деталей. Всё зависит от ситуации, но для начала понимания этих различий будет достаточно.
Какую задачу выполняет Low poly модель при запекании? Помимо UV развертки, которая нужна для объяснения программе куда и какой элемент high poly модели запекать на карте нормалей, low poly используется для создания Cage.
Cage — это в какой-то степени копия Low poly модели, которая расширяется по нормалям объекта. Затем, из cage внутрь проецируются лучи, которые захватывают все high poly элементы, попавшие в зону cage, и перепекают их на карту нормалей.
Cage — лишь один из подходов к запеканию, в следующих статьях мы разберем другие способы и расскажем об их достоинствах и недостатках.
От битности зависит количество оттенков, которое может быть записано в изображении. 24-битное изображение может записать 8 бит, или 256 значений в каждый канал. 256 значений обычно достаточно для текстур типа diffuse, specular или gloss map, потому что они используют более широкий спектр цветов, и на них не нужно четко изображать слабые градиенты.
Если утрировать, битность определяет количество доступных промежуточных оттенков на изображении. Чем выше битность — тем больше доступно оттенков.
На практике это пригодится при отрисовке плавных переходов от одного цвета к другому. В следующих статьях мы разберем проблемы, которые может вызвать неправильная битность текстуры.
Самый распространенный тип карты нормалей. Она адаптирует направление нормалей вершин объекта, в зависимости от положения объекта в пространстве. Таким образом, нормали объекта отображаются корректно при любом его положении в пространстве. Из-за различий в алгоритмах отображения карт нормалей, Tangent Space Normal разделяется на два типа: DirectX и OpenGL.
Карта нормалей состоит из трех каналов — RGB. Это нужно для переноса информации о трех осях XYZ из трехмерного пространства в двухмерное пространство текстуры.
Если tangent space normal адаптирует направление нормалей вершин объекта в зависимости от положения объекта в пространстве, то world space normal записывает статичную информацию. Грубо говоря, если объект при запекании был повернут лицевой стороной на север, а позже ты повернешь его на восток, нормали начнут отображаться некорректно.
И хоть невозможно двигать объект в пространстве, у таких карт есть одно преимущество — при работе с ними не нужно думать о направленности нормалей объекта.
Их часто используют в текстурировании, так как они могут дать вводную информацию о том, как свет падает на объект. В Substance painter практически каждый генератор работает в том числе и на основе информации из карты World Space Normal.
Object Space Normal — это модифицированная версия World Space Normal. Она отличается тем, что адаптирует карту нормалей и меняет ее ориентацию при перемещении объекта в пространстве.
Из недостатков: карта не подходит для использования на деформирующихся объектах. Например, её невозможно будет корректно применять на стену с симуляцией разрушения, или на развевающуюся на ветру ткань.
Изогнутые карты нормалей сочетают в себе информацию из AO и normal map. Они помогают усилить работу карты ambient occlusion и нужны для большего контроля над отражаемым от объекта светом. Удобно использовать, если нет возможности подключить Screen Space Reflection.
Большинство из перечисленных карт встречается в работе очень редко, но знать о них нужно, если планируешь расти в 3D. Чаще всего все используют Tangent Space Normal в качестве карты нормалей и World Space Normal для текстурирования.
В следующей статье мы поговорим об особенностях работы с Normal map, расскажем, на что стоит обращать внимание и как избежать лишних телодвижений. Stay tuned.
Это норма — 2: как запекаются карты нормалей
Это вторая часть серии туториалов о картах нормалей. Первая часть находится здесь, но для понимания второй части читать её не обязательно.
Общий принцип запекания карты нормалей относительно прост: у нас есть lowpoly-модель с UV-координатами и highpoly-модель; мы переносим информацию о нормалях с highpoly на lowpoly. Благодаря этому lowpoly будет отражать свет так же, как highpoly.
Во время этого процесса программа запекания по сути испускает лучи из lowpoly, следуя по нормалям вершин и ища higpoly. Это самый важный аспект создания карт нормалей, и бОльшая часть проблем, возникающих при работе с картами нормалей, связан с ним.
Если вы не контролируете нормали вершин lowpoly-модели, то потеряете контроль над картой нормалей.
Плохая корреляция карт нормалей
Чтобы контролировать сглаживание lowpoly-модели, нам нужны разделённые (split) нормали вершин (для создания жёстких рёбер) или усреднённые (averaged) нормали вершин (для создания гладких рёбер).
Как оказалось, не все 3D-программы используют для усреднения нормалей вершин одинаковые вычисления. Это значит, что в разных 3D-редакторах lowpoly-модель будет выглядеть иначе, а её нормали вершин будут указывать немного в разных направлениях. Обычно это не представляет большой проблемы, потому что эти отклонения очень малы, но они влияют на внешний вид модели; и эти различия усиливаются при использовании карт нормалей, потому что карты нормалей изменяют нормали lowpoly-модели, которые в разных программах различаются.
Индустрия 3D-графики работает над устранением этой проблемы; недавно появился стандарт под названием Mikk space. Это метод вычисления нормалей вершин, который могут использовать все 3D-приложения, чтобы нормали вершин во всех 3D-программах выглядели одинаково. Однако нужно учесть, что пока его используют не все 3D-приложения.
Ещё один способ снижения этого влияния заключается в том, чтобы не очень сильно полагаться на карты нормалей при запекании. Попробуйте сделать так, чтобы lowpoly-модель больше напоминала highpoly-модель и используйте больше жёстких рёбер на плоских поверхностях. В таком случае карте нормалей не придётся выполнять всю работу и небольшие отклонения станут менее заметными.
Скос деталей карт нормалей
Когда компьютер усредняет направление нормали у нормалей вершин lowpoly-модели, большие изменения в углах поверхности могут «скосить» нормали lowpoly-модели и они больше не будут перпендикулярными поверхности lowpoly.
Так как программа запекания нормалей при поиске деталей highpoly использует направления нормалей lowpoly, то если эти направления будут скошенными, то они будут выглядеть скошенными на карте нормалей:
Это очень распространённая проблема, для которой найдено несколько решений. Идеального решения нет, всё зависит от геометрии.
1. В некоторых 3D-программах запекания существует опция повторного запекания (rebaking) этих частей с временным изменением нормалей lowpoly, чтобы они запекались без скоса. Например, такая опция есть в Marmoset Toolbag. Пользователь Reddit под ником Tanagashi любезно объяснил мне, что некоторые программы наподобие xNormal могут тесселировать lowpoly, чтобы добавить новые вершины и сделать нормали перпендикулярными к поверхности lowpoly, запекать карту нормалей в пространстве объекта, а затем преобразовывать её в касательное пространство на основании исходных нормалей lowpoly. С помощью новой карты нормалей программа может создавать маски для управления тем, где использовать исходную карту нормалей, а где созданную из тесселированной lowpoly-модели.
2. Добавление вершин сделает переход между нормалями вершин менее скошенным, потому что один угол в 90º будет разделён на несколько меньших градусов, делая второй переход менее скошенным. Очевидно, что это увеличивает количество полигонов, и поскольку вы добавляете геометрию, я рекомендую использовать эти дополнения для создания более интересного силуэта модели.
3. Разделение усреднённых нормалей вершин (делая ребро жёстким/используя отдельные smoothing groups): таким образом, каждая вершина будет иметь несколько нормалей, каждая из которых перпендикулярна к поверхности lowpoly. Не забывайте, что когда 3D-программа имеет разделённую нормаль вершины, то она на самом деле создаёт дубликат вершины, увеличивая таким образом количество вершин и немного снижая производительность. Кроме того, как мы увидим позже, жёсткие рёбра создают проблему «чёрных рёбер».
4. Можно изменять нормали моделей, чтобы изгибать нормали lowpoly, чтобы они были перпендикулярными нормалям highpoly. Помните, что не все программы позволяют использовать изменённые нормали (в Zbrush есть только усреднённые нормали, файлы OBJ и устаревшие FBX не содержат специальной информации о нормалях). По сути, существует два способа изменения нормалей:
Cage/baking distance
По умолчанию, испускаемые с поверхности lowpoly лучи проходят ограниченное расстояние, чтобы lowpoly не получала информацию о нормалях от далёких частей highpoly. Это расстояние обычно называется «frontal/rear distance», потому что лучи могут испускаться по направлению внутрь, наружу, или в обоих направлениях. На рисунке ниже это расстояние показано красным:
Некоторые 3D-приложения (например, 3ds Max) также позволяют использовать «клетку» (cage). Cage — это «копия» lowpoly-модели, которую можно модифицировать таким образом, чтобы она идеально заключала в себе highpoly. Также в некоторых случаях (не всегда) она позволяет нам менять направление лучей, не изменяя при этом исходные нормали вершин lowpoly. Это может помочь получит наилучшие граничные случаи запекания и избежать скосов; однако нужно помнить, что мы запекаем, используя не направление вершин нормалей, но в конечном итоге применим карту нормалей для изменения истинных нормалей lowpoly, поэтому результат может выглядеть странно.
Швы на рёбрах
Как мы видели, если имеется модель с жёсткими рёбрами (некоторые рёбра имеют больше одной smoothing group, или некоторые рёбра помечены как «hard»), то программа запекания разделяет нормаль вершин между двумя гранями. У этой операции есть хорошие и плохие стороны.
Хорошо в ней то, что нормали не усредняются, поэтому присутствует меньше искажений нормалей: нормали вершин полностью перпендикулярны к поверхности lowpoly. Также это может сделать lowpoly более красивой, если у неё есть грани под резкими углами, более подходящими для жёстких рёбер.
Плохо то, что теперь между нормалями существует пробел, и это может означать, что мы можем потерять информацию, если lowpoly имеет пробел в нормалях там, где она не может получить деталей highpoly. Более того, некоторые части проекции lowpoly могут пересекаться и конкурировать за одно UV-пространство. Оба эффекта создают шов вдоль ребра, заметность которого зависит от движка.
Однако этого можно легко избежать при помощи простого трюка: если две грани разделены жёстким ребром, то нужно поместить каждую грань на отдельный UV-остров, оставив между ними пространство. Чтобы снизить влияние проблемы разделённых нормалей, программы запекания пытаются немного дополнительной информации за пределами вершин нормалей, но для этого им требуется на текстуре дополнительное пространство. Если грани, разделённые жёстким ребром, соединены в UV, то для сохранения этой дополнительной информации на текстуре не будет места.
Заключение
Подготовив lowpoly-модель и сделав её как можно ближе к highpoly-модели, я начинаю работать над сглаживанием перед UV. Я задаю сглаживание для lowpoly (если объект органический, то я начинаю с полностью сглаженной модели, если он имеет твёрдую поверхность, то я задаю угол сглаживания в пределах 30-60º и настраиваю сглаживание, пока результат не будет выглядеть хорошо).
Подготовив сглаживание модели, я начинаю работать над UV, разделяя все жёсткие рёбра на отдельные UV-острова (чтобы избежать швов на рёбрах).
Если возникают ошибки со скосами, то я добавляю дополнительные рёбра (обычно я делаю фаски (bevel), чтобы сохранить округлость силуэта). Это срабатывает для большинства моих моделей, но я могу исправлять ошибки со скосами, если использую для запекания Marmoset Toolbag, или применяя собственные/взвешенные нормали.
При наличии ошибок проецирования я изменяю baking distance/cage, модифицирую lopoly/highpoly, чтобы они лучше подходили для запекания, или удаляю карты нормалей на отдельных очень жёстких частях, например, на концах конусов.
Следующая статья будет инструкцией по устранению проблем с запеканием карт нормалей и обсуждением наиболее часто встречающихся проблем и решений.
Это норма — 3: типы карт нормалей
Как и многие другие вещи в нашей отрасли, за многие годы карты нормалей эволюционировали, и сегодня существует несколько их типов, которые могут выглядеть по-разному. В статье я перечислю те, которые помню, но, возможно, существуют и другие.
Карта нормалей касательного пространства (Tangent space normal map): самый распространённый сегодня тип карт нормалей; именно о нём мы говорили в предыдущих статьях. Он модифицирует направление нормалей модели на основании направления нормалей её вершин (то есть нам нужно контролировать нормали вершин lowpoly-модели).
Карта нормалей касательного пространства Mikk (Mikk tangent space normal map). Не все 3D-редакторы вычисляют среднее нормалей вершин одинаково. Это приводит к тому, что в разных движках внешний вид карт нормалей отличается, поэтому нам нужно запекать карту нормалей при помощи того же способа, который использует программа рендеринга (это называется «использовать синхронизированный рабочий процесс (synched workflow)»)
Mikk предложил способ вычисления нормалей вершин, который должен был стать универсальным, чтобы все программы вычисляли их одинаково. С точки зрения рабочего процесса это означает, что можно использовать низкополигональную модель (lowpoly) со всеми её усреднёнными нормалями (с одной группой сглаживания (smoothing group) или со сглаживанием всех граней), запечь карту нормалей в касательном пространстве Mikk, и это будет выглядеть точно так же, как высокополигональная модель (highpoly), без необходимости устранения ошибок сглаживания или отделения жёстких граней в UV. В будущем я напишу туториал о том, как это делается.
Помните, что это всё равно карта нормалей касательного пространства, но нормали модели вычисляются универсальным способом и модели можно использовать в разных программах.
Двухканальная карта нормалей касательного пространства (2-channel tangent space normal map): оказывается, что при помощи информации, хранящейся в двух из трёх каналов карты нормалей, компьютер может вычислить третий, снизив занимаемый объём памяти ценой увеличения количества вычислений. Так как обычно в большем дефиците находится память, такая оптимизация используется часто и некоторые движки выполняют её автоматически (например, Unreal Engine, когда мы устанавливаем для сжатия нормалей текстуры параметр «normal map»). Освободив один канал карты нормалей, мы можем уменьшить размер текстуры или использовать этот канал для metalness/roughness/opacity…
Обычно устраняют синий канал карты нормалей, поэтому такие текстуры выглядят жёлтыми. Так как эта оптимизация иногда выполняется некоторыми движками автоматически, вы можете замечать такие текстуры в своём проекте.
Карта нормалей мирового пространства (World space normal map): эта карта нормалей вместо того, чтобы модифицировать направление нормалей вершин, полностью их игнорирует и меняет способ отражения света lowpoly-моделью в мировом пространстве (world space) (при запекании она считает, что нормали вершин параллельны осям мира).
Можно сказать, что карта нормалей касательного пространства сообщает модели «ты должна отразить свет вправо», а карта нормалей мирового пространства — «ты должна отразить свет на восток».
Такие карты нормалей более разноцветные и в них больше заметных градиентов; их использовали, потому что в таком случае не нужно думать о нормалях вершин lowpoly, но у них есть недостаток — нельзя двигать модель, потому что она будет выглядеть странно (мы устанавливаем грань так, чтобы она всегда отражала свет на восток. Если повернуть её, то грань продолжит отражать свет на восток.).
Сегодня карты нормалей мирового пространства используются в играх очень редко, но их всё равно можно применять для создания красивых текстур, например, синий канал показывает, как модель должна отражать свет, падающий сверху модели, поэтому можно использовать его, чтобы добавить к текстуре цветное освещение.
Стоит также помнить, что мировые координаты в разных приложениях реализованы по-разному: в Unreal, 3D Studio Max, Blender вверх направлена ось Z, а в Maya, Modo и Cinema4D — ось Y. Это значит, что при переносе между приложениями карты нормалей мирового пространства могут портиться.
Карта нормалей пространства объекта (Object space normal map): это улучшенная версия предыдущего типа карт, и она очень на него похожа. Идея заключается в том, что при перемещении модели в мире её карта нормалей мирового пространства должна переориентироваться относительно объекта.
Это можно описать как «эта грань должна отражать свет вправо от модели». Если поворачивать модель в мире, то карта нормалей должна изменяться в соответствии с этими изменениями. Однако это не работает с деформируемыми мешами, потому что в таких картах учитывается только перемещение объекта. Именно по этой причине сегодня наиболее распространены карты нормалей касательного пространства.
Наклонные карты нормалей (Bent normal maps): по сути, в них сочетается информация AO и карты нормалей, наклоняющая направления нормалей так, чтобы свет стремился отражаться к тем частям модели, на которые попадает свет.
Такие карты используются для улучшения Ambient Oclussion и чтобы избежать эффекта под названием «утечка света» (light leaking), при котором модель может отражать свет теми частями, которых он не может достичь. Лично я никогда ими не пользовался, но исследовал бы их возможности, если бы столкнулся с заметной «утечкой света». Более подробную информацию можно найти здесь, здесь и здесь.
16-битные карты нормалей (16 bit normal maps): иногда, когда на карте нормалей присутствует очень плавный градиент, мы можем замечать появление полос. Эти полосы возникают из-за нехватки цветов для представления плавного градиента, обычно вызванной сжатием текстур.
Узнать больше о 16-битных картах нормалей можно у самого бога туториалов — Earthquake.
Следует также учитывать, что для уменьшения последствий этой проблемы существуют и другие техники, например, полное устранение карт нормалей (для представления этой плавной поверхности используется только геометрия), преобразование lowpoly так, чтобы она была более похожа на highpoly, чтобы градиенты оказались менее заметны, или использование дизеринга.
Так какой же из типов мы должны использовать?
В 90% случаев наилучшим решением являются карты нормалей касательного пространства Mikk. В отличие от вариантов с использованием карт нормалей пространства мира или объекта, модель сможет деформироваться, а направление нормалей останется правильным.
Следует запекать карту нормалей в том же касательном пространстве, что и в программе рендеринга. Наиболее распространённое касательное пространство — это Mikk, так что по возможности используйте его.
Если же на вашей карте нормалей появляется пикселизация, подумайте над использованием 16-карт нормалей или одного из упомянутых выше решений.
По сути, это все типы карт нормалей, которые я смог вспомнить. Если вам известны какие-то другие типы, то сообщите мне о них, и я добавлю их в этот туториал!
Благодарю за прочтение, надеюсь, статья была вам полезна. Спасибо Shnya за комментарии и помощь.
Имитируя объём: как карты нормалей помогают заменить высокополигональные объекты Статьи редакции
Что такое карты нормалей, и как происходит их запекание для низкополигональных моделей.
3D-художник Карлос Лемос опубликовал на сайте 80 LEVEL туториал, в котором подробно рассказал о принципах, на основе которых работают карты нормалей, а также поэтапно описал процесс запекания. А мы выбрали из него ключевую информацию, которая поможет новичкам разобраться в этой теме.
Чтобы понятнее объяснить принципы работы карт нормалей, Лемос обратился к истории 3D-моделирования. Первые 3D-модели выглядели примерно так.
Первое очевидное решение этой проблемы состояло в увеличении количества полигонов — это сделало поверхность более ровной и гладкой.
Но для визуальной гладкости объекта требовалось огромное количество полигонов, что негативно сказывалось на производительности. Поэтому нужно было иное решение. Им как раз и стали карты нормалей.
Принцип работы нормалей проще всего показывать на наглядном примере. Если провести от центра полигона линию, которая будет перпендикулярна его поверхности, то это и будет нормаль. Её цель состоит в том, чтобы контролировать направление поверхности. Когда свет падает на поверхность, используется именно эта нормаль, чтобы правильно рассчитать отражение.
Иными словами, отражение света будет симметричным относительно нормали полигона. Именно так работают отражения в реальном мире.
По умолчанию все полигоны отражают световые лучи перпендикулярно своей поверхности (как в реальности), потому что нормали полигона по умолчанию перпендикулярны поверхности полигона.
Благодаря этому поверхность воспринимается гладкой — результат можно сравнить с моделью, состоящей из огромного количества полигонов. Именно по этому принципу работают группы сглаживания в 3ds Max, Blender и устанавливается рёбра как hard или smooth в Modo, Maya.
Чтобы не получалось таких странных объектов, существует угол сглаживания — если угол, под которым соединяются полигоны, выше угла сглаживания, то переход будет мягким, если ниже, то жёстким.
Тем не менее нормали полигонов используются скорее для нанесения текстур, искривляющих отражение света, а не для сглаживания переходов между полигонами. Для этого в первую очередь используются нормали вершин (вертексные нормали). В основе этого подхода лежит примерно та же идея, но немного более сложная.
Каждая вершина может иметь одну или несколько связанных нормалей. Если у неё есть одна нормаль, то она называется усреднённой нормалью вершины (averaged vertex normal), а если несколько, то разделённой (split vertex normal).
Допустим, есть два полигона, соединённых ребром. Если переход между двумя гранями гладкий, то каждая вершина имеет одну нормаль с усреднённым значением нормалей полигонов.
Если переход жёсткий, то каждая вершина имеет несколько нормалей — так появляется пробел, который визуально разделяет две плоскости. Это и называется разделённой нормалью вершины.
Чтобы воссоздать отражающие свойства высокополигональной модели на низкополигональной модели, как раз и применяются карты нормалей — она запекается в виде текстуры и накладываются на нужный объект. Вся информация о том, как модель должна отражать свет, хранится в текстуре. Это и называется картой нормалей.
Чтобы объяснить принцип запекания карты нормалей, начнём с примера.
Нормали нельзя просто взять и перенести на другой объект, потому что на лоуполи-модели нет нужных полигонов. Чтобы нормали на лоуполи правильно имитировали затенение, им нужно придать такое же направление, как и на хайполи.
Движок использует текстуру для «модификации» низкополигональных моделей, что позволяет им отражать свет так же, как высокополигональным. Но это всего лишь текстура, поэтому она не может повлиять на реальную форму и силуэт объекта.
Стоит помнить, что карты нормалей — это не обычные текстуры: они содержат информацию о нормалях, а не о цвете. Но карту нормалей можно представлять как набор из трёх текстур, содержащихся в одном изображении.
В заключение пройдёмся по ключевым вещам, которые описаны в тексте. Нормали — это векторы, которые используются для определения того, как свет отражается от поверхности. Они могут применяться для управления переходом между гранями: через усреднение нормалей связанных вершин, чтобы сделать плавный переход, или разделение, чтобы сделать жёсткий переход.
Также нормали можно применять для создания низкополигональной модели, которая сможет отражать свет так же, как высокополигональная модель. Эта информация хранится в трёх отдельных каналах изображения, и 3D-редактор считывает её, чтобы понять, в каком направлении должен падать свет.




















