Я изучаю некоторые основы OpenGL, но мне интересно, почему есть вызов, glNormal
чтобы установить нормаль вершин.
Если я создам простой треугольник, как это:
glBegin(GL_TRIANGLES);
glVertex3f(0,0,0);
glVertex3f(1,0,0);
glVertex3f(0,1,0);
glEnd();
Не должны ли нормали определяться неявно по типу геометрического примитива? Если я не установлю нормальный, OpenGL вычислит это?
Ответы:
Вызов
glNormal
несколько раз междуglBegin/End
позволяет вам установить нормаль для каждой вершины, а не для каждого примитива.Для более сложной сетки, состоящей из нескольких треугольников, необходимо, чтобы нормаль в одной вершине зависела от других треугольников окружающей геометрии, а не только от нормали треугольника, которому она принадлежит.
Вот пример той же геометрии с:
(0,0,1)
):Модель затенения по умолчанию (
GL_SMOOTH
) вызывает интерполяцию нормалей вершин грани по всей грани. Для нормалей для каждой вершины это приводит к гладкой заштрихованной сфере, но для нормалей для каждой грани вы получите характерный граненый вид.источник
Нет, GL не рассчитывает для вас норму. Это не может знать, что должно быть нормальным. Ваши примитивы ничего не значат за пределами растеризации (и нескольких других мест). GL не знает, какие грани (треугольники) разделяют вершину (вычисление этого во время выполнения очень дорого без использования различных структур данных).
Вам нужно предварительно обработать «треугольный суп» меша, чтобы найти общие вершины и вычислить нормали. Это должно быть сделано до того, как игра наберет скорость.
Есть также случаи, например, с жесткими ребрами, когда геометрически есть общая вершина в углу, но вы хотите разделить нормали, чтобы она правильно освещалась. В модели рендеринга GL / D3D вам для этого нужны две отдельные вершины (в одной позиции), каждая с отдельной нормалью.
Все это вам понадобится и для UV, и для наложения текстур.
источник
Короткий ответ: на самом деле вы не нужно устанавливать нормальное значение. Нормальные векторы используются, только если вы выполняете освещение OpenGL (или, возможно, какой-то другой расчет, который может зависеть от них), но если это не относится к вам (или если вы используете какой-то другой метод для освещения, например, карты освещения ) тогда вы можете довольно счастливо пропустить все вызовы glNormal.
Итак, давайте предположим, что вы делаете что-то, где указание glNormal имеет смысл, и посмотрим на это еще немного.
glNormal может быть указан для примитива или вершины. Для нормальных пермитивных элементов все, что это означает, состоит в том, что все нормали для каждой вершины примитивной грани в одном направлении. Иногда это то, что вы хотите, но иногда это не так - нормали для каждой вершины полезны в том, что они позволяют каждой вершине иметь свою собственную ориентацию.
Возьмите классический пример сферы. Если бы каждый треугольник в сфере имел одинаковую нормаль, то конечный результат был бы весьма граненым. Это, вероятно, не то, что вы хотите, вместо этого вы хотите плавное затенение. Таким образом, вы выполняете усреднение нормалей для каждого треугольника, имеющего общую вершину, и получаете плавный заштрихованный результат.
источник
Минимальный пример, который иллюстрирует некоторые детали того, как
glNormal
работает рассеянная молния.Комментарии
display
функции объясняют, что означает каждый треугольник.теория
В OpenGL каждая вершина имеет свой собственный связанный вектор нормали.
Вектор нормали определяет яркость вершины, которая затем используется для определения яркости треугольника.
Когда поверхность перпендикулярна свету, она ярче параллельной поверхности.
glNormal
устанавливает текущий вектор нормали, который используется для всех следующих вершин.Начальное значение для нормального , прежде чем все
glNormal
это0,0,1
.Нормальные векторы должны иметь норму 1, иначе цвета меняются!
glScale
также изменяет длину нормалей!glEnable(GL_NORMALIZE);
заставляет OpenGL автоматически устанавливать для них норму 1. Этот GIF прекрасно это иллюстрирует.Список используемой литературы:
источник
Вам нужен glNormal для реализации некоторых функций, зависящих от кодера. Например, вы можете захотеть создать нормали, сохраняющие твердые края.
источник