Карта нормалей дота 2 что это
Почему игры используют карты нормалей?
Чтобы хорошо выглядеть, ассеты игр ААА-класса, такие как персонажи, оружие и элементы окружения в значительной степени полагаются на карты нормалей. Но что такое карты нормалей и почему они так широко распространены?
Балансировка между качеством и производительностью
Игры должны работать в режиме реального времени со скоростью 60+ кадров в секунду. Это означает, что высокополигональные модели, обычно используемые для 3D-печати или анимации, не будут хорошо работать в игре, так как они будут значительно замедлять производительность игры.
Для обеспечения плавной работы игры необходимы модели с низким уровнем полигонов.
Но в то же время геймеры ожидают красивые визуальные эффекты с высоким уровнем детализации. Разработчики игр должны иметь возможность использовать большое количество моделей в одной сцене, не говоря уже о различных эффектах освещения и физике.
Итак, как же найти компромисс между высокой производительностью игры и реалистичными визуальными эффектами?
Карты нормалей — лучший компромисс, который обеспечивает высокое качество модели и высокую производительность игры. Секрет в том, что они позволяют нам получить большее количество деталей при использовании меньшего количество полигонов.
Имитация геометрии с помощью текстур
Как это работает? Карты нормалей (Normal maps) и карты смещения (Displacement maps) представляют собой особые виды текстур, которые влияют на то, как ведет себя свет при попадании на поверхность. Они создают иллюзию глубины, сообщая лучу света отскакивать от имитационных особенностей поверхности, даже если на самом деле их там нет.
Это позволяет нам достичь высокого уровня детализации, не обременяя игровой движок сложной геометрией. Звучит слишком хорошо, чтобы быть правдой? Имейте в виду, что есть некоторые ограничения для данной техники.
Карты нормалей VS карты высот
В то время как карты нормалей и карты высот дают нашим низкополигональным моделям вид более детализированных, они используются для совершенно разных целей.
Наиболее очевидное различие заключается в том, что карты высот создаются лишь в оттенках серого, потому что они отображают только разницу высот. Черный (0) — «вниз», белый (1) — «вверх», а 0.5 означает отсутствие изменения высоты.
Существует несколько различных типов карт высот, с которыми вы, возможно, уже знакомы.
Bump maps — это способ старой школы для добавления деталей к низкополигональным объектам. Они используются так же, как и обычные карты, за исключением того, что они содержат только информацию о высоте, а не информацию об угле.
Displacement maps иногда используются для изменения местоположения фактических вершин объекта. Такое перемещение не добавляет никаких дополнительных деталей. Вместо этого оно используется для создания более сложных объектов. Часто подобным способом генерируется рельеф мира с использованием карт смещения.
Еще карты смещения используются для отображения параллакса (так называемое виртуальное отображение смещения), что является более сложной техникой, в которой игровой движок пытается смещать координаты текстуры относительно камеры. Это довольно ресурсозатратно, но может давать хорошие результаты.
Normal Maps не содержат информации о высоте. Вместо этого они содержат информацию о углах. Они цветные, потому что значения RGB сообщают рендеру, в каком направлении идет наклон, и насколько он крут.
Наиболее важным преимуществом этого является то, что мы можем использовать информацию об угле для того, чтобы искусственно сгибать края соседних граней друг к другу, тем самым имитируя эффект фаски. Это невозможно сделать только с информацией о высоте, потому что рендер не может знать, в каком направлении должны быть согнуты края.
Смягчение острых краев звучит достаточно просто, но это дает удивительно большой скачок визуального качества. Все потому, что в реальной жизни ничто не имеет абсолютно острых краев (кроме, разве что, графена). С другой стороны, в компьютерной графике все имеет бесконечно острый край, поскольку каждая грань имеет нулевую толщину.
Вы вряд ли заметите фактическую толщину края в игре, но вы можете заметить тот факт, что, по крайней мере, некоторое количество света должно находится на этих областях.
Помимо того, что свет на углах выглядит более естественным, этот блеск помогает передать форму объекта, особенно если смотреть на него с расстояния. Так как многие игровые объекты отображаются на экране довольно мелкими, художники часто преувеличивают углы объектов, чтобы помочь игроку увидеть все четко или подчеркнуть важные объекты.
3 типа карт нормалей
Существует три типа карт нормалей, которые дают идентичный результат, но вычисляются немного по-разному.
Tangent space (касательное пространство)
Как следует из названия, карты нормалей касательного пространства основаны на касательном направлении каждой грани. Эти карты всегда состоят из комбинации трех цветов.
- Синий показывает наклон в направлении нормали
- Красный показывает наклон влево и вправо в направлении касательной
- Зеленый показывает наклон вверх и вниз в направлении касательной. OpenGL карты нормалей отображают зеленым цветом наклон вверх, в то время как DirectX наклон вниз.
Object space (объектное пространство)
Карты нормалей пространства объектов основаны на всем объекте, а не на его индивидуальных гранях. Такие карты немного быстрее вычисляются графическими картами, но у них есть некоторые недостатки.
Поскольку правая сторона будет другого цвета, нежели левая, никакие UV-карты не могут быть отзеркалены, а это означает, что большое количество текстурного пространства будет потрачено впустую на симметричных моделях. Это также означает, что если объект скручивается, то мы увидим инвертированное затенение.
World space (мировое пространство)
Карты нормалей в пространстве мира являются наименее гибкими. Поскольку они основаны на глобальных координатах, объект вообще не может вращаться, чтобы сохранить корректность затенения. Этот тип карт нормалей используется только для больших, статических и асимметричных объектов, таких как окружение игрового мира, или временно используется в таких программах, как Substance Painter, в качестве средства вычисления различных погодных эффектов и не только.
Заключение
Наиболее распространенным типом карт нормалей являются карты касательного пространства, поскольку они наиболее гибки. Но полезно понимать и другие типы, чтобы вы могли использовать их, если это будет необходимо. Для углубленного изучения карт нормалей и того, как моделировать объекты с их использованием и запекать данные карты, посмотрите курс «Введение в моделирование с использованием карт нормалей».
Кузница полигонов: создание карт нормалей
Всего пару лет назад технология карт нормалей была настоящей революцией. Именно благодаря ей стало возможным изображать в играх низкополигональные модели так, как будто они высокополигональные. За примерами далеко ходить не надо, достаточно вспомнить Far Cry и DOOM 3.
Сегодня с картами нормалей работает большинство моделлеров по всему миру. И будут работать еще ой как долго. Пора и нам детально изучить, что же это за зверь такой и как к нему подступиться. Обратите внимание, что материал рассчитан на более-менее подкованного в вопросе трехмерного моделирования пользователя. Если же вы только начинаете увлекательное погружение в мир 3D, то специально для вас мы приготовили сюрприз. На нашем диске находится полуторачасовой видеоурок, наглядно иллюстрирующий данную статью. Все упоминающиеся в статье файлы можно взять с нашего DVD (в разделе «Игрострой»).
Базовые принципы
Рис. 1. Три стадии разработки.
Суть технологии заключается в генерации для низкополигональной модели такой текстуры, которая, будучи наложенной по специальному алгоритму, в точности имитирует высокополигональную сетку. То есть модель всего в несколько тысяч полигонов смотрится так, как будто она составлена из десятков и даже сотен тысяч треугольников.
Генерируемая для этой цели текстура называется картой нормалей: она содержит в себе информацию о разнице между низкополигональной моделью и высокополигональной (принято говорить просто «разница», без упоминания между чем и чем). Главная проблема при создании карты нормалей — правильно посчитать эту разницу.
Разница хранится в трех цветовых составляющих изображения (красной, зеленой и голубой). Цвет каждого пикселя кодирует информацию о том, в какую сторону была ориентирована нормаль детальной модели по отношению к нормали вершины низкополигональной модели в данной точке развертки. Красная и зеленая компоненты определяют отклонение нормали вправо/влево и вверх/вниз соответственно. Голубая цветовая составляющая, по сути, является обычной картой рельефа (bump map).
Точка отсчета
Рис. 3. Сглаживание с выделением контура.
Из программного обеспечения нам потребуются 3DS Max 7 (или выше) и ZBrush 2. На этот раз мы не будем заострять внимание на процессе моделирования: почти все действия по моделированию в 3DS Max можно детально изучить на нашем диске в видеоуроке. Этап моделирования в ZBrush записан в виде скрипта, его тоже смотрите на диске.
Работа начинается с. концептуального рисунка. Берем в руки карандаш и рисуем эскиз того предмета, который будем моделировать. Нам нужен точный шаблон. Я, например, пофантазировав полчаса, придумал концепцию фэнтезийного клинка «Коготь грифона» (рис. 1, эскиз или файл Gryphon’s_Blade_Sketch.bmp). Поэтому в статье мы будем работать именно с этой моделью.
После непродолжительного колдовства с полигонами (см. видеоурок) получается модель как в файле Gryphon’s_Blade_LOW_Complete.max. Именно для нее нам предстоит сделать сначала высокодетализированный аналог, а затем и карту нормалей.
Подготовка модели к детализации
Для тех, кто создавал свою модель с нуля, хочу заметить, что вся работа ведется не с сеточным объектом (Editable Mesh), а полигонным (Editable Poly). Игровые движки разницу между ними не различают, отличие проявляется именно при подготовке высокополигональной модельки.
Рис. 2. Сглаживание «в лоб».
С чего же начать? Просто добавить в стек модификатор MeshSmooth? Оказывается, не все так просто с этими полигонами. На рис. 2 наглядно продемонстрировано, что будет, если кубик просто сгладить: все нужные контуры потеряются. Другой минус сглаживания «в лоб» в том, что обработанная модель будет находиться внутри низкополигональной (ведь при сглаживании ребра и вершины этой модели являются контрольными узлами сглаженного каркаса — значит, всегда будут находиться вне его), а нам это не подходит, потому что детализированная модель должна быть на одном уровне с упрощенной.
Однако решение у данной проблемы все-таки есть: если нам надо, чтобы некоторые контуры сохранили свою «резкость», то ребра и вершины, образующие эти контуры, следует размножить — например, удвоить командой Chamfer (Фаска) из свитков Edit Edges/Edit Vertices. При сглаживании в местах разделения появятся четко различимые особенности контуров (рис. 3). Используя этот прием, доводим сетку до состояния, когда сглаженный вариант соответствует низкополигональному (рис. 4).
Стоит отметить, что при создании каркаса для сглаживания можно использовать такой нехитрый алгоритм: создаем дубликат low-poly, применяем к нему модификатор Push так, чтобы «раздутый» каркас немного покрывал собой исходный. После этого устанавливаем требуемый уровень сглаживания в свитке Subdivision Surface (отмечаем галочку Use NURMS Subdivision). Теперь модифицируем ребра и вершины (там, где это требуется), параллельно наблюдая за качеством сглаженного каркаса. Все время нужно следить, чтобы полигоны не становились иной формы (только треугольной или четырехугольной). Пятиугольные полигоны, в принципе, допустимы, но следует учитывать, что могут возникнуть проблемы: алгоритм сглаживания начинает такие полигоны доводить до треугольных и четырехугольных, но делает это далеко не лучшим образом.
Поэтому единственный критерий правильности в нашем случае — сглаженная сетка модифицированной low-poly должна быть без артефактов и совпадать с исходной низкополигональной моделью либо покрывать ее. Результат можно посмотреть в файле Gryphon’s_Blade_LOW2+Subdiv_Complete.max.
Рис. 4. Низкополигональная модель и ее сглаженный аналог.
Проработка детальной модели
Мы подошли к самому интересному этапу работы — созданию детальной модели в ZBrush. Для того чтобы начать работу, экспортируем подготовленную сглаженную модель в формат OBJ. Опции экспорта настраиваем так: снимаем галочки в группе File, а в комбинированном списке Faces выбираем пункт Polygons, после чего кликаем ОК. В среде ZBrush выполняем команду Tool/Load Tool, в открывшемся диалоге находим экспортированный файл. Сохраняем появившийся в меню новый инструмент как ZTL-файл.
Чтобы посмотреть урок моделирования деталей «Когтя грифона», идем в меню ZScript, кликаем на ¬es, жмем Load и выбираем файл Blade_Hi_Detail_Modelling.zsc. В левом нижнем углу экрана появится маленькая кнопочка Play. Нажимаем ее (нам предложат перезапустить среду — соглашаемся), после чего курсор сам переместится на меню загрузки требуемого инструмента. В открывшемся диалоговом окне выбираем файл Blade_Hi_Start.ZTL. Курсор сам начнет «танцы» по интерфейсу ZBrush, а нам остается только наблюдать за этим и внимательно читать всплывающие подсказки (рис. 5). С помощью этого урока разобраться с моделированием в ZBrush не составит труда.
Когда модель готова, командой Tools/Export переводим каркас обратно в OBJ-файл, который впоследствии импортируем в 3DS Max (в ту же самую сцену, где находится low-poly). Высокополигональную модель можно посмотреть в файле Gryphon’s_Blade_High_Complete.max.
Для новичков данная статья довольно сложна. Поэтому на нашем диске (в разделе «Игрострой») можно найти статьи цикла «Игромодельер», которые помогут разобраться в процессе моделирования и текстурирования. В них детально рассматривается проблема создания развертки, дается ряд советов по рисованию текстур послойно в Photoshop и Painter, а также в пакете Deep Paint 3D.
Вычисление карты нормалей
В идеале полигонные каркасы должны быть одинаково ориентированы и находиться на одном и том же месте. Если по каким-либо причинам этого не произошло, придется подогнать их положение вручную. Поскольку детальная модель может быть чрезвычайно сложной, имеет смысл использовать упрощенное ее представление — в виде бокса (опция Display As Box в свойствах объекта).
Рис. 5. Подсказки в ZBrush 2.
Низкополигональная модель лишена развертки, поэтому при помощи модификатора UVW Unwrap добавляем для упрощенной модели текстурные координаты. В нашем случае имеет смысл делать развертку как показано на рис. 6.1.
Пора приступать к нормал-мэппингу. Выбираем на сцене нашу лоуполи-модель и выполняем команду Rendering/Render To Texture, она запускает движок так называемого текстурного «запекания», с помощью которого можно проецировать на текстуру низкополигональной модели не только нормали, но также цвет, тени и многое другое.
Первый свиток, опции которого нас интересуют, — Objects to Bake (объекты для «запекания»). В группе Projection Mapping (проецирование карт) отмечаем галочкой пункт Enabled и снимаем пометку со ставшего активным пункта Sub-Object Levels. Также выбираем в списке рядом пункт Projection Modifier (проекционный модификатор). Жмем Pick и в диалоговом окне выбираем высокополигональную модель. Поскольку развертку для лоуполи мы сделали сами, кликаем флажок Use Existing Channel (использовать существующий канал мэппинга) в группе Mapping Coordinates.
Следующий необходимый нам свиток — Output. Здесь мы добавляем те текстурные карты, которые нас интересуют. Пока нам требуется только NormalsMap, который выбираем из соответствующего списка (предварительно необходимо нажать кнопку Add). В строке File Name and Type устанавливаем имя и тип результирующего файла карты, после этого указываем размер создаваемой текстуры. Чем больше, тем лучше — в идеале 2048. Теперь щелкаем Render, после чего запустится процесс рендеринга текстуры, но на экране будет отображена только проекция полной визуальной карты высокополигональной модели. На этой карте, скорее всего, будут присутствовать некоторые участки, закрашенные красным цветом. Давайте разберемся, что это значит.
Рис. 6. Некоторые этапы создания текстур.
Переключаемся на стек модификаторов лоуполи-модели. Оказывается, в его вершину добавилась новая строка — Projection. Этот модификатор является вспомогательным при проецировании с одной модели на другую и служит для создания так называемой клетки (Cage). Клетка является копией исходного низкополигонального каркаса, но модифицирована она так, что внутри нее полностью помещается высокополигональная модель. Так вот, красными пятнами на текстуре «Макс» помечает те части, где детальная модель вылезла за клетку: произошло это из-за того, что генерировать идеальную клетку «Макс» пока не умеет (да и не скоро еще научится). Поэтому опять придется поработать вручную. Действуем по следующему алгоритму:
1. Сохраненную в файл карту нормалей загружаем в слот Diffuse пустого материала, включаем отображение текстуры во вьюпорте и назначаем этот материал нашей упрощенной модели. Карта нормалей будет наглядно (цветом) отображена в видовых окнах «Макса».
2. У проекционного модификатора выбираем уровень редактирования Cage и в одноименном свитке жмем кнопку Reset. Это восстановит изначальную форму клетки. Теперь, увеличивая значение Amount в группе Push, придаем такую форму клетке, чтобы она равномерно покрывала высокополигональную модель. После этого, перемещая вершины клетки, максимально улучшаем степень покрытия.
3. Рендерим текстуру.
Все эти шаги повторяем до тех пор, пока красные участки с текстуры либо не исчезнут, либо не окажутся в незаметных местах (закрытые сгибы, складки). Пример удачно сгенерированной карты нормалей показан на рис. 6.2.
Самая сложная часть работы позади, нам осталось только доработать детали и проверить модель в деле.
Рис. 7. Сравнение сложности каркасов моделей.
Финальные штрихи
Использовать карту нормалей можно двумя способами. Первый способ заключается в том, чтобы в слот Bump пустого материала положить Normal Bump, а в него уже загрузить текстуру. После применения этого материала к низкополигональной сетке результат будет виден во время рендеринга модели. Второй способ, наоборот, позволяет видеть результат только во вьюпорте. Для этого у материала в свитке DirectX Manager выбираем пункт Metal Bump9 и отмечаем галкой Enable Plugin Material. Теперь в появившемся свитке DirectX Shader — Metal Bump 9 присоединяем карту нормалей в пункте Normal.
Добавим красок. В отличие от традиционного процесса создания текстур, рисование карты цвета с использованием Normal Map упрощается: ведь нам уже не требуется прорисовывать тени и блики. Поэтому, используя либо экспортированную Texporter развертку, либо непосредственно карту нормалей, в Photoshop наносим только фактуру кожи, цвет металла и деталей.
Если результат вас устраивает, то работу можно заканчивать. Если же нет, то незамедлительно прочитайте текстовый блок «Трехмерная грязь» — там детально разобрано, как ул учшить качество текстуры.
Когда у вас есть не только low-poly, но и высокополигональная модель, рисовать на текстуре элементы механического износа и загрязнения не обязательно, потому что для этого существует маленький, но чрезвычайно полезный 3DS Max-плагин под названием Quick Dirt 1.5.
Используется он так: применяем модификатор QuickDirt к детальной модели и указываем тип загрязнения — Dents в свитке General Parameters. Во вьюпорте мы наглядно увидим области механического износа на детальной модели (рис. 1, HighPoly).
К детальной модели применяем материал QuickDirt, который можно найти в списке стандартных материалов. Чтобы поместить все детали текстуры для лоуполи, в списке элементов для «запекания» (Render To Texture) добавим Blend, в опциях которого отключены все пункты, кроме Diffuse. Сохраняем новую текстуру в файл (рис. 6.3). Теперь если в «Фотошопе» ее наложить на карту цвета в режиме Multiply, немного подчистить и поиграть с настройками прозрачности, то текстура цвета для низкополигональной модели принимает вид как на рис. 6.4 (см. также Gryphon’s_Blade_Diffuse.bmp на диске).
Упрощенная модель с улучшенной текстурой смотрится намного реалистичнее и качественнее (рис. 1).
Полученную модель можно перенести в любую игру. Но итог нашей работы — это не только красивая моделька. Мы перешагнули барьер, отделявший профессионального разработчика игр от модмейкера. Теперь вы можете самостоятельно создавать профессиональные модели не только для уже существующих, но и для своих собственных игр.
В завершение обратите внимание на рис. 7 — насколько «тяжелой» выглядит многополигонная модель по сравнению с low-poly.
Это норма: что такое карты нормалей и как они работают
На протяжении нескольких лет я пытался разобраться в картах нормалей и в проблемах, которые обычно возникают при работе с ними.
Большинство найденных объяснений было слишком техническим, неполным или чересчур сложным для моего понимания, поэтому я решил попробовать объяснить собранную мной информацию. Я понимаю, что эти объяснения могут быть неполными или не совсем точными, но всё равно попробую.
Первые созданные человеком 3D-модели выглядели примерно так:
Это замечательно, но у такой модели есть очевидное ограничение: она выглядит слишком полигональной.
Наиболее очевидное решение: добавить больше полигонов, сделав поверхность более равномерной и гладкой, вплоть до того, чтобы полигоны казались единой гладкой поверхностью. Но оказывается, для того, чтобы сделать поверхности наподобие сфер гладкими, нужно огромное количество полигонов (особенно сегодня).
Требовалось другое решение, и так были изобретены нормали. (Всё происходило не совсем так, но так проще объяснять и понимать.)
Давайте проследим за линией из центра полигона, перпендикулярной его поверхности. Мы дадим этой линии очень непривычное название: нормаль. Цель нормали — контролировать, куда указывает поверхность, чтобы когда свет отразиться от этой поверхности, она могла использовать нормаль для вычисления получившегося отражения. Когда свет падает на полигон, мы сравниваем угол луча света с нормалью полигона. Луч отражается под тем же углом относительно направления нормали:
Другими словами, отражение света будет симметрично относительно нормали полигона. Именно так работает большинство отражений в реальном мире. По умолчанию лучи света отражаются от всех полигонов совершенно перпендикулярно к их поверхности (как должны это делать в реальной жизни), потому что нормали полигона по умолчанию перпендикулярны к поверхности полигона. Если в нормалях будут пробелы, то мы увидим их как отдельные поверхности, поскольку свет отразится в одном или другом направлении.
Если две грани соединены, то мы можем попросить компьютер сгладить переход между нормалью одного полигона к другому, чтобы нормали постепенно выстраивались в соответствии с ближайшей нормалью полигона. Таким образом, когда свет попадёт ровно в центр одного полигона, то он отразится прямо, в соответствии с направлением нормали. Но между полигонами это направление нормали сглаживается, изменяя отражение света.
Мы будем воспринимать переход как единую поверхность, потому что свет будет отражаться между одним и другим полигоном плавным образом, и между ними не будет пробелов. По сути, свет отражается от этих полигонов плавно, как будто у нас имеется множество полигонов.
Именно этим мы управляем, задавая smoothing groups (3ds Max, Blender) или указывая рёбра как hard или smooth (Modo, Maya): мы сообщаем программе, какие переходы между гранями должны быть плавными, а какие — жёсткими.
Вот сравнение одной сферы из 288 полигонов с жёсткими и плавными переходами:
Потенциально мы можем задать нечто вроде параллелепипеда, чтобы все его вершины имели усреднённые нормали. 3D-редактор будет стремиться сгладить его поверхность, чтобы она выглядела как единая плавная поверхность. Для 3D-редактора это вполне логично, но выглядит очень странно, потому что у нас есть объект, который очевидно должен иметь несколько отдельных поверхностей (каждая грань параллелепипеда), однако программа пытается показать их как одну плавную поверхность.
Именно поэтому в 3D-редакторах обычно есть параметр углов сглаживания: если у нас есть два связанных полигона под углом, превышающем угол сглаживания, то их переход будет плавным, а соединение полигонов под углом меньше угла сглаживания будет жёстким. Благодаря этому крутые углы между поверхностями будут отображаться как разные поверхности, как это и бывает в реальном мире.
Итак, мы использовали нормали для контроля над переходами между гранями модели, но можно пойти ещё дальше.
Так как мы меняем способ отражения света от объекта, можно также сделать так, чтобы очень простой объект отражал свет, как сложный. Это называется картой нормалей. Мы используем текстуру для изменения направления света, отражающегося от 3D-объекта, заставляя его выглядеть сложнее, чем он есть на самом деле.
Примером из реального мира могут служить голограммы, которые раньше вручали в подарок при покупке картофельных чипсов (по крайней мере, у нас, в Испании). Они совершенно плоские, но отражают свет так, как бы это делал 3D-объект, благодаря чему становятся сложнее, чем на самом деле. В мире 3D-графики это работает даже лучше, но всё равно имеет свои ограничения (поскольку поверхность остаётся плоской).
Хоть мы и применяем нормали полигонов для реализации какой-то чёрной магии, на самом деле мы не контролируем сглаживание поверхности модели при помощи нормалей полигонов. Мы используем нормали вершин для контроля сглаживания нормалей. По сути, идея та же, но немного более сложная.
С каждой вершиной может быть связано одна или несколько нормалей. Если она имеет одну нормаль, то можно назвать её усреднённой нормалью вершины, а если несколько — то разделённой нормалью вершины.
Давайте возьмём два полигона, соединённых ребром. Если переход между двумя гранями плавный (если мы указали его как плавный в Maya/Modo, или обе имеют одинаковую smoothing group в Max/Blender), то каждая вершина имеет одну нормаль, которая является средней нормалей полигонов (поэтому она и называется усреднённой нормалью вершины). Важное примечание: до недавнего времени каждый 3D-редактор использовал собственный способ вычисления усреднённых нормалей вершин, то есть карты нормалей, вычисленные в одной программе, в другой могли выглядеть совершенно иначе. Подробнее об этом я расскажу во второй части туториала.
Если переход жёсткий (hard edge или разные smoothing groups), то каждая вершина имеет несколько нормалей: по одной для каждой соединённой вершины, выровненной по их нормалям. При этом между нормалями образуется пробел, который выглядит как две разные поверхности. Именно это называется разделённой нормалью вершины.
Как вы могли догадаться, контроль нормалей вершин очень важен, если мы хотим контролировать карты нормалей. К счастью, нам не обязательно изменять нормали напрямую или даже видеть их, но понимание того, как это работает, поможет вам понять, почему мы выполняем работу именно так и больше разбираться в проблемах, с которыми мы можем встретиться.
При запекании карты нормалей мы по сути говорим программе изменить направление, которому следуют нормали lowpoly-модели, так, чтобы они соответствовали направлению в highpoly-модели; поэтому lowpoly-модель будет отражать свет так же, как highpoly. Вся эта информация хранится в текстуре под названием «карта нормалей». Давайте рассмотрим пример.
Допустим, у нас есть вот такая низкополигональная модель (lowpoly). Плоская поверхность с четырьмя вершинами и настроенными UV, которые программа запекания будет использовать для создания карты нормалей.
И она должна получить информацию о нормалях от этой высокополигональной (highpoly) модели, нормали которой сложнее.
Помните, что мы переносим только информацию о нормалях, то есть UV, материал, топология, преобразования и т.п. к делу не относятся. Проверенное правило: если highpoly-модель выглядит хорошо, то её нормали тоже хороши и вполне должны подходить для запекания.
Программа запекания берёт lowpoly-модель и испускает лучи, следуя по направлениям нормалей lowpoly (именно поэтому нам нужно контролировать нормали lowpoly). Эти лучи имеют ограниченную длину чтобы не получать информацию нормалей от далёких граней (обычно это расстояние называется bake distance или cage distance). Когда эти лучи сталкиваются с highpoly, программа запекания вычисляет, как отразить эти лучи, чтобы они следовали по направлению нормалей highpoly, и сохраняет эту информацию в карту нормалей.
Вот результат запекания для нашего примера:
У нас есть текстура, которую движок использует для изменения нормалей lowpoly, чтобы свет отражался от этой lowpoly-модели так же, как он отражался бы от highpoly-версии. Не забывайте, что это только текстура, которая не влияет на силуэт lowpoly-модели (невозможно изменить способ отражения света от модели, если свет не падает на эту модель).
Хотя понятно, что можно «считать» внешний вид highpoly по внешнему виду карты нормалей, очевидно, что карты нормалей — это не обычные текстуры, потому что они хранят информацию не о цвете, а о нормалях. Также это значит, что карты нормалей нельзя рассматривать как обычные текстуры; к тому же, как мы увидим, они обладают особыми параметрами сжатия и гамма-коррекции.
Можно воспринимать карту нормалей как набор из трёх текстур в оттенках серого, хранящийся в одном изображении:
Первое изображение сообщает движку, как эта модель должна отражать свет, падающий справа; оно хранится в красном канале текстуры карты нормалей.
Второе изображение сообщает движку, как модель должна отражать свет, падающий снизу*; оно хранится в зелёном канале текстуры карты нормалей.
*В некоторых программах свет падает не снизу, а сверху, то есть могут быть «левосторонние» и «правосторонние» карты нормалей. Как мы увидим позже, это может вызывать некоторые проблемы.
Третье изображение сообщает движку, как модель должна отражать свет, падающий спереди; оно хранится в синем канале текстуры карты нормалей. Так как большинство объектов при освещении спереди выглядят белыми, карты нормалей обычно кажутся синеватыми.
Когда мы комбинируем все три изображения в одно, то получаем карту нормалей. Помните, что это объяснение не полностью корректно, но надеюсь, что оно позволит вам понять информацию, хранящуюся внутри карты нормалей, и лучше разобраться, что она делает.
Нормали — это векторы, которые используются для определения того, как свет отражается от поверхности. Их можно использовать для контроля над переходом между гранями (усреднением нормалей соединённых вершин для создания плавного перехода или разделением их для создания жёсткого перехода), но также их направление можно изменять, чтобы lowpoly-модель отражала свет так же, как более сложная модель.
Эта информация хранится в трёх отдельных каналах изображения, и 3D-редактор считывает её, чтобы понять, в каком направлении должна смотреть поверхность модели.
В следующей статье цикла мы поговорим о том, как можно запекать эти детали из highpoly-модели в lowpoly.
поясняю разницу: BUMP, NORMAL, HEIGHT, DISPLACEMENT Mapping
Тут была тема аналогочная, почитав ее, чтоб народ не путался, я хотел разъяснить что такое бамп маппинг, но пока минут 10 писал, тему удалили вроде 🙂 мне обидно стало вот я новую и начал. На нее можно не отвечать, это я так для общего образования пишу, без подробностей.
:-> 8) 🙂 8-> 🙂 так! подведем итог. Если серьезно:
1. Есть просто текстурирование, когда текстура накладывается на полигон (пусть это будет квадрат) равномерно освещенная.
2. Bump Mapping. Насколько я понимаю, этот термин большинство истолковывает как рельефное текстурирование. _Если я не ошибаюсь_, это было впервые во времена видях типа G400 или G200, Matrox тогда этим хвалилась очень. Рельефное – это значит текстура накладывается на плоский полигон, плюс используется дополнительная BumpMap-текстура, которая хранит информацию о высоте каждого пикселя. Таким образом при рендеринге видяхой в 3D-режиме (в игрушке, например) мы видим не плоский полигон, а полигон с наличием некоторого рельефа. Поясню если этот полигон освещается слева, а в BumpMap записано что посередине квадрата небольшая горка должна быть, то мы увидим что она как бы на самом деле есть, т.е. увидим тень справа от горки и более ярко освещенный склон слева этой горки. Хочу обратить внимание что это все будет изображено на плоском полигоне (имитировано)
Чтобы задать все эти выпуклости и впуклости, надо где-то хранить о них информацию. Способы хранения информации о рельефе:
1. Карта высот (HeightMap). В большинстве случаев серая текстура. Ну тут все просто, чем выше точка тем светлее она на на карте высот.
2. Карта нормалей (NormalMap). Тут уже хитрее. Текстура (карта нормалей) содержит не высоту, а вектор нормали вооброжаемой поверхности в данной точке (нормаль это вектор перпендикулярный поверхности). То есть в случае, если мы хотим изобразить горку посередине нашего плоского, квадратного полигона, то на карте нормалей на левом склоне горки вектор нормали будет наклонен чуть налево, на правом склоне соответственно направо. Технически в текстуре вектор нормали представляется с помощью 3-х значений (цветов), но это уже мне лень расписывать. В отличии от HeightMap, текстура NormalMap содержит три цвета на точку, поэтому она сиреневая 🙂 а не grayscale.
При прорисовке (рендеринге) рельефного полиона движок игры (или 3D редактор), накладывает обычную текстуру с учетом рельефа, который берет из либо NormalMap, либо HeightMap. И мы видим что реально плоский польгон выглядит рельефным.
3. Существует более прогрессивный способ задания рельефа, так называемая Displacement Map (карта смещений). В принципе она тоже вся серая и выглядит почти как карта высот. Принципиальное отличие заключается происходит на этапе подготовки модели для вывода на экран. Если выводим таким способом наш квадратный полигон с горкой по середине, DirectX подменит плоский полигон наполигон с _реальной_ горкой посередине этого квадрата. То есть он сам автоматом добавит полигоны там где задана горка (а она задана в Displacement Map). Еще раз отмечу, что в отличии от Normal и Height, этот способ реально создает рельеф на заданном полигоне (искривляет полигон). Естественно он самый качественный и тормозной, кол-во полигонов-то увеличивается. И вообще на сегодняшний день практичнее использовать NormalMap.
.. вроде все. Могу запостить несколько картинок для большей понятливости, так сказать на пальцах показать. Но вообще-то в инете подробной инфы достаточно. Шоб до завтра заучили! 🙂 Хотя я вижу некоторые это более-менее уже знают и понимают.
Вот небольшой пример из 3DStudio Max7 Tutorials, одна пешка содержит полигонов в 10 раз меньше чем другая :), а разницы при рендеринге почти нет. Все из-за правильного применения NormalMap.
Краткий экскурс в мир альфа-каналов и карт нормалей
Koxae
Локализатор
–>
Статус: Offline
Автор статьи: Koxae
Добавлено: 3 Январь 2012
Просмотров: 15285 | Комментарии: 17
Альфа-канал играет немаловажную роль при создании текстур. В нём используются только градации серого. Запомнить как он работает очень просто: белый – да, чёрный – нет, серый – так себе, в зависимости от светлости. Найти его можно, разумеется, в свитке каналов – Channels. Вот он, как раз, в самом низу, так и называется Alpha 1
Больше одного альфа-канала для игровых текстур оставлять не нужно.
Для диффузной карты альфа-канал используется только в том случае, если мы хотим сделать часть текстуры прозрачной. В этом случае чёрным закрашиваем то, что хотим отрезать, серым – что будет полупрозрачным (редко используется), белым – всё остальное.
Что касается карты свечения – glow map (маркер _g в конце имени файла) и карты глянца – environment mask (маркер _m в конце имени файла), то им альфа-канал не нужен вообще, они сами себе являются альфа-каналом. Тут тот же принцип: белый светится или отражает, чёрный – нет. Для карты свечения возможно использование цветов, но существует масса нюансов, поэтому опустим.
И, наконец, карта нормалей – normal map, в подавляющем большинстве, просто обязана иметь грамотный альфа-канал, в противном случае, модель будет выглядеть как маслом намазанная. Белый альфа-канал есть смысл оставить только для драгоценных камней, чистого нового стекла и жидкостей. Всё остальное приглушаем. Обычная ткань и неполированное дерево – почти чёрный цвет альфа-канала.
Ну, вот мы и подобрались к самому интересному
Карта нормалей
Сделать сиё чудо можно несколькими способами. Некоторые требуют хорошего навыка моделирования 3х-мерных объектов и нам сейчас не подходят. К счастью, есть плагин от славных людей из NVidia для создания карт нормалей из любого изображения. Есть ещё потрясающая программа
Применим к текстуре NormalMapFilter (Filter -> NVIDIA Tools -> NormalMapFilter):
В разделе Height Generation настраивается общее отображение будущей карты нормалей.
Пункт Wrap для безшовных текстур лучше выключить, иначе появятся швы на стыках, для одиночных текстур – всё равно. Все 3 пункта Invert делают то, что и написано, но мне ни разу не понадобились, поэтому я ничего не буду писать про них.
Путём выбора значения sample в подразделе Filter Type выбирается, собственно, детализация.
Как видите, самый чёткий результат мы получаем устанавливая значение sample 4.
В поле Scale настраивается высота рельефа. Для сравнения:
Главный недостаток NormalMapFilter в том, что он не умеет различать мелкие и крупные детали текстуры. Поэтому мы можем получить либо детализированную карту с небольшим рельефом, либо высокий рельеф без мелких деталей.
Выходов из этой ситуации несколько.
1. Отредактировать непосредственно изображение, сделав максимально контрастными крупные детали и минимально контрастными мелкие. Иногда этого не избежать, но для не очень сложных текстур есть ещё пара хитростей.
Приведу пример на сделанной на коленке простой текстуре:
Попробуем применить к ней NormalMapFilter со значениями 4 samples и 30 scale (я хочу получить достаточный контраст):
И уже видны косяки – чересчур рельефное дерево при недостаточном рельефе борозд и кнопки. К тому же, кнопка обрела на своей поверхности абсолютно ненужные детали. Единственный путь к вменяемой карте нормалей для этой текстуры я вижу в редактировании изображения. Я перевела все элементы текстуры в градации серого, изменила их контрастность и яркость и добавила тёмные ореолы кнопке и бороздам, в первом случае – кнопка слегка утоплена, во втором – смягчаю контур борозд:
Применила фильтр с теми же самыми настройками:
Уже больше похоже на правду.
2. Второй способ я подсмотрела на сайте render.ru, идея принадлежит Евгению Булатову. Возвращаемся к нашей подопытной текстуре брусчатке, переводим изображение в 16 Bits/Chanel (меню Image –> Mode), обесцвечиваем Ctri+Shift+U и применяем NormalMapFilter с настройками: 4 sample, scale 5, Average RGB.
Затем, дублируем слой, применяем фильтр Blur -> Gaussian Blur с небольшим значением (я выбрала 2) и назначаем слою тип смешивания Overlay. Повторяем процедуру: дублируем дублированный слой (тот, который уже размыт), Gaussian Blur (можно нажать Ctrl+F и последний фильтр применится сам с последними настройками); дублируем, размываем и так много раз. Вот что у меня получилось при 10и дублированных слоях:
И мелкие детали видны и рельеф на месте. Осталось завершить процесс. Объединяем все слои в один, применяем NormalMapFilter изменив Average RGB на Normalize Only и переводим изображение в 8 Bits/Chanel:
3. Дублируем слой Background с текстурой, на слой Background применяем NormalMapFilter со значениями: 9х9 samples, 20 scale, Average RGB ( *1 ). Затем, на сдублированный слой применяем тот же NormalMapFilter, но со значениями: 4 samples, 3 scale, Average RGB, дублируем его ( *2 ), сливаем все слои и применяем NormalMapFilter изменив Average RGB на Normalize Only ( *3 ).
Осталось сделать адекватный альфа-канал и карту нормалей можно считать готовой к употреблению.
Все изменения карты Доты в 7.29. Перемешали лагеря нейтралов, посадили деревья у Т2
Очень много картинок.
9 апреля в Доте вышел долгожданный патч 7.29, в котором Valve не только изменила параметры кучи героев и предметов, но и ОЧЕНЬ сильно поменяла карту. Мы же собрали все изменения ландшафта в этом посте.
А весь текст патча вы можете прочитать тут:
Патч 7.29 в Dota 2 вышел!
Половина Radiant
Треугольник
Было:
Стало:
Что изменили? Гору для Обса, что стояла у потайной лавки, передвинули ближе к треугольнику. С треугольника к центру проложили небольшую тропинку, начинающуюся от лагеря нейтралов рядом с рекой, что создало еще один путь для атаки Т1 в центре.
Маленький лес
Было:
Стало:
Что изменили? Примерно все. Передвинули оба лагеря нейтралов, а за легким еще и небольшую дорожку сделали. Теперь средний лагерь почти автоматически уходит Dire, им его просто проще контролировать. Также убрали небольшой лес, располагавшийся ближе к Т1 в легкой Radiant, его передвинули на бывшее место среднего лагеря.
Большой лес
Было:
Стало:
Что изменили? Главное – переместили аванпост в центр леса, теперь с него невозможно получить обзор на легкий лагерь в маленьком лесу. Также лагерь мидера отодвинули подальше от центра (фармить станет заметно неудобнее). А еще поменяли расположение всех лагерей, кроме ближнего к Т2 в центре, а гору для Обса за Т2 в легкой просто убрали.
Гору для Обса с реки переместили на бывшее место среднего лагеря, а центральную гору передвинули к Т2 в легкой.
Т2 в оффлейне
Было:
Стало:
Что изменили? Добавили полноценный лабиринт деревьев слева от башни, теперь там нет тупика для ТП-аута. А еще справа от башни высадили совсем небольшой лес с тремя точками входа. Контринициировать у этой вышки для Radiant станет значительно проще.
Т2 в центре
Было:
Стало:
Что изменили? Поменяли расположение деревьев сверху от башни. Лес, соединявший центральную линию с большим лесом сильно потерял в числе деревьев, теперь там можно легко ходить и без Топорика. А главное – этот лес передвинули ближе к башне, ликвидировав огромное плато, что было раньше.
Т2 в легкой
Было:
Стало:
Что изменили? Лабиринт деревьев снизу от башни, он стал намного проще. Также убрали ХГ-выступ из большого леса, располагавшийся вплотную к вышке.
Половина Dire
Треугольник
Было:
Стало:
Что изменили? Удалили гору для Обса у потайной лавки, а гору у Т2 переместили ближе к центру треуголки, срезав при этом часть ХГ рядом с башней (+ туда еще деревьев посадили). Большой лагерь переместили к потайной лавке, теперь он расположен прямо у входа в треуголку с реки.
Маленький лес
Было:
Стало:
Что изменили? Добавили гору для Обса в стандартную точку для варда на вход в лес. Легкий лагерь передвинули сильно левее, поэтому Radiant будет легче за него бороться. Аванпост переместили в центр большого леса, а на его место поставили лагерь нейтралов, перед которым на лоуграунде создали тропинку.
Большой лес
Было:
Стало:
Что изменили? Аванпост теперь в центре большого леса, лагерь нейтралов, стоявший у Т2 в легкой, переместили к входу в лес с реки. Также гора для Обса теперь располагается почти в центре леса (раньше была за Т2 в легкой).
Т1 в центре
Было:
Стало:
Что изменили? Из леса за Т1 теперь можно выйти к большому лесу без топорика. Также немного поменяли лабиринт, что расположен рядом с треугольником.
Т2 в оффлейне
Было:
Стало:
Что изменили? Высадили одинокое дерево перед башней (оно точно выиграет пару драк). Срезали часть ХГ слева от башни, откуда раньше было очень удобно инициировать с Блинком. Справа от башни сделали полноценный лабиринт, а не несколько тупиков.
Т2 в центре
Было:
Стало:
Что изменили? Высадили несколько деревьев в лабиринт сверху от башни, усложнив его. Аналогично и двумя другими островками деревьев – они стали заметно крупнее, за ними теперь реально спрятаться.
Т2 в легкой
Было:
Стало:
Что изменили? Вместо лагеря нейтралов добавили сплошную линию из деревьев. Также высадили небольшой лабиринт снизу от башни, а лес сверху слегка расширили. Защищать эту вышку теперь проще.
В чем разница между bump, normal и displacement?
В статье мы подробно рассмотрим отличия карт bump от normal и displacement.
Вы столкнулись с трудностями при назначении карты bump на 3D-объект? Не переживайте! Многие 3D-художники, которые только начали изучать с 3D-текстурирование, испытывают сложности в этой области, не зная, какой тип карт выбрать: bump, normal и displacement.
Все три типа карт создают дополнительную детализацию на поверхности геометрии. Некоторые из этих деталей «настоящие», другие нет. Итак, попытаемся разобраться, в чем же заключается разница между картами bump, normal и displacement.
Что такое карты bump
Карты bump являются одним из старейших типов карт. И первое, что нужно понять – это то, что bump создает фейковую детализацию. И это правда, поскольку карты bump создают иллюзию глубины на поверхности модели с помощью трюка со светом. Никакой дополнительной детализации при этом не добавляется.
Обычно, карты bump – это черно-белые 8-битные изображения. И это только 256 цветов черного, серого или белого. С помощью этих значений карты bump сообщают 3D-редактору всего 2 вещи: деформировать геометрию вверх или вниз.
Когда значения карты bump близки к 50% серого, с поверхностью геометрии практически ничего не происходит. Когда изображение ярче, ближе к белому, детали выдавливаются на поверхности геометрии. Если изображение более темное, ближе к черному, детали вдавливаются в поверхность геометрии.
Карты bump отлично подходят для создания на поверхности модели мелкой детализации, например, пор или морщин на коже. Кроме того, их сравнительно легко создать в таком 2D-редакторе, как Photoshop, помня при этом, что работать нужно только с черно-белыми цветами.
Минус же карт bump заключается в том, что детализации, созданной с их помощью, можно достаточно быстро лишиться, если посмотреть на объект с неверного ракурса. Кроме того, при использовании карт bump силуэт модели остается неизменным, поскольку они создают фейковую, а не реальную детализацию.
Что такое карты normal
Карты нормалей или normal-карты – это улучшенные карты bump. Normal-карты, как и карты bump, создают фейковую детализацию, не добавляя дополнительных деталей геометрии в сцене. В результате, карты нормалей создают на поверхности модели иллюзию детализации, но эта детализация в корне отличается от той, которую создают карты bump.
Как мы уже знаем, карты bump используют черно-белые цвета, чтобы вдавливать или выдавливать поверхность геометрии. Normal-карты работают с RGB-информацией, которая точно отвечает X, Y и Z значениям в 3D-сцене. Эта RGB-информация сообщает 3D-редактору точное направление нормалей каждого полигона поверхности. Ориентация нормалей поверхности, которые часто называются просто нормалями, сообщает 3D- редактору, в какой цвет окрасить тот или иной полигон.
Normal-карты бывают двух типов и выглядят совершенно по-разному в 2D-пространстве.
Наиболее распространенным типом карт нормалей являются normal-карты типа tangent space, которые зачастую сочетают в себе лиловый и синий цвета. Этот тип карт нормалей лучше всего подходит для мешей, которые должны деформироваться при анимации. Normal-карты типа tangent space идеально подходят для персонажей. Для объектов, которые статичны и не испытывают деформаций, больше подходят карты нормалей типа object space. Эти карты окрашены в различные цвета и просчитываются немного быстрее normal-карт типа tangent space.
При использовании карт нормалей нужно понимать несколько моментов. В отличие от bump’а эти карты сложнее создать в 2D-редакторе типа Photoshop. Запекаются normal-карты с хайпольного меша на лоупольный. Однако, есть несколько путей их редактирования. Например, возможность редактирования карт нормалей представлена в MARI.
Кроме того, normal-карты лучше других вписываются в большинство пайплайнов. Но в отличие от карт bump в этом правиле есть исключение. И касается оно мобильного геймдева, поскольку аппаратные средства начали «понимать» карты нормалей сравнительно недавно.
Что такое карты displacement
Когда же дело доходит до создания дополнительной детализации для лоупольных мешей в игру вступают карты displacement, которые способны творить чудеса. Карты displacement создают физическую детализацию меша, на который они назначаются. Для создания displacement’а меш необходимо подразделить несколько раз или тесселировать, чтобы разрешения хватило для создания реальной геометрии.
Карты displacement выгодно отличает то, что их можно запечь с хайпольного меша или нарисовать вручную. Карты displacement, как и карты bump, работают с черно-белыми значениями цветов. При этом с легкостью можно использовать и 8-битные карты displacement, но лучший результат можно получить с помощью 16- или 32-битных карт displacement. И, хотя, 8-битные карты displacement лучше выглядят в 2D-пространстве, в на рендере они могут вызвать странные артефакты и пр. из-за недостаточной информации.
А вот что касается времени просчета, то тут все далеко не так круто. Создание дополнительной детализации в режиме реального времени достаточно трудоемкий процесс, с которым 3D-редактор справится не быстро. Кроме того, большинство 3D-редакторов просчитывают displacement уже на рендере. По сравнению с картами bump и normal карты displacement могут серьезно сказаться на времени рендера.
Ничто не справится с детализацией так, как это сделают карты displacement. И, поскольку поверхность геометрии изменяется на самом деле, это отражается и на силуэте модели. Но при этом всегда нужно оценивать реальную необходимость, а также преимущества использования карт displacement.
Одновременное использование всех карт
В некоторых случаях для одного и того же объекта можно использовать карту bump или normal в сочетании с displacement. При этом карту displacement лучше всего использовать для значительных изменений геометрии, а карты bump и normal для добавления мелких деталей.
Вне зависимости от того, какую карту вы выберите, принцип их работы необходимо понимать в любом случае, это только поможет еще лучше использовать преимущества карт bump, normal и displacement.
Читайте в нашей предыдущей статье о тонкостях displacement.