Was macht die Grafikkarte mit dem vierten Element eines Vektors als Endposition?

25

Aus dieser Frage geht hervor, dass Sie einen Positionsvektor mit vier Elementen wünschen, da es einfacher ist, seine Position mit der Matrixmultiplikation zu ändern.

Für sich genommen würde dies bedeuten, dass das vierte Element einfach ignoriert werden sollte, wenn es als Darstellung eines 3D-Punkts betrachtet wird (keine Transformation vorausgesetzt), aber ich weiß, dass dies nicht zutrifft, wenn ich der GPU einen Vektor 4 bereitstelle, wenn der vierte Element ist nicht eins, es wird nicht gerendert - warum?

Welche Bedeutung hat das vierte Element im Rasterizer?

EDIT : Bei der Überprüfung war diese Frage etwas schlecht formuliert; Im zweiten Absatz wäre es genauer zu sagen: "Wenn der Wert des vierten Elements nicht innerhalb eines bestimmten Bereichs liegt, wird es nicht 'richtig' / 'wie erwartet' gerendert."

sebf
quelle
Gibt ein Vektor4 mit Koordinaten (x, y, z, 0.5) nicht die gleichen Ergebnisse wie der Vektor4 mit Koordinaten (2x, 2y, 2z, 1)?
FxIII
@FxIII, ich konnte das nicht genau reproduzieren, aber Sie haben Recht, das war eine falsche pauschale Aussage in meinem ursprünglichen Beitrag, nach einigen weiteren Experimenten habe ich sie aktualisiert.
2.

Antworten:

23

Die vierte Komponente ist ein Trick, um die perspektivische Projektion im Auge zu behalten. Wenn Sie eine perspektivische Projektion durchführen, möchten Sie durch z dividieren: x '= x / z, y' = y / z, aber dies ist keine Operation, die durch eine 3x3-Matrix implementiert werden kann, die auf einem Vektor von x arbeitet. y, z. Der zum Standard gewordene Trick besteht darin, eine vierte Koordinate w anzufügen und zu deklarieren, dass x, y, z nach dem Anwenden aller Transformationen und vor dem Rastern immer durch w geteilt werden.

Die perspektivische Projektion wird dann durch eine Matrix erreicht, die z in w verschiebt, so dass Sie am Ende durch z dividieren. Es gibt Ihnen aber auch die Flexibilität, w = 1.0 zu lassen, wenn Sie keine Division durchführen möchten. Zum Beispiel, wenn Sie nur eine parallele Projektion oder eine Drehung oder was auch immer wollen.

Die Möglichkeit, Positionen mit w = 1 und Richtungen mit w = 0 zu codieren und die vierte Zeile / Spalte einer Matrix für die Übersetzung zu verwenden, ist ein netter Nebeneffekt, aber nicht der Hauptgrund für das Anhängen von w. Man könnte affine Transformationen (eine 3 × 3-Matrix plus einen 3-Komponenten-Translationsvektor) verwenden, um eine Translation zu erreichen, ohne dass dies in Sicht wäre. (Man müsste nachverfolgen, was eine Position und was eine Richtung ist, und verschiedene Transformationsfunktionen auf jede anwenden. Das ist ein bisschen unpraktisch, aber nicht wirklich eine große Sache.)

(Übrigens werden mit w erweiterte Vektoren mathematisch als homogene Koordinaten bezeichnet und befinden sich an einem Ort, der als projektiver Raum bezeichnet wird . Sie müssen jedoch nicht die höhere Mathematik verstehen, um 3D-Grafiken zu erstellen.)

