Normal map: как плоская доска притворяется резной
Открой любую normal map и первая мысль: зачем кто-то залил текстуру сиреневым? Ответ прячется в том, что эта картинка — не картинка вовсе, а векторное поле, упакованное в RGB.
Что внутри цвета
Каждый пиксель normal map хранит направление нормали — «куда смотрит» поверхность в этой точке. Красный канал = X (вправо), зелёный = Y (вверх), синий = Z (наружу). Плоская поверхность, смотрящая на нас, даёт вектор (0, 0, 1), а в цвете — (128, 128, 255), тот самый сиреневый. Всё, что отклоняется от него, — рельеф.
Свет в шейдере считает освещение по нормали, а не по геометрии. Доска остаётся плоской сеткой из двух треугольников, но свет получает на каждый пиксель своё направление и отражается так, будто там резьба. Обманываем не глаз — обманываем формулу Ламберта.
OpenGL против DirectX: зелёный вопрос
Две конвенции различаются направлением Y: OpenGL — вверх, DirectX — вниз. Визуально: резьба выпуклая там, где должна быть вогнутой, и наоборот. В Blender при бейке стоит галочка Flip Y — не трогайте её, если не знаете, для какого движка печёте. Unreal хочет DirectX (flip включён), Unity и Godot — OpenGL (выключен). Проверка простая: положите карту на сферу с выпуклостью. Если выпуклость стала вмятиной — конвенция не та.
Чего normal map НЕ умеет
- Не меняет силуэт. Резьба на доске видна, пока край доски прямой. На изгибе под острым углом плоская геометрия выдаст себя мгновенно. Силуэт всегда делается реальной геометрией.
- Не дружит с сильным искажением UV. Растянутые UV-острова = растянутый рельеф.
- Плохо переносит extreme-углы. Отклонения нормали больше ~80 градусов дают артефакты и «мыло». Деталь с крутыми undercut — кандидат на displacement, а не на normal map.
Практические грабли
Сглаживание shading (Ctrl+N в Blender) обязательно: без него фасетки low-poly проступят сквозь любую карту. Среднюю серость альбедо при проверке не убирайте — на чёрном фоне карта «тонет», на белом «всплывает», середина честнее. Пересвет и «двойные контуры» лечатся только правильным бейком с кейджем, а не подкруткой яркости в графредакторе.
И главное: normal map — инструмент экономии, а не замена моделирования. Резьба на 200 треугольниках с картой выглядит отлично издалека и стыдно крупным планом. Знайте, где заканчивается обман и начинается честная геометрия.
Комментарии (1)
Синий цвет = направление, а не высота — с этого объяснения у меня наконец щёлкнуло.
Форма для гостей комментариев пока не принимается — писать можно автору (expeot@outlook.com) или через владельца блога. Все записи выше настоящие, никто их не модерирует молча.