Кузница полигонов: создание карт нормалей
Всего пару лет назад технология карт нормалей была настоящей революцией. Именно благодаря ей стало возможным изображать в играх низкополигональные модели так, как будто они высокополигональные. За примерами далеко ходить не надо, достаточно вспомнить Far Cry и DOOM 3.
Сегодня с картами нормалей работает большинство моделлеров по всему миру. И будут работать еще ой как долго. Пора и нам детально изучить, что же это за зверь такой и как к нему подступиться. Обратите внимание, что материал рассчитан на более-менее подкованного в вопросе трехмерного моделирования пользователя. Если же вы только начинаете увлекательное погружение в мир 3D, то специально для вас мы приготовили сюрприз. На нашем диске находится полуторачасовой видеоурок , наглядно иллюстрирующий данную статью. Все упоминающиеся в статье файлы можно взять с нашего DVD (в разделе «Игрострой»).
Базовые принципы
Суть технологии заключается в генерации для низкополигональной модели такой текстуры, которая, будучи наложенной по специальному алгоритму, в точности имитирует высокополигональную сетку. То есть модель всего в несколько тысяч полигонов смотрится так, как будто она составлена из десятков и даже сотен тысяч треугольников.
Генерируемая для этой цели текстура называется картой нормалей: она содержит в себе информацию о разнице между низкополигональной моделью и высокополигональной (принято говорить просто « разница », без упоминания между чем и чем). Главная проблема при создании карты нормалей — правильно посчитать эту разницу.
Разница хранится в трех цветовых составляющих изображения (красной, зеленой и голубой). Цвет каждого пикселя кодирует информацию о том, в какую сторону была ориентирована нормаль детальной модели по отношению к нормали вершины низкополигональной модели в данной точке развертки. Красная и зеленая компоненты определяют отклонение нормали вправо/влево и вверх/вниз соответственно. Голубая цветовая составляющая, по сути, является обычной картой рельефа (bump map).
Точка отсчета
Из программного обеспечения нам потребуются 3DS Max 7 (или выше) и ZBrush 2. На этот раз мы не будем заострять внимание на процессе моделирования: почти все действия по моделированию в 3DS Max можно детально изучить на нашем диске в видеоуроке. Этап моделирования в ZBrush записан в виде скрипта, его тоже смотрите на диске.
Работа начинается с… концептуального рисунка. Берем в руки карандаш и рисуем эскиз того предмета, который будем моделировать. Нам нужен точный шаблон. Я, например, пофантазировав полчаса, придумал концепцию фэнтезийного клинка «Коготь грифона» ( рис. 1, эскиз или файл Gryphon’s_Blade_Sketch.bmp ). Поэтому в статье мы будем работать именно с этой моделью.
После непродолжительного колдовства с полигонами (см. видеоурок) получается модель как в файле Gryphon’s_Blade_LOW_Complete.max. Именно для нее нам предстоит сделать сначала высокодетализированный аналог, а затем и карту нормалей.
Подготовка модели к детализации
Для тех, кто создавал свою модель с нуля, хочу заметить, что вся работа ведется не с сеточным объектом ( Editable Mesh ), а полигонным ( Editable Poly ). Игровые движки разницу между ними не различают, отличие проявляется именно при подготовке высокополигональной модельки.
С чего же начать? Просто добавить в стек модификатор 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.
Проработка детальной модели
Мы подошли к самому интересному этапу работы — созданию детальной модели в ZBrush. Для того чтобы начать работу, экспортируем подготовленную сглаженную модель в формат OBJ. Опции экспорта настраиваем так: снимаем галочки в группе File , а в комбинированном списке Faces выбираем пункт Polygons , после чего кликаем ОК. В среде ZBrush выполняем команду Tool/Load Tool , в открывшемся диалоге находим экспортированный файл. Сохраняем появившийся в меню новый инструмент как ZTL -файл.
Чтобы посмотреть урок моделирования деталей «Когтя грифона», идем в меню ZScript , кликаем на & notes, жмем 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 в свойствах объекта).
Низкополигональная модель лишена развертки, поэтому при помощи модификатора 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 , после чего запустится процесс рендеринга текстуры, но на экране будет отображена только проекция полной визуальной карты высокополигональной модели. На этой карте, скорее всего, будут присутствовать некоторые участки, закрашенные красным цветом. Давайте разберемся, что это значит.
Переключаемся на стек модификаторов лоуполи-модели. Оказывается, в его вершину добавилась новая строка — Projection. Этот модификатор является вспомогательным при проецировании с одной модели на другую и служит для создания так называемой клетки (Cage). Клетка является копией исходного низкополигонального каркаса, но модифицирована она так, что внутри нее полностью помещается высокополигональная модель. Так вот, красными пятнами на текстуре «Макс» помечает те части, где детальная модель вылезла за клетку: произошло это из-за того, что генерировать идеальную клетку «Макс» пока не умеет (да и не скоро еще научится). Поэтому опять придется поработать вручную. Действуем по следующему алгоритму:
1. Сохраненную в файл карту нормалей загружаем в слот Diffuse пустого материала, включаем отображение текстуры во вьюпорте и назначаем этот материал нашей упрощенной модели. Карта нормалей будет наглядно (цветом) отображена в видовых окнах «Макса».
2. У проекционного модификатора выбираем уровень редактирования Cage и в одноименном свитке жмем кнопку Reset. Это восстановит изначальную форму клетки. Теперь, увеличивая значение Amount в группе Push , придаем такую форму клетке, чтобы она равномерно покрывала высокополигональную модель. После этого, перемещая вершины клетки, максимально улучшаем степень покрытия.
3. Рендерим текстуру.
Все эти шаги повторяем до тех пор, пока красные участки с текстуры либо не исчезнут, либо не окажутся в незаметных местах (закрытые сгибы, складки). Пример удачно сгенерированной карты нормалей показан на рис. 6.2.
Самая сложная часть работы позади, нам осталось только доработать детали и проверить модель в деле.
Финальные штрихи
Использовать карту нормалей можно двумя способами. Первый способ заключается в том, чтобы в слот 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.