Карты нормалей. Часть I

Здравствуйте.

Иногда по работе мне приходится спрашивать у дизайнеров про то, смогут ли они сделать карту нормалей и использовать ее на своей модели. В большинстве случаев ответ отрицательный.

Что это за технология и откуда она взялась?

Немного из истории карт нормалей.

Впервые идея о том, что можно «брать» детали с высокополигональной модели и переносить на низкополигональную, была предложена на СИГГРАФ (SIGGRAPH) в 1996 во время доклада “Использование сглаженных поверхностей для добавления плотности полигональной сетке” авторов Кришнамурати и Левои. Предлагалось использовать созданные на основе НУРБС (NURBS) карты смещения (displacement maps) для увеличения детализации низкополигональной поверхности. Это была только идея; приложение, которое смогло это сделать, появилось гораздо позже.

SIGGRAPH (The Special Interest Group for Computer Graphics) группа SIGGRAPH специальная группа в составе ASM, объединяющая специалистов по компьютерной графике. Проводит ежегодные конференции, предназначенные для художников и аниматоров, работающих с компьютерной графикой.

В 1998 опять на СИГГРАФ были прочитаны 2 доклада о трансформации деталей, составляющих объект как нормалей с высокополигональной модели на низкополигональную. Назывался доклад: «Appearance Preserving Simplification» за авторством Коэна и еще нескольких исследователей из Института инженеров по электротехнике и электронике визуализации. В первой работе представлен алгоритм, с помощью которого при упрощении можно следить за тем, как потерянные детали должны отрисовываться на упрощенной сетке. Далее был представлен простой подход, при котором высоко- и низкополигональная сетка разделяется, а утерянные детали восстанавливаются независимо от способа создания низкополигональной модели. Этот метод (с небольшими вариациями) в данный момент используется в большинстве приложений.

Что же такое карта нормалей?

Карта нормалей (normal map) — это дальнейшее развитие такой технологии как бамп (bump (англ.) – изгиб, выпуклость; выпуклая вмятина, вздутие). Иногда карты нормалей называют «3-х точечная бамп-карта» (Dot3 bump mapping).

Бамп-карта искажает значения нормалей полигонов, а карта нормалей полностью их заменяет. Т.е., оригинальные нормали объекта заменяются нормалями с высокополигональной модели.

Как и бамп, карты нормалей увеличивает визуальную детализацию 3d-модели без добавления дополнительных полигонов.

Бамп рассчитывается на основе текстуры с одним каналом (grayscale — оттенки серого). Карты нормалей используют многоканальную RGB-текстуру.

Карта нормалей рассчитывается для каждого пикселя текстуры. Значения каждого из каналов RGB — это XYZ координаты нормали текселя.

Тексель (текстурный элемент, текстурный пиксель) — это основной элемент, составляющий текстуру. Каждая текстура представляет собой массив текселей, так же как картинка — это массив пикселей.

Обычно карты нормалей существуют в 2-х вариациях: объектное пространство (object-space) и касательное пространство (tangent-space). Они отличаются системой координат, в которой нормали измеряются и сохраняются.

Tangent space (пространство касательных, касательное пространство) — это обобщение на случай произвольного многообразия понятий касательной прямой для одномерных кривых и касательной плоскости для двумерных поверхностей.

Как видите — все просто 

Хотите больше теории — найдете в англоязычном Интернете.

По-простому говоря: 1 тексель текстуры с картами нормалей заменяет 10 полигонов, а может и больше.

Больше всего «нормала», наверное, в играх.

Игра, в которой я впервые прочувствовал, что такое «нормал» — DOOM 3 производства id Software.

Вот они — кишки с картами нормалей.

Нажмите на изображении, чтобы увидеть его в полный размер.

Название файла:	Doom_III_E3_alpha.jpg
Просмотров:	834
Размер:	35.5 КБ
ID:	3500
Ссылка на это изображение на wikipedia.org

Настоящие «нормальные» монстры.

Нажмите на изображении, чтобы увидеть его в полный размер.

Название файла:	Doom3shadows2.jpg
Просмотров:	680
Размер:	38.7 КБ
ID:	3501
Ссылка на это изображение на wikipedia.org

Это не игра, а гимн картам нормалей. Они там повсюду.

Сейчас 2008 год. Технология придумана давно. Применяется уже 5 лет точно, причем очень «плотно» в самых популярных играх.

Не играли в ДУМ 3?

А про «Зед-Браш» (ZBRUSH) слышали?

Этот программный продукт создан для того, чтобы снимать красивые карты нормалей (ну и многое другое еще сделать позволяет).

В итоге можно сказать, что использование карт нормалей — довольно старая и популярная технология.

Тем не менее, не так уж много 3d дизайнеров используют возможности карт нормалей в своей работе.

Я думаю, дело в кажущейся сложности технологического процесса.

