Archiv verlassen und diese Seite im Standarddesign anzeigen : Normalentransformation Vertex Shader
Hallo zusammen,
ich weiß nicht so genau, ob ich hier richtig bin. Aber ich versuche es mal.
Habe eine Frage zu Vertex Shadern und zwar bekommen die unter anderm ja auch Normalen übergeben.
Was ist den genau mit der Normalentransformation und Normalisierung gemeint?
Wie werden sie den transformiert und wie sieht das genau aus?
Grüße Luna
Neomi
2007-02-25, 13:56:42
Normalenvektoren haben keine Position, sondern nur eine Richtung. Deshalb können sie nicht im Raum verschoben werden und benötigen eine eigene Transformation. Die Normalisierung bzw. Normierung teilt alle Komponenten eines Vektors durch die Länge des Vektors. Dadurch hat der resultierende Vektor dann eine Länge von exakt 1, was für viele Berechnungen wichtig ist.
Ja aber wie genau sieht diese Transformation aus. Hat das irgendwas mit transponierten Inversen zu tun?
mickii
2007-02-25, 15:44:34
sind 3 dot3 fuer die normalen, und ein normalize beim normalisieren. naechste frage
Spasstiger
2007-02-25, 16:12:26
Ja aber wie genau sieht diese Transformation aus. Hat das irgendwas mit transponierten Inversen zu tun?
Bei der Normalisierung werden die Werte einach durch den Betrag des Vektors geteilt, so dass sich als neuer Betrag 1 ergibt.
EDIT: Vielleicht hilft das weiter: http://www.opengl.org/documentation/specs/version1.1/glspec1.1/node26.html
tokugawa
2007-02-25, 19:24:31
Ja aber wie genau sieht diese Transformation aus. Hat das irgendwas mit transponierten Inversen zu tun?
Ja. Genau genommen dürfen die Normalen nicht mit der normalen Transformationsmatrix (bzw. deren 3x3-Anteil) multipliziert werden, sondern mit der inversen transponierten.
Einen Unterschied macht das aber nur bei bestimmten Transformationen wie etwa nicht-uniformen Skalierungen.
Normalisierung ist wieder was eigenes, und heißt nur dass der Vektor auf einen "Einheitsvektor" gebracht wird, sprich, auf einen Vektor derselben Richtung mit Länge 1.
Ein guter Absatz dazu findet sich auf http://www.cg.tuwien.ac.at/courses/CG/LU/Beispiel3.html
Um im 5. Beispiel korrekte Beleuchtung zu ermöglichen, müssen spätestens dort auch die Normalvektoren richtig transformiert werden. Es empfiehlt sich jedoch, dies jetzt (oder im nächsten Beispiel) schon zu tun.
Die Transformationen von Normalvektoren ist allerdings im Fall von nicht uniformen Skalierungen nicht trivial, deshalb hier die richtige Erklärung:
Normalvektoren dürfen nicht mit der Transformationsmatrix multipliziert werden, sondern müssen mit ihrer transponierten Inversen multipliziert werden. Wenn also M die aktuelle Transformationsmatrix ist, dann ist (' steht für transponieren, _inv für die Inverse)
n_neu = (M_inv' * n)
Da in der Angabe aber sowieso eine eigene Matrix verwendet wird, um die Normalvektoren zu transformieren, und diese auch bei jeder Transformation aktualisiert wird, läßt sich das Problem leicht lösen:
In "CG1Object::scale(x,y,z)" muß transformNormalsMatrix einfach mit der inversen Skalierung multipliziert werden, also "modelMatrixVector.scale(1/x, 1/y, 1/z);", während die Punkt-Transformationsmatrix wie gewohnt mit der eigentlichen Skalierung transformiert wird ("modelMatrixPoint.scale(x,y,z);"). Bei den Viewing Matrizen in CG1Camera muß das nicht berücksichtigt werden, da wir hier ja keine Skalierung verwenden.
Zur Erklärung:
Der Normalvektor n ist dadurch definiert, daß sein inneres Produkt mit einem Tangentialvektor t im Oberflächenpunkt gleich Null ist, also: n dot t = 0. (dot steht fuer das dot-product). Nun gilt: t dot n = t' * n (Definition des inneren Produkts!). Wenn wir t mit M transformieren, also t_neu = M*t, dann suchen wir einen Vektor n_neu, für den wieder gilt: t_neu dot n_neu = 0. Setzt man für n_neu = M_inv'*n, dann gilt:
t_neu dot n_neu = (M*t)' * (M_inv'*n) = t'*M'*M_inv'*n = t'*(M_inv*M)'*n = t'*n = 0.
Dabei haben wir nur benutzt, dass (A*B)' = B'*A', und M*M_inv die Einheitsmatrix ist.
Bei der Rotation muß man das übrigens deswegen nicht berücksichtigen, weil für jede Rotationsmatrix die transponierte Inverse gleich der Rotationsmatrix selbst ist, also gilt: R = R_inv', wie man sich leicht anhand der einfachen Achsenrotationsmatrizen überlegen kann!
vBulletin®, Copyright ©2000-2025, Jelsoft Enterprises Ltd.