Pourquoi l'inverse transposé de la matrice de vue du modèle est-il utilisé pour transformer les vecteurs normaux?

22

Lors du rendu de scènes 3D avec des transformations appliquées aux objets, les normales doivent être transformées avec l'inverse transposé de la matrice de vue du modèle. Donc, avec un normal , modelViewMatrix , la normale transformée estM n nMn

n=(M1)Tn

Lors de la transformation des objets, il est clair que les normales doivent être transformées en conséquence. Mais pourquoi, mathématiquement, est-ce la matrice de transformation correspondante?

Nero
la source
Si la matrice du modèle est constituée de translation, de rotation et d'échelle, vous n'avez pas besoin de faire de transposition inverse pour calculer la matrice normale. Divisez simplement la normale par une échelle au carré et multipliez par la matrice du modèle et nous avons terminé. Vous pouvez l'étendre à n'importe quelle matrice avec des axes perpendiculaires, calculez simplement l'échelle quadratique pour chaque axe de la matrice que vous utilisez à la place. J'ai écrit les détails dans mon blog: lxjk.github.io/2017/10/01/Stop-Using-Normal-Matrix.html
Eric

Réponses:

22

nx+d=0nMnMx+d=0x

d=d

nMx=nx

Je vais réécrire ceci avec les produits scalaires exprimés en notation matricielle (en considérant les vecteurs comme des matrices à 1 colonne):

nTMx=nTx

Maintenant, pour satisfaire cela pour tout , nous devons avoir:x

nTM=nT

Maintenant, résolvant pour en termes de , nnn

nT=nTM1n=(nTM1)Tn=(M1)Tn

xMMM

Il s'agit essentiellement d'une propriété du produit scalaire. Pour que le produit scalaire reste invariant lorsqu'une transformation est appliquée, les deux vecteurs en pointillés doivent se transformer de manière correspondante mais différente.

Mathématiquement, cela peut être décrit en disant que le vecteur normal n'est pas un vecteur ordinaire, mais une chose appelée covecteur (aka vecteur covariant, vecteur dual ou forme linéaire). Un covecteur est fondamentalement défini comme "une chose qui peut être parsemée d'un vecteur pour produire un scalaire invariant". Pour y parvenir, il doit se transformer en utilisant la transposition inverse de toute matrice opérant sur des vecteurs ordinaires. Cela vaut dans un certain nombre de dimensions.

Notez qu'en 3D spécifiquement, un bivecteur est similaire à un covecteur. Ils ne sont pas tout à fait les mêmes car ils ont des unités différentes: un covecteur a des unités de longueur inverse tandis qu'un bivecteur a des unités de longueur au carré (surface), donc ils se comportent différemment sous l'échelle. Cependant, ils se transforment de la même manière en ce qui concerne leur orientation, ce qui est important pour les normales. Nous ne nous soucions généralement pas de l'ampleur d'une normale (nous les normalisons toujours de toute façon à la longueur unitaire), nous n'avons donc généralement pas besoin de nous soucier de la différence entre un bivecteur et un covecteur.

Nathan Reed
la source
2
explication impressionnante. cependant un peu rapide sur 2 points, un peu plus de détails seraient appréciés: 1. comment passer des produits scalaires aux produits matriciels? 2. entre la ligne 2 et 3 de la dernière section citée, ce qui se passe (n est déplacé de gauche à droite un peu comme par magie)
v.oddou
4
1. (a ^ T) b est identique au point (a, b) si a et b sont des matrices de colonnes de même dimension. Essayez les mathématiques par vous-même! 2. (AB) ^ T = (B ^ T) (A ^ T), et (A ^ T) ^ T = A Pour plus d'identités matricielles, consultez The Matrix Cookbook
Mokosha
3
@ v.oddou Yep, Mokosha a raison. Le produit scalaire peut être exprimé en multipliant une matrice 1 × n (vecteur ligne) par une matrice × 1 (vecteur colonne); le résultat est une matrice 1 × 1 dont le composant unique est le produit scalaire. La transposition d'un vecteur colonne est un vecteur ligne, nous pouvons donc écrire a · b comme a ^ T b. Pour la deuxième question, transposer un produit de matrices revient à transposer les facteurs individuels et à inverser leur ordre.
Nathan Reed
parfait, tout est clair sans problème maintenant. merci à tous les deux.
v.oddou
@NathanReed (Mon Dieu, cela me ramène aux premiers jours de PowerVR où nous avons modélisé la plupart des choses avec des avions). Il peut également être utile de mentionner que, à des fins d'optimisation, si vous avez une matrice Mr qui ne contient que des rotations, (c'est-à-dire est orthogonale), alors Inverse ( Mr ) = Transpose ( Mr ), et donc Trans (Inverse ( Mr ) = _ Mr_. Vous pouvez également prendre des raccourcis avec la partie traduction et si vous savez que la mise à l'échelle est uniforme. FWIW dans la bibliothèque graphique SGL PowerVR, nous avons utilisé pour garder les booléens pour suivre si une matrice de transformation avait ces propriétés pour réduire les coûts avec les transformations normales.
Simon F
6

C'est tout simplement parce que les normales ne sont pas vraiment des vecteurs! Ils sont créés par des produits croisés, ce qui donne des bivecteurs et non des vecteurs. L'algèbre fonctionne très différemment pour ces coordonnées, et la transformation géométrique n'est qu'une opération qui se comporte différemment.

Une excellente ressource pour en savoir plus à ce sujet est la présentation d'Eric Lengyel sur Grassman Algebra .

ap_
la source
Les normales sont également des pseudovecteurs. En règle générale et en règle générale, tout ce qui résulte d'un produit croisé (par exemple les avions) sera transformé de la même manière.
Matthias