Кнопок много. Какие надо нажимать, чтобы «получилось»? Тайна.

Вы думаете, я делал ЭТО в 2000 году? Или в 2004, когда вышел ДУМ?

Нет. Я и сам узнал про эти «нормали» недавно.

Сначала были ограничения со стороны «железа». Потом — программного обеспечения, но и они приблизительно в 2005 году закончились.

Я начал использовать «нормал» приблизительно с 2005 года, но это была не совсем та технология, о которой вы могли прочитать выше.

Я рисовал бамп, используя оттенки серого. Иногда преобразовывал цветное изображение в серое, а затем с помощью специального фильтра в Фотошопе превращал его в карту нормалей.

Нажмите на изображении, чтобы увидеть его в полный размер.

Название файла:	bump_normal.gif
Просмотров:	660
Размер:	5.6 КБ
ID:	3502

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

Если вы делаете персонажа, машину или еще какой либо сложный объект, вам придется использовать другой метод. Тот самый, который предложили в 1998 году. Когда вы «снимаете» карту нормалей с высокополигональной модели, а затем накладываете эту карту на низкополигональный объект.

Попробуем преодолеть технологические сложности, сделав простейшую карту нормалей.

Генерировать нормал можно в Maya, 3ds max, NVIDIA Melody и Z-Brush. Наверное список программ больше.

Я делал это в 3ds max.

Переходим в 3ds max 9

Попробуем сделать карту нормалей для этого объекта.

Нажмите на изображении, чтобы увидеть его в полный размер.

Название файла:	base_object.gif
Просмотров:	237
Размер:	7.4 КБ
ID:	3503

Это 2 полигона, соединенных под прямым углом.

Вот «усики» нормалей. По 2 штуки на фэйс (видны в Edit Mesh при включении одной галочки).

Нажмите на изображении, чтобы увидеть его в полный размер.

Название файла:	base_object_normals.gif
Просмотров:	252
Размер:	15.5 КБ
ID:	3504

Я хочу добиться от этого угловатого объекта сглаженных углов, как на скриншоте ниже.

Нажмите на изображении, чтобы увидеть его в полный размер.

Название файла:	hipoly_normals.gif
Просмотров:	254
Размер:	65.2 КБ
ID:	3505

Вот что у нас есть перед началом работы.

Нажмите на изображении, чтобы увидеть его в полный размер.

Название файла:	objects.gif
Просмотров:	218
Размер:	34.8 КБ
ID:	3506

Внимание! На объекты должна быть назначена только одна группа сглаживания.

Нажмите на изображении, чтобы увидеть его в полный размер.

Название файла:	one_smooth_group.gif
Просмотров:	233
Размер:	18.6 КБ
ID:	3507

Первым делом надо разложить анврап на низкополигональной модели.

Именно на анврап упрощенной модели будут спроецированы детали высокополигональной модели.

Как ляжет анврап, так и произойдет проецирование. Если анврап «кривой» — ждите неправильной карты нормалей.

Выделив упрощенный объект, сразу перейдем в Unwrap UVW и сделаем Flatten Maping с установками по умолчанию.

Вот что получилось. Красным обведено проблемное место.

Нажмите на изображении, чтобы увидеть его в полный размер.

Название файла:	weld_stage_02.gif
Просмотров:	274
Размер:	51.1 КБ
ID:	3508

Это разрыв UV-координат. Я специально наложил на объект простую текстуру, которая помогает продемонстрировать проблему.

Нажмите на изображении, чтобы увидеть его в полный размер.

Название файла:	weld_stage_03.gif
Просмотров:	413
Размер:	83.0 КБ
ID:	3509

От разрывов необходимо избавляться по максимуму или прятать их в незаметные места.

Пару раз отразим наши полигоны. Немного подвинем. Именно подвинем, а не растянем. Объединим точки (Weld).

Готово.

Белая линия на стыке говорит о том, что разрыва текстурных координат нет.

Нажмите на изображении, чтобы увидеть его в полный размер.

Название файла:	OK_stage_04.gif
Просмотров:	266
Размер:	66.0 КБ
ID:	3510

И на текстуре все в порядке.

Теперь надо совместить объекты. Для этого обычно достаточно поместить Pivot объекта в центр объекта (делается для двух объектов автоматически) и выровнять объект один относительного другого по всем осям координат.

Вот Pivot’ы.

Нажмите на изображении, чтобы увидеть его в полный размер.

Название файла:	pivots.gif
Просмотров:	308
Размер:	66.4 КБ
ID:	3511

Выравниваем объекты относительно друг друга. Ctrl+A

Нажмите на изображении, чтобы увидеть его в полный размер.

Название файла:	align.gif
Просмотров:	301
Размер:	52.3 КБ
ID:	3512

Внимание! Объекты находятся в точке с координатами 0,0,0

