Согласно Красной книге OpenGL, Приложение F, обычная матрица трехмерного преобразования M может использоваться для расчета действия на вектор нормали следующим образом:
normalTransformed = transpose(inverse(M)) * normal
Однако, хотя ортогональная плоскость, связанная с преобразованной нормалью, действительно трансформированной поверхности, может случиться так, что сам трансформированный вектор нормали указывает направление, противоположное ожидаемому, т. е. «в» поверхность, а не «вне» поверхности.
Если я хочу, чтобы normalTransformed указывал в правильном направлении (то есть в том же направлении, в котором он указывает, когда поверхность, к которой он прикреплен, не трансформируется), как мне это сделать математически?
ПРИМЕР
Предположим, моя нормаль к поверхности равна (0,0,1), а мое преобразование представляет собой перемещение на 10 в направлении Z. Матрица преобразования M тогда:
1 0 0 0
0 1 0 0
0 0 1 10
0 0 0 1
Транспонирование(инверсия(M)) тогда:
1 0 0 0
0 1 0 0
0 0 1 0
0 0 -10 1
Применительно к нормали к поверхности (0,0,1), т. е. (0,0,1,1) в однородных координатах, это дает:
normalTransformed = (0, 0, 1 , -9)
Назад от однородных координат:
(0, 0, -1/9)
Нормирование к длине 1:
(0, 0, -1)
Что указывает на направление, противоположное исходному вектору нормали (0, 0, 1).