Учитывая треугольник, определенный его тремя вершинами ABC, вектор, перпендикулярный («нормальный») этому треугольнику, легко получить с помощью перекрестного произведения двух векторов, например, ABxAC. Но также ABxBC.
Дело в том, что перекрестное произведение НЕ коммутативно. Итак, ABxAC - это не то же самое, что ACxAB. Точно это ABxAC = - ACxAB, это тот же вектор, но в противоположном направлении .
Нормальное направление передней поверхности должно быть рассчитано в соответствии с порядком намотки или треугольником. Тот же порядок, в котором вы устанавливаете вершины треугольника в буфере, - это порядок выбора векторов для перекрестного произведения.
Вы должны знать, как GL делает порядок намотки в зависимости от типа треугольного примитива
Пример
Допустим, вы используете glDrawArrays (GL_TRIANGLES, ...) и ваш буфер вершин выглядит как v1, v2, v3, v1, v3, v4, v1, v4, v5 и т. Д. (Vi = vix, viy, viz) где все порядки намотки против часовой стрелки. Тогда:
Vector AB = v2 - v1
Vector AC = v3 - v1
Vector perp = cross(AB, AC)
Vector norm = normalize(perp) //divide each component by lenght of perp
Теперь у вас есть нормаль к лицам, нормали в точках немного сложнее.
Простейшим способом является вычисление среднего значения нормали к треугольникам, разделяющим вершину. Когда каждый фрагмент треугольника заштрихован, нормаль в этой точке может быть интерполирована из нормалей в вершинах. В результате вы получаете «мягкий» переход от треугольника к треугольнику.
Если вы хотите сохранить края (жесткий переход), то вы должны указать разные нормали для разных треугольников. Таким образом, каждая вершина, если смотреть на шейдер, получает свою собственную нормаль. Повторите вершину для другого треугольника, затем установите другую нормаль даже для той же самой вершины.