Erste Schritte mit der Rasterungsphase
In diesem Abschnitt wird das Festlegen des Viewports, des Scissors-Rechtecks, des Rasterungszustands und des Multisamplings beschrieben.
Festlegen des Viewports
Ein Viewport ordnet Vertexpositionen (im Clipraum) rendernden Zielpositionen zu. In diesem Schritt werden die 3D-Positionen in einen 2D-Raum skaliert. Ein Renderziel ist mit nach unten zeigenden Y-Achsen ausgerichtet. Dies erfordert, dass die Y-Koordinaten während der Viewportskala gedreht werden. Darüber hinaus werden die x- und y-Erweiterungen (Bereich der x- und y-Werte) skaliert, um die Viewportgröße gemäß den folgenden Formeln anzupassen:
X = (X + 1) * Viewport.Width * 0.5 + Viewport.TopLeftX
Y = (1 - Y) * Viewport.Height * 0.5 + Viewport.TopLeftY
Z = Viewport.MinDepth + Z * (Viewport.MaxDepth - Viewport.MinDepth)
Tutorial 1 erstellt einen Viewport 640 × 480 mithilfe von D3D11_VIEWPORT und durch Aufrufen von ID3D11DeviceContext::RSSetViewports.
D3D11_VIEWPORT vp[1];
vp[0].Width = 640.0f;
vp[0].Height = 480.0f;
vp[0].MinDepth = 0;
vp[0].MaxDepth = 1;
vp[0].TopLeftX = 0;
vp[0].TopLeftY = 0;
g_pd3dContext->RSSetViewports( 1, vp );
Die Viewportbeschreibung gibt die Größe des Viewports, den Bereich an, dem die Tiefe (mit MinDepth und MaxDepth) zugeordnet werden soll, und die Position der oberen linken Seite des Viewports. MinDepth muss kleiner oder gleich MaxDepth sein. Der Bereich für MinDepth und MaxDepth liegt zwischen 0,0 und einschließlich 1,0. Es ist üblich, dass der Viewport einem Renderziel zugeordnet wird, aber es ist nicht erforderlich. außerdem muss der Viewport nicht die gleiche Größe oder Position wie das Renderziel aufweisen.
Sie können ein Array von Viewports erstellen, aber nur eins kann auf eine primitive Ausgabe aus dem Geometry-Shader angewendet werden. Es kann jeweils nur ein Viewport aktiv festgelegt werden. Die Pipeline verwendet während der Rasterung einen Standard-Viewport (und ein Scissor-Rechteck, die im nächsten Abschnitt erläutert wird). Der Standardwert ist immer der erste Viewport (oder das Scherenrechteck) im Array. Um eine pro primitive Auswahl des Viewports im Geometrie-Shader auszuführen, geben Sie die ViewportArrayIndex-Semantik für die entsprechende GS-Ausgabekomponente in der GS-Ausgabesignaturdeklaration an.
Die maximale Anzahl von Viewports (und Scissor-Rechtecke), die gleichzeitig an die Rasterisierungsstufe gebunden werden können, beträgt 16 (durch D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE angegeben).
Festlegen des Scherenrechtecks
Ein Scherenrechteck bietet Ihnen eine weitere Möglichkeit, die Anzahl der Pixel zu reduzieren, die an die Ausgabefusionsphase gesendet werden. Pixel außerhalb des Scherenrechtecks werden verworfen. Die Größe des Scherenrechtecks wird in ganzen Zahlen angegeben. Nur ein Scherenrechteck (basierend auf ViewportArrayIndex in Systemwertsemantik) kann während der Rasterung auf ein Dreieck angewendet werden.
Verwenden Sie zum Aktivieren des Scherenrechtecks das ScissorEnable-Element (in D3D11_RASTERIZER_DESC1). Das Standardmäßige Scherenrechteck ist ein leeres Rechteck. Das heißt, alle Rect-Werte sind 0. Anders ausgedrückt: Wenn Sie das Scherenrechteck nicht einrichten und die Schere aktiviert ist, senden Sie keine Pixel an die Ausgabe-Merger-Phase. Das häufigste Setup besteht darin, das Scherenrechteck auf die Größe des Viewports zu initialisieren.
Um ein Array von Scherenrechtecken auf das Gerät festzulegen, rufen Sie ID3D11DeviceContext::RSSetScissorRects mit D3D11_RECT auf.
D3D11_RECT rects[1];
rects[0].left = 0;
rects[0].right = 640;
rects[0].top = 0;
rects[0].bottom = 480;
g_pd3dContext->RSSetScissorRects( 1, rects );
Diese Methode akzeptiert zwei Parameter: (1) die Anzahl der Rechtecke im Array und (2) ein Array von Rechtecken.
Die Pipeline verwendet während der Rasterung einen Standardmäßigen Scissor-Rechteckindex (der Standardwert ist ein Rechteck ohne Größe mit deaktiviertem Clipping). Um dies zu überschreiben, geben Sie die SV_ViewportArrayIndex Semantik zu einer GS-Ausgabekomponente in der GS-Ausgabesignaturdeklaration an. Dadurch markiert die GS-Phase diese GS-Ausgabekomponente als systemgenerierte Komponente mit dieser Semantik. Die Rasterisierungsphase erkennt diese Semantik und verwendet den Parameter, dem sie als Scherenrechteckindex angefügt ist, um auf das Array der Scherenrechtecke zuzugreifen. Vergessen Sie nicht, die Rasterisierphase anzufordern, das von Ihnen definierte Scherenrechteck zu verwenden, indem Sie den ScissorEnable-Wert in der Rasterizerbeschreibung aktivieren, bevor Sie das Rasterizerobjekt erstellen.
Festlegen des Rasterisierungsstatus
Ab Direct3D 10 wird der Rasterisierungszustand in einem Rasterisierzustandsobjekt gekapselt. Sie können bis zu 4096 Rasterizerstatusobjekte erstellen, die dann auf das Gerät festgelegt werden können, indem Sie ein Handle an das Zustandsobjekt übergeben.
Verwenden Sie ID3D11Device1::CreateRasterizerState1 , um ein Rasterizerstatusobjekt aus einer Rasterizerbeschreibung zu erstellen (siehe D3D11_RASTERIZER_DESC1).
ID3D11RasterizerState1 * g_pRasterState;
D3D11_RASTERIZER_DESC1 rasterizerState;
rasterizerState.FillMode = D3D11_FILL_SOLID;
rasterizerState.CullMode = D3D11_CULL_FRONT;
rasterizerState.FrontCounterClockwise = true;
rasterizerState.DepthBias = false;
rasterizerState.DepthBiasClamp = 0;
rasterizerState.SlopeScaledDepthBias = 0;
rasterizerState.DepthClipEnable = true;
rasterizerState.ScissorEnable = true;
rasterizerState.MultisampleEnable = false;
rasterizerState.AntialiasedLineEnable = false;
rasterizerState.ForcedSampleCount = 0;
g_pd3dDevice->CreateRasterizerState1( &rasterizerState, &g_pRasterState );
Mit diesem Beispielsatz von Zustand wird möglicherweise die einfachste Rasterungseinrichtung erreicht:
- Volltonfüllmodus
- Rückflächen herauszudullieren oder zu entfernen; Angenommen, gegen den Uhrzeigersinn Wickelreihenfolge für Grundtypen
- Deaktivieren der Tiefenverzerrung, aber Aktivieren der Tiefenpufferung und Aktivieren des Scherenrechtecks
- Deaktivieren von Multisampling und Zeilen-Antialiasing
Darüber hinaus umfassen die grundlegenden Rasterisiervorgänge immer Folgendes: Ausschneiden (zum Ansichts frustum), Perspektivteilung und Viewportskalierung. Legen Sie nach dem erfolgreichen Erstellen des Rasterizerzustandsobjekts das Gerät wie folgt fest:
g_pd3dContext->RSSetState(g_pRasterState);
Multisampling
Multisampling-Beispiele für einige oder alle Komponenten eines Bilds mit einer höheren Auflösung (gefolgt von Downsampling auf die ursprüngliche Auflösung), um die sichtbarste Form von Aliasing zu reduzieren, die durch das Zeichnen von Polygonkanten verursacht wird. Obwohl Multisampling Subpixelbeispiele erfordert, implementieren moderne GPU-Instanzen Multisampling, sodass ein Pixel-Shader einmal pro Pixel ausgeführt wird. Dies bietet einen akzeptablen Kompromiss zwischen der Leistung (insbesondere in einer GPU-gebundenen Anwendung) und dem Antialiasing des endgültigen Images.
Um Multisampling zu verwenden, legen Sie das Feld aktivieren in der Rasterungsbeschreibung fest, erstellen sie ein Multisampled-Renderziel, und lesen Sie entweder das Renderziel mit einem Shader, um die Beispiele in eine einzelne Pixelfarbe aufzulösen, oder rufen Sie ID3D11DeviceContext::ResolveSubresource auf, um die Beispiele mithilfe des Video-Karte aufzulösen. Das häufigste Szenario ist das Zeichnen auf ein oder mehrere Renderziele mit mehreren Stempeln.
Multisampling ist unabhängig davon, ob eine Beispielmaske verwendet wird, alpha-to-coverage aktiviert ist oder Schablonenvorgänge (die immer pro Beispiel ausgeführt werden).
Tiefentests sind durch Multisampling betroffen:
- Wenn Multisampling aktiviert ist, wird die Tiefe pro Stichprobe interpoliert, und der Tiefen-/Schablonentest wird pro Stichprobe durchgeführt. Die Ausgabefarbe des Pixel-Shaders wird für alle übergebenen Beispiele dupliziert. Wenn der Pixel-Shader die Tiefe ausgibt, wird der Tiefenwert für alle Beispiele dupliziert (obwohl in diesem Szenario der Nutzen des Multisamplings verloren geht).
- Wenn multisampling deaktiviert ist, werden die Tiefen-/Schablonentests weiterhin pro Stichprobe durchgeführt, aber die Tiefe wird nicht pro Stichprobe interpoliert.
Es gibt keine Einschränkungen für das Mischen von Multisampled- und Nicht-Multisampled-Renderings innerhalb eines einzelnen Renderziels. Wenn Sie Multisampling aktivieren und zeichnen für ein Nicht-Multisampled-Renderziel verwenden, erzeugen Sie das gleiche Ergebnis, als wäre Multisampling nicht aktiviert. Die Stichprobenerstellung erfolgt mit einem einzelnen Beispiel pro Pixel.
Zugehörige Themen