it-swarm.com.de

Warum werden Normalen mit der Transponierten Umkehrung der Modelview-Matrix umgesetzt?

Ich arbeite an einigen Shadern und muss Normalen umwandeln. 

Ich habe in einigen Tutorials gelesen, wie Sie Normalen umwandeln, indem Sie multiplizieren Sie sie mit der Transponierten des Inversen der Modelview-Matrix . Aber ich kann keine Erklärung finden, warum das so ist und was ist die Logik dahinter?

37
user1796942

Schauen Sie sich dieses Tutorial an:

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

Sie können sich vorstellen, dass, wenn die Oberfläche einer Kugel sich ausdehnt (also die Kugel entlang einer Achse oder etwas Ähnlichem skaliert wird), die Normalen dieser Oberfläche sich alle zueinander "beugen". Es stellt sich heraus, dass Sie die auf die Normalen angewendete Skala invertieren müssen, um dies zu erreichen. Dies ist dasselbe wie das Transformieren mit der Inverse Transpose Matrix. Der Link oben zeigt, wie man daraus die inverse transponierte Matrix ableiten kann.

Beachten Sie auch, dass Sie die ursprüngliche Matrix bei normaler Skalierung einfach als normale Matrix übergeben können. Stellen Sie sich vor, dass die gleiche Kugel entlang aller Achsen gleichmäßig skaliert wird. Die Oberfläche wird sich weder dehnen oder verbiegen noch die Normalen.

25
Invalid

Sie ergibt sich aus der Definition eines Normalen.

Angenommen, Sie haben den Normalen N und einen Vektor V, einen Tangentenvektor an derselben Position auf dem Objekt wie der Normalzustand. Dann per Definition N·V = 0.

Tangentialvektoren laufen in dieselbe Richtung wie die Oberfläche eines Objekts. Wenn Ihre Oberfläche eben ist, dann ist die Tangente die Differenz zwischen zwei identifizierbaren Punkten auf dem Objekt. Wenn also V = Q - R, wo Q und R Punkte auf der Oberfläche sind, dann, wenn Sie das Objekt mit B transformieren:

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

Die gleiche Logik gilt für nichtplanare Oberflächen unter Berücksichtigung von Grenzwerten.

Angenommen, Sie möchten das Modell mit der Matrix B transformieren. B wird also auf die Geometrie angewendet. Um herauszufinden, was Sie mit den Normalen tun müssen, die Sie für die Matrix lösen müssen, A, so dass:

(AN)·(BV) = 0

Um das explizite Punktprodukt zu eliminieren, verwandeln Sie das in eine Zeile oder eine Spalte.

[tranpose(AN)](BV) = 0

Ziehen Sie die Transpose nach außen, entfernen Sie die Klammern:

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

Das ist also "die Transponierung des Normalen" [product with] "die Transponierung der bekannten Transformationsmatrix" [product with] "die Transformation, die wir für" [product with] "lösen, den Vektor auf der Oberfläche des Modells" = 0

Wir haben jedoch mit der Angabe von transpose(N)*V = 0 begonnen, da das Gleiche ist wie mit N·V = 0. Um unsere Einschränkungen zu erfüllen, brauchen wir den mittleren Teil des Ausdrucks - transpose(A)*B -, um wegzugehen.

Daraus können wir folgern:

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

Mein Lieblingsbeweis ist unten, wobei N die Normalzahl und V ein Tangentenvektor ist. Da sie senkrecht stehen, ist ihr Punktprodukt gleich Null. M ist eine beliebige 3x3 invertierbare Transformation (M-1 * M = I). N 'und V' sind die durch M transformierten Vektoren.

enter image description here

Um ein wenig Intuition zu erhalten, betrachten Sie die Scherumwandlung unten.

enter image description here

Beachten Sie, dass dies nicht für Tangentenvektoren gilt.

26
wcochran

Wenn die Modellmatrix aus Verschiebung, Rotation und Skalierung besteht, müssen Sie keine inverse Transponierung durchführen, um die normale Matrix zu berechnen. Teilen Sie einfach die Norm durch die Skalierung des Quadrats und multiplizieren Sie sie mit der Modellmatrix, und wir sind fertig. Sie können dies auf jede beliebige Matrix mit senkrechten Achsen erweitern. Berechnen Sie stattdessen einfach die quadratische Skalierung für jede Achse der verwendeten Matrix. 

Ich habe die Details in meinem Blog geschrieben: https://lxjk.github.io/2017/10/01/Stop-Using-Normal-Matrix.html

0
eric