Некоторые действия, которые я делаю, возможно, избыточны, но мне они помогли решить много проблем.

Выделив низкополигональный объект, применяем модификатор «Проекция» (Projection).

Нажмите на изображении, чтобы увидеть его в полный размер.

Название файла:	projection.gif
Просмотров:	283
Размер:	50.7 КБ
ID:	3513

Этот модификатор будет проецировать что-то с одного объекта на другой. В нашем случае что-то — карта нормалей.

Указываем — с какого объекта будет сниматься карта нормалей. Без этого ничего работать не будет.

Нажмите на изображении, чтобы увидеть его в полный размер.

Название файла:	pick.gif
Просмотров:	428
Размер:	59.0 КБ
ID:	3514

Выбираем детализированную геометрию, кликнув по объекту (Pick) или выбрав из списка присутствующих в сцене (Pick List).

Внимание! Чтобы не запутаться, я назвал простой объект — LowPoly, а сложный HiPoly.

Появился Контейнер (cage) — фиолетовые линии. Он охватывает модели. Что в него попадет — то и будет спроецировано. Иногда контейнер очень кривой, особенно на моделях со сложной геометрией — тогда делаем Сброс (Reset).

Нажмите на изображении, чтобы увидеть его в полный размер.

Название файла:	reset_push.gif
Просмотров:	560
Размер:	5.9 КБ
ID:	3515

Без ресета в Максе никуда!

После сброса контейнер плотно прижмется к упрощенному объекту, повторяя его формы. Мы должны увеличить контейнер. Не забудьте: что в нем — то и попадет на карту нормалей.

Внимание! Контейнер не должен пересекать сам себя или низкополигональный объект.

Нажимаем 0 (ноль) — появляется окно Render to Texture.

Нажмите на изображении, чтобы увидеть его в полный размер.

Название файла:	projection_start.gif
Просмотров:	938
Размер:	79.1 КБ
ID:	3516

Бывает нужно указать Target Slot. Это чтобы Макс знал, куда класть свежесгенерированную текстуру. По умолчанию выбран Бамп.

Нажимаем Render.

Макс рендерит. Но мы не видим нормала.

Да, во время рендера он не виден. Зато в указанном месте создается файл. Вот что получилось у меня.

Нажмите на изображении, чтобы увидеть его в полный размер.

Название файла:	normal.gif
Просмотров:	615
Размер:	45.7 КБ
ID:	3517

Похоже на нормал. Как проверить работает он или нет?

В слот Bump Редактора материалов назначаем материал NormalBump. Значение 100.

Нажмите на изображении, чтобы увидеть его в полный размер.

Название файла:	normalbumpmat.gif
Просмотров:	492
Размер:	72.7 КБ
ID:	3518

В слот Normal назначаем обычный Bitmap с нашей текстурой.

Обратите внимание, я отключил диффузную текстуру. Она мешала оценить результат.

Можно посмотреть, если хочется, как лег нормал, включив отображение текстуры (кубик с шашечками) Bitmap’a в слоте Normal.

Нажмите на изображении, чтобы увидеть его в полный размер.

Название файла:	view_normal.gif
Просмотров:	231
Размер:	59.7 КБ
ID:	3519

Тоже вроде все правильно.

Результат отлично виден на рендере. Запускаем обычный сканлайн.

Где низкополигональный «уголок»?

Нажмите на изображении, чтобы увидеть его в полный размер.

Название файла:	render_01.jpg
Просмотров:	610
Размер:	3.9 КБ
ID:	3520

А вот с такого ракурса?

Нажмите на изображении, чтобы увидеть его в полный размер.

Название файла:	render_02.jpg
Просмотров:	592
Размер:	4.1 КБ
ID:	3521

Сделаем картинку крупнее.

Нажмите на изображении, чтобы увидеть его в полный размер.

Название файла:	render_03.jpg
Просмотров:	604
Размер:	8.3 КБ
ID:	3522

Если бы не угол — то заметить разницу было бы довольно сложно.

А вот во вьюпорте.

Нажмите на изображении, чтобы увидеть его в полный размер.

Название файла:	compare_in_max.gif
Просмотров:	249
Размер:	62.0 КБ
ID:	3523

Карта нормалей готова!

Высокополигональный объект — 64 полигона.
Низкополигональный — 2 полигона.

Визуальные отличия минимальные. Цель достигнута.

Хотя конечно многое зависит от ракурса 🙂

Что дальше?
Дальше куча глюков, проблем и шаманства.

В следующий раз попробуем сделать что-нибудь посложнее.

Обсуждение. Дополнения. Исправления. Вопросы.

Библиография
http://en.wikipedia.org/wiki/Normal_map
http://en.wikipedia.org/wiki/Texel_%28graphics%29
http://en.wikipedia.org/wiki/Tangent_space

Comments

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.