Nathan Reed
quelle
Es ist wiederum leicht falsch, in diesen Begriffen von Vektoren und Punkten zu sprechen, da es einen Isomorphismus zwischen Punkten und Vektoren gibt (der Punkt und der Vektor, die den Ursprung zu diesem Punkt verschieben, sind dieselbe Einheit). Wäre richtiger, über Punkte / Vektoren (w! = 0) und (projektive) Richtungen (w = 0) zu sprechen. Auf jeden Fall ist der Missbrauch des Begriffs "Vektor" in der Sprache der 3d-Bibliotheken ein recht konsolidierter Standard.
FxIII
@FxIII: Korrigiert. Es war verwirrend, "Vektor" im üblichen mathematischen Sinne und als Synonym für "Richtung" im selben Beitrag zu verwenden.
Nicol Bolas
@FxIII und Nicol Bolas: Da bin ich anderer Meinung. Sie codieren tatsächlich Vektoren als w = 0 - einschließlich sowohl Vektoren, die nur eine Richtung darstellen, als auch tatsächlicher Vektoren, bei denen die Länge wichtig ist. Beispielsweise können Sie den Winkelgeschwindigkeitsvektor (Richtung = Rotationsachse, Länge = Geschwindigkeit) eines Objekts mithilfe der Objektmatrix zwischen dem lokalen Raum und dem Weltraum transformieren. Sie möchten nicht, dass die Winkelgeschwindigkeit der Übersetzung des Objekts hinzugefügt wird. Sie möchten nur, dass es gedreht wird. Also setzen Sie w = 0. Ich sehe das Problem nicht?
Nathan Reed
@ NathanReed Ich hoffe, dass mein Beitrag dazu beiträgt, diesen Punkt zu klären. Ein großer Teil meines Beitrags besteht jedoch aus Definitionen und dem Missbrauch des Begriffs Vektor sowie dem Primat der linearen Algebra gegenüber der Standardterminologie der 3D-Bibliothek. Natürlich sind beide umstritten, da jede Definition und jeder
Vorranganspruch
@ Nathan, ich kann jetzt klar erkennen, wozu das vierte Element dient und wie die darin enthaltenen Informationen vom Rasterizer verwendet werden. Vielen Dank!
2.
10

Um auf den entsprechenden Kommentar von Natan zu antworten, habe ich einige Überlegungen angestellt, die nützlich sein können, um zu verstehen, was wirklich passiert, wenn Sie Vektoren im affinen Raum verwenden, um 3D-Vektoren im euklidischen Standardraum darzustellen.

Zuerst werde ich einen Vektor aufrufen , der Koordinaten hat, so dass ein Punkt und ein Vektor dasselbe Gebilde sind. Sie können einen Vektor als Differenz von zwei Punkten sehen: V = B - A ; V bewegt A in B , da A + V = A + B - A = B . Wenn Sie A = 0 (den Ursprung) setzen, erhalten Sie V = B - 0 = B : den Punkt B und den Vektor, der 0 bewegtbis B sind dasselbe.

Ich werde "Vektor" nennen - in dem Sinne, wie er in den meisten 3D-Bibliotheken verwendet wird -, wenn ein Vektor des affinen Raums w = 0 hat.

Die Matrix wird verwendet, weil Sie damit eine lineare Funktion in einer kompakten / eleganten / effizienten Form darstellen können, aber lineare Funktionen haben den Hauptnachteil, dass der Ursprung nicht transformiert werden kann: F ( 0 ) = 0, wenn F linear sein soll ( Amog andere Sache solchen F (λ X ) = & lgr; F ( X ) und F ( A + B ) = F ( A ) + F ( B ))

Dies bedeutet, dass Sie keine Matrix erstellen können, die eine Übersetzung ausführt, da Sie den Vektor 0 niemals verschieben werden. Hier kommt der Affine Space ins Spiel . Der affine Raum fügt dem euklidischen Raum eine Dimension hinzu, sodass mit Skalierung und Rotation translantiert werden kann.

Der affine Raum ist ein projektiver Raum in dem Sinne, dass Sie eine Äquivalenzbeziehung zwischen affinen und euklidischen Vektoren aufbauen können, um sie zu verwechseln (wie wir es mit Poins und Vektoren getan haben). Alle affinen Vektoren, die mit der gleichen Richtung zum Ursprung projizieren, können als der gleiche euklidische Vektor angesehen werden.

Dies bedeutet, dass alle Vektoren, die die gleichen Proportionen in den Koordinaten haben, als äquivalent betrachtet werden können:

Mathematisch:

Gleichwertigkeit

dh jeder affine Vektor kann auf eine Canon-Version mit w = 1 reduziert werden (wir wählen aus jedem äquivalenten Vektor denjenigen aus, den wir am besten mögen).

Visuell (2D euklidisch - 3D affin):

visuelle Äquivalenz

daher der Mittelwert von "projektivem" Raum; Sie sollten beachten, dass hier der euklidische Raum 2D ist (der Cyan-Bereich)

Es gibt eine bestimmte Menge von affinen Vektoren, die (mit Leichtigkeit) nicht in ihre kanonische Version gebracht werden können, die auf der (Hyper-) Ebene w = 0 liegt.

Wir können es visuell zeigen:

Bildbeschreibung hier eingeben

Was Sie sehen (sollten), ist, dass, während w -> 0, der projizierte Vektor in den euklidischen Raum zum Unendlichen, aber zum Unendlichen in einer bestimmten Richtung geht .

Es ist nun klar, dass das Addieren von zwei Vektoren im projektiven Raum zu Problemen führen kann, wenn Sie den Summenvektor als projizierten Vektor im euklidischen Raum betrachten. Dies hängt an, weil Sie die W-Komponenten im affinen Raum summieren und dann auf den projizieren euklidische (Hyper-) Ebene.

Aus diesem Grund können Sie nur "Punkte" zu "Vektoren" summieren, da ein "Vektor" die w-Koordinate des "Punkts" nicht ändert. Dies gilt nur für "Punkte" mit w = 1:

Bildbeschreibung hier eingeben

Wie Sie sehen, ist der grüne Punkt derjenige, der erhalten wird, indem die zwei affinen Vektoren addiert werden, die den Cyan- "Punkt" und den V- "Vektor" darstellen . Wenn Sie jedoch V auf jeden affinen Vektor in einer vom Kanon verschiedenen Form anwenden , erhalten Sie ein falsches Ergebnis (der rote "" Punkt "").

Sie sehen, dass der affine Raum nicht transparent zur Beschreibung der Operation auf euklidischen Räumen verwendet werden kann und der Missbrauch des Begriffs "Vektor" unter der (strengen) Beschränkung von Berechnungssummen nur für kanonprojektive Vektoren Sinn macht .

Es ist durchaus vernünftig anzunehmen , dass die GPU annimmt, dass ein Vector4 w = 0 oder w = 1 haben muss, es sei denn, Sie wissen wirklich, was Sie tun.

FxIII
quelle
Es war sehr schwierig, eine Antwort auf diese Frage zu finden, da alle zum Verständnis beigetragen haben, wie die Beziehung der vierten Komponente verwendet wird und warum sie benötigt wird. Ihre Erklärung des euklidischen und affinen Raums ist sehr hilfreich, ich hätte es sicherlich nicht so verstanden, wie ich es jetzt ohne diesen Detaillierungsgrad tue. Vielen Dank!
2.
+1 für eine gute Erklärung (und Diagramme!) Des projektiven Raums. Der affine Raum und der projektive Raum sind jedoch nicht dasselbe (siehe die Wikipedia-Definition des affinen Raums). Ein guter Weg, dies zu sagen, ist vielleicht: Sowohl der projektive 3-Raum als auch der affine 3-Raum können in R ^ 4 eingebettet werden, aber die Einbettungen sind nicht ganz konsonant. Die Kodierung von Vektoren aus dem affinen Raum als w = 0 ist möglich und sinnvoll, aber aus projektiver Sicht nicht sinnvoll. Ebenso sind projektive Richtungen (Punkte im Unendlichen) aus affiner Sicht nicht aussagekräftig.
Nathan Reed
1

Nehmen Sie einen Vektor wie (x, y, z, w) an. Dieser Vektor hat 4 Komponenten x (x-Koordinate im Raum), y (y-Koordinate im Raum), z (z-Koordinate im Raum) und die interessante und mysteriöse w-Komponente. Tatsächlich arbeiten die meisten 3D-Spiele im 4D-Raum. Sie werden auch als homogener 4D-Raum bezeichnet. Es gibt einige offensichtliche Vorteile ->

1> Es hilft uns, Matrizen von Translation und Rotation in einer zu kombinieren. Aber Sie denken vielleicht, wozu es gut ist, wir könnten einfach die Translations- und Rotationsmatrix multiplizieren, und das ist es, aber es gibt nicht mehr w-Komponente in all unseren Vektoren. Wenn wir dann den 3D-Vektor (xyz) mit der kombinierten Translations- und Rotationsmatrix auf irgendeine Weise multiplizieren, skalieren wir die Werte unbewusst mit x, y oder z (so funktioniert die Matrixmultiplikation) Wahrscheinlich ist die Positionsmatrix (Übersetzungsteil der kombinierten Matrix) aufgrund der Skalierung beschädigt. Um dieses Problem zu beheben, wird der Vektor der vierten Komponente eingeführt, und diese Komponente des Vektors (w) enthält in 99% der Fälle den Wert 1,0. Diese vierte Komponente ermöglicht es uns nicht skalierte Positionswerte haben (Übersetzung). Die Matrix wird dargestellt als->

 [x y z w] [rx1 rx2 rx3 1]
           [ry1 ry2 ry3 1]
           [rz1 rz2 rz3 1]
           [px  py  pz  1]

und dann haben wir die einfache und doch mächtige Matrix. :)

2> Wir kopieren den z-Wert in der perspektivischen Projektionsphase in die w-Komponente und teilen das x, y damit. Auf diese Weise werden Objekte kürzer, wenn sie sich vom Bildschirm entfernen.

gamePro
quelle
Vielen Dank! Ich sehe immer mehr die Notwendigkeit, die vierte Komponente in einer wirklich nützlichen Darstellung einer Entität im 3D-Raum zu verwenden.
2.