Подтвердить что ты не робот

Почему преобразование нормалей с транспонированием обратной матрицы модели?

Я работаю над некоторыми шейдерами, и мне нужно преобразовать нормали.

Я читал в немногих учебниках, как вы преобразовываете нормали, вы умножаете их на транспонирование обратной матрицы модели. Но я не могу найти объяснение, почему это так, и какова логика этого?

4b9b3361

Ответ 1

Взгляните на этот учебник:

https://paroj.github.io/gltut/Illumination/Tut09%20Normal%20Transformation.html

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

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

Ответ 2

Он вытекает из определения нормальной.

Предположим, что у вас есть нормальный, N и вектор, V, касательный вектор в том же положении на объекте, что и обычный. Тогда по определению N·V = 0.

Тангенциальные векторы работают в том же направлении, что и поверхность объекта. Поэтому, если ваша поверхность плоская, то касательная - это разница между двумя идентифицируемыми точками объекта. Поэтому, если V = Q - R, где Q и R - точки на поверхности, тогда, если вы преобразуете объект на B:

V' = BQ - BR
   = B(Q - R)
   = BV

Такая же логика применяется для непланарных поверхностей, рассматривая пределы.

В этом случае предположим, что вы намерены преобразовать модель по матрице B. Таким образом, B будет применяться к геометрии. Затем, чтобы выяснить, что делать с нормалями, вам нужно решить для матрицы A, чтобы:

(AN)·(BV) = 0

Включение этого в строку против столбца для исключения явного продукта dot:

[tranpose(AN)](BV) = 0

Потяните транспонирование снаружи, устраните скобки:

transpose(N)*transpose(A)*B*V = 0

Итак, чтобы "транспонировать нормальный" [продукт с] "транспонировать известную матрицу преобразования" [произведение с] "преобразование, которое мы решаем для" [продукта с] "вектором на поверхности model" = 0

Но мы начали с утверждения, что transpose(N)*V = 0, так как это то же самое, что сказать, что N·V = 0. Поэтому для удовлетворения наших ограничений нам нужна средняя часть выражения - transpose(A)*B - чтобы уйти.

Отсюда можно заключить, что:

 transpose(A)*B = identity
 => transpose(A) = identity*inverse(B)
 => transpose(A) = inverse(B)
 => A = transpose(inverse(B))

Ответ 3

Мое любимое доказательство ниже, где N - нормальное, а V - касательный вектор. Поскольку они перпендикулярны, их точечный продукт равен нулю. M - любое 3x3 обратимое преобразование (M -1 * M = I). N 'и V' - векторы, преобразованные через M.

enter image description here

Чтобы получить некоторую интуицию, рассмотрим преобразование сдвига ниже.

enter image description here

Обратите внимание, что это не относится к касательным векторам.

Ответ 4

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

Я написал подробности в своем блоге: https://lxjk.github.io/2017/10/01/Stop-Using-Normal-Matrix.html

Ответ 5

Не понимаю, почему вы просто не обнуляете 4-й элемент вектора направления перед умножением на модельную матрицу. Никакой обратной или транспонированной необходимости. Подумайте о векторе направления как о разнице между двумя точками. Переместите две точки с остальной частью модели - они все еще находятся в одном и том же относительном положении к модели. Возьмите разницу между двумя точками, чтобы получить новое направление, а четвертый элемент - отменяется до нуля. Лот дешевле.