Нормалы против карт нормалей

17

Я использую средство импорта ресурсов Assimp ( http://assimp.sourceforge.net/lib_html/index.html ) для анализа 3d-моделей.

Пока что я просто вытащил нормальные векторы, которые определены для каждой вершины в моих сетках. Тем не менее, я также нашел различные учебники на картах нормалей ...

Как я понимаю, для карт нормалей векторы нормалей сохраняются в каждом текселе карты нормалей, и вы вытаскиваете их из текстуры нормалей в шейдере.

Почему есть два способа получения нормалей, какой считается лучшим и почему?

KaiserJohaan
источник

Ответы:

31

Короткий ответ

Карты нормалей и нормали - это две разные вещи: нормали - это геометрическое свойство любой сетки / поверхности, ее использование не является исключительным для расчета затенения и освещения, но на самом деле имеет много других применений, например в физике. Карты нормалей - это текстуры, которые кодируют альтернативные векторы нормалей, используемые в компьютерной графике для имитации неровностей.

Длинный ответ

Нормалы в геометрии нормаль - это вектор или линия, перпендикулярная данному объекту (например, нормаль к плоскости, нормаль к вершине). Нормы в графике обычно используются для расчета освещенности, например, для расчета диффузного отражения на поверхности путем помещения точечного произведения между направлением света и нормалями поверхности. Нормалы обычно рассчитываются на основе геометрических свойств сетки (грани / вершины) путем взятия перекрестного произведения любых двух непараллельных ребер, лежащих на одной плоскости.

В OpenGL нормали задаются для каждой вершины (следовательно, они называются атрибутами вершин), даже если они могут быть рассчитаны только для каждой грани, в этом случае вам необходимо указать одну и ту же нормаль для каждой вершины грани. Нормы можно интерполировать с помощью OpenGL по каждой вершине грани (треугольника), чтобы вы могли рассчитать отраженный свет на пиксель, а не на вершину, что дает более точный результат.

Отображение нормалей: с другой стороны, это методика компьютерной графики, которая кодирует нормали в текстурной карте, поэтому каждый нормаль кодируется для каждого текселя. Он обычно используется для фальсификации освещения ударов и вмятин (например, картографирование выпуклостей, отображение параллакса).

Так как нормали рассчитываются на основе геометрических свойств сетки / поверхности, Карты нормалей предоставят вам альтернативные нормали, которые могут имитировать неровности, чтобы добавить детали к поверхности, не добавляя больше полигонов.

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

Зачем нам оба?

Говоря только о рендеринге, нормали и карты нормалей обычно используются вместе для достижения окончательного эффекта освещения, хорошим примером может служить рельефный шейдер, где вам нужна нормаль карты нормалей для достижения эффекта рельефного освещения, и вам все равно понадобится геометрическая нормаль для расчета того, что называется касательным пространством . Касательное пространство обычно используется для повторного использования для карт нормалей.

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

Расширяем ответ, чтобы объяснить, почему касательные пространства важны:

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

[EDIT] Добавлено изображение для представления карты нормалей в касательном пространстве и карты нормалей в мировом пространстве.

введите описание изображения здесь

Длинный ответ: На приведенном ниже рисунке показана плоскость UV и нормаль, которая определяет касательное пространство, при создании карты нормалей мы уже будем знать, что используемое пространство всегда будет иметь направление Normal в направлении Z (поэтому карты нормалей выглядят голубоватыми) , это поможет нам игнорировать кривизну поверхности **,.

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

введите описание изображения здесь

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

** кривизна поверхности определяется величиной, от которой геометрический объект отклоняется от плоской или прямой в случае линии, но это определяется по-разному в зависимости от контекста.

Касательное пространственное представление

concept3d
источник
1
Если вы можете найти изображение, изображающее, как нормальная текстура не может быть последовательно использована без нормального и касательного поля, определенного для каждой вершины, вы сделаете это лучшим ответом на этот загадочный вопрос для большинства начинающих графических программистов!
Теодрон
Хороший ответ, но нормали не интерполируются OpenGL на каждом лице. Вы должны сделать это самостоятельно и передать интерполированную нормаль в OpenGL (или в свой код шейдера).
Анастасиос Г
1
@AnastasiosG Я думаю, что он говорит о поведении изменяющихся данных по умолчанию, поскольку они интерполируются через треугольник всякий раз, когда фрагмент вычисляется для определенного примитива. Я знаю, что был флаг, который вы могли бы использовать, чтобы сказать OpenGL использовать одну конкретную нормаль из возможных 3 вершинных нормалей треугольника, но это не поведение по умолчанию, как мне известно.
Теодрон
1
@AnastasiosG Я думал, что такие подробности не пойдут на пользу, так как речь идет не о том, как использовать OpenGL. Но если это поможет, в эпоху фиксированных конвейеров вам потребовался порядок glShadeModel (GL_SMOOTH), чтобы сказать openGL о интерполяции. В эпоху программируемого конвейера вы определяете переменные как переменные или входящие / исходящие в шейдере, чтобы OpenGL мог интерполировать.
concept3d
Я хотел бы добавить, что карты рельефа - это просто (геометрические) нормали, которые поднимаются / опускаются на основе черно-белой текстуры. :)
Энтальпи