Die Direct3D-Transformationspipeline
Dieser Artikel enthält eine technische Erläuterung für Direct3D-Anwendungsentwickler zum Festlegen der Parameter der Direct3D-Transformationspipeline durch die direkte Bearbeitung von Direct3D-Matrizen.
Übersicht
Direct3D verwendet drei Transformationen, um ihre 3D-Modellkoordinaten in Pixelkoordinaten (Bildschirmraum) zu ändern. Diese Transformationen sind Welttransformationen, Sichttransformationen und Projektionstransformationen.
Die Welttransformation steuert, wie Modellkoordinaten in Weltkoordinaten umgewandelt werden. Die Welttransformation kann Übersetzungen, Drehungen und Skalierungen umfassen, gilt aber nicht für Lichter. Weitere Informationen zum Arbeiten mit Welttransformationen finden Sie unter World Transform.
Die Ansichtstransformation steuert den Übergang von Weltkoordinaten in "Kameraraum" und bestimmt die Kameraposition in der Welt. Ein Beispiel für die Arbeit mit Ansichtstransformationen finden Sie unter Ansichtstransformation.
Die Projektionstransformation ändert die Geometrie vom Kameraraum in einen "Clipraum" und wendet perspektivische Verzerrungen an. Der Begriff "Clipspace" bezieht sich darauf, wie die Geometrie während dieser Transformation auf das Ansichtsvolume gekappt wird. Ein Beispiel für die Arbeit mit Projektionstransformationen finden Sie unter Projektionstransformation.
Schließlich wird die Geometrie im Clipbereich in Pixelkoordinaten (Bildschirmbereich) umgewandelt. Diese Transformation wird durch die Viewporteinstellungen gesteuert.
Das Beschneiden und Transformieren von Scheitelpunkten muss im homogenen Raum erfolgen (einfach gesagt, in dem das Koordinatensystem ein viertes Element enthält), aber das Endergebnis für die meisten Anwendungen müssen nicht homogene dreidimensionale (3D)-Koordinaten sein, die im "Bildschirmraum" definiert sind. Dies bedeutet, dass sowohl die Eingabevertices als auch das Clippingvolumen in einen homogenen Raum übersetzt werden müssen, um das Clipping durchzuführen, und dann wieder in einen nicht homogenen Raum übersetzt werden, der angezeigt werden soll.
Die drei Direct3D-Transformationen– Welt-, Ansichts- und Projektionstransformationen – werden durch Direct3D-Matrizen definiert. Eine Direct3D-Matrix ist eine homogene 4x4-Matrix, die durch eine D3DMATRIX-Struktur definiert wird. Obwohl Direct3D-Matrizen keine Standardobjekte sind – sie werden nicht durch eine COM-Schnittstelle dargestellt –, können Sie sie wie jedes andere Direct3D-Objekt erstellen und festlegen. Weitere Informationen zu Direct3D-Matrizen finden Sie unter Transformationen.
Die Transformationspipeline
Wenn ein Scheitelpunkt in der Modellkoordinate von Pm = (Xm, Ym, Zm, 1) angegeben wird, werden die in der folgenden Abbildung gezeigten Transformationen auf die Berechnung der Bildschirmkoordinaten Ps = (Xs, Ys, Zs, Ws) angewendet.
Im Folgenden finden Sie Beschreibungen der Phasen, die in der vorherigen Abbildung dargestellt sind:
Die Weltmatrix Mworld transformiert Scheitelpunkte aus dem Modellraum in den Weltraum. Diese Matrix wird wie folgt festgelegt:
d3dDevice->SetTransform (D3DTRANSFORMSTATE_WORLD, matrix address)
Bei der Direct3D-Implementierung wird davon ausgegangen, dass die letzte Spalte dieser Matrix (0, 0, 0, 1) lautet. Es wird kein Fehler zurückgegeben, wenn der Benutzer eine Matrix mit einer anderen letzten Spalte angibt, aber die Beleuchtung und der Nebel sind falsch.
Ansichtsmatrix Mview transformiert Scheitelpunkte aus dem Weltraum in den Kamerabereich. Diese Matrix wird wie folgt festgelegt:
d3dDevice->SetTransform (D3DTRANSFORMSTATE_VIEW, matrix address)
Bei der Direct3D-Implementierung wird davon ausgegangen, dass die letzte Spalte dieser Matrix (0, 0, 0, 1) lautet. Es wird kein Fehler zurückgegeben, wenn der Benutzer eine Matrix mit einer anderen letzten Spalte angibt, aber die Beleuchtung und der Nebel sind falsch.
Projektionsmatrix Mproj transformiert Scheitelpunkte aus dem Kameraraum in den Projektionsraum. Diese Matrix wird wie folgt festgelegt:
d3dDevice->SetTransform (D3DTRANSFORMSTATE_PROJECTION, matrix address)
Die letzte Spalte der Projektionsmatrix sollte (0, 0, 1, 0) oder (0, 0, a, 0) für die richtigen Nebel- und Lichteffekte sein; Das Formular (0, 0, 1, 0) wird bevorzugt.
Das Clippingvolumen für alle Punkte Xp = (Xp, Yp, Zp, Wp) im Projektionsraum ist definiert wie folgt:
-Wp < Xp <= Wp -Wp < Yp <= Wp 0 < Zp <= Wp
Alle Punkte, die diese Formeln nicht erfüllen, werden abgeschnitten.
Wenn ein Ansichtsvolume wie folgt definiert ist:
- Bildschirmfensterbreite im Kamerabereich in der Nähe der Clippingebene
- Höhe des Sh-Screen-Fensters im Kamerabereich in der Nähe der Clippingebene
- Zn-Abstand zur nahen Clippingebene entlang der Z-Achsen im Kameraraum
- Zf-Abstand zur fernen Clippingebene entlang der Z-Achsen im Kameraraum
dann könnte eine perspektivische Projektionsmatrix wie folgt geschrieben werden:
wobei Mij Mitglieder von Mproj sind.
Für die orthogonale Projektion haben wir:
Direct3D geht davon aus, dass die Matrix für die Perspektivprojektion folgende Form hat:
Wenn die Perspektivprojektionsmatrix nicht diese Form aufweist, gibt es einige Artefakte. Beispielsweise funktioniert Tabellennebel nicht.
Direct3D ermöglicht es dem Benutzer, die Cliplautstärke wie folgt zu ändern:
Dies kann wie folgt umgeschrieben werden:
Dabei gilt Folgendes:
Cx, Cy - dvClipX, dvClipY from D3DVIEWPORT9 Cw, Ch - dvClipWidth, dvClipHeight from D3DVIEWPORT9 Zmin, Zmax - dvMinZ, dvMaxZ from D3DVIEWPORT9
Diese Transformation kann eine höhere Genauigkeit bieten und entspricht dem Skalieren und Verschieben des Clippingvolumens.
Die entsprechende Mclip-Matrix lautet:
Ein Scheitelpunkt wird wie folgt transformiert:
dvClipWidth = 2 dvClipHeight = 2 dvClipX = -1 dvClipY = 1 dvMinZ = 0 dvMaxZ = 1
Wenn Sie die Cliplautstärke nicht skalieren möchten, können Sie viewport-Parameter auf Standardwerte festlegen:
(Xc, Yc, Zc, Wc) = (Xp, Yp, Zp, Wp) * Mclip
Die Clippingphase ist optional, wenn der Benutzer das D3DDP_DONOTCLIP-Flag in einem DrawPrimitive-Aufruf angibt. In diesem Fall können alle Matrizen (einschließlich Mvs) kombiniert werden.
Die Viewport-Skalierungsmatrix Mvs skaliert Koordinaten innerhalb des Viewportfensters und kippt die Y-Achse von oben nach unten:
Dabei gilt Folgendes:
dwX, dwY - viewport offsets in pixels from D3DVIEWPORT9 dwWidth, dwHeight - viewport width and height in pixels from D3DVIEWPORT9
Schließlich werden bildschirmkoordinaten berechnet und an den Rasterizer übergeben:
Tipps zur Verwendung
Hier finden Sie einige Tipps zur Verwendung der Direct3D-Transformationspipeline:
Die letzte Spalte der Welt- und Ansichtsmatrizen sollte (0, 0, 0, 1) sein, oder die Beleuchtung ist falsch.
Legen Sie die Viewportparameter fest, um eine Mclip-Identitätsmatrix zu erstellen, es sei denn, Sie wissen genau, wofür sie benötigt wird.
dvClipWidth = 2 dvClipHeight = 2 dvClipX = -1 dvClipY = 1 dvMinZ = 0 dvMaxZ = 1