Freigeben über


Tessellationsstufen

Die Direct3D 11-Laufzeit unterstützt drei neue Stufen, die tessellation implementieren, wodurch Oberflächen mit geringer Detaildetail-Unterteilung in detailreichere Grundtypen auf der GPU konvertiert werden. Tessellationskacheln (oder aufteilen) hochgeordnete Oberflächen in geeignete Strukturen zum Rendern.

Durch die Implementierung von Tessellation in der Hardware kann eine Grafikpipeline niedrigere Detailmodelle (niedrigere Polygonanzahl) auswerten und in höheren Details rendern. Während die Software-Tessellation durchgeführt werden kann, kann die von der Hardware implementierte Tessellation eine unglaubliche Menge visueller Details (einschließlich Unterstützung für die Verdrängungszuordnung) generieren, ohne die visuellen Details zu den Modellgrößen hinzuzufügen und die Aktualisierungsraten zu lähmen.

Vorteile der Tessellation

Tesselation:

  • Spart viel Arbeitsspeicher und Bandbreite, was es einer Anwendung ermöglicht, detailliertere Oberflächen aus Modellen mit niedriger Auflösung zu rendern. Die in der Direct3D 11-Pipeline implementierte Tessellationstechnik unterstützt auch die Verdrängungszuordnung, die atemberaubende Mengen an Oberflächendetails erzeugen kann.
  • Unterstützt skalierbare Renderingtechniken, z. B. fortlaufende oder ansichtsabhängige Detailebenen, die dynamisch berechnet werden können.
  • Verbessert die Leistung, indem teure Berechnungen mit niedrigerer Häufigkeit durchgeführt werden (Berechnungen für ein Modell mit niedrigeren Details). Dazu können Mischberechnungen unter Verwendung von Blendformen oder Morphzielen für realistische Animationen oder physikalische Berechnungen zur Kollisionserkennung oder Weichkörperdynamik gehören.

Die Direct3D 11-Pipeline implementiert Tessellation in hardware, wodurch die Arbeit von der CPU auf die GPU deaktiviert wird. Dies kann zu sehr großen Leistungsverbesserungen führen, wenn eine Anwendung eine große Anzahl von Morphzielen und/oder komplexeren Skinning-/Verformungsmodellen implementiert. Um auf die neuen Tessellationsfeatures zuzugreifen, müssen Sie sich über einige neue Pipelinephasen informieren.

Neue Pipelinephasen

Tessellation verwendet die GPU, um eine detailliertere Oberfläche aus einer Oberfläche zu berechnen, die aus Quad-Patches, Dreieckspatches oder Isolines erstellt wurde. Um die hochgeordnete Oberfläche anzunähern, wird jeder Patch in Dreiecke, Punkte oder Linien unter Verwendung von Tessellationsfaktoren unterteilt. Die Direct3D 11-Pipeline implementiert Tessellation mit drei neuen Pipelinestufen:

  • Hull-Shader Phase – Eine programmierbare Shaderphase, die einen Geometriepatch (und Patchkonstanten) erzeugt, der jedem Eingabepatch (Quad, Dreieck oder Linie) entspricht.
  • Tessellator-Phase – Eine Pipelinephase mit fester Funktion, die ein Samplingmuster der Domäne erstellt, das den Geometriepatch darstellt, und generiert eine Reihe kleinerer Objekte (Dreiecke, Punkte oder Linien), die diese Beispiele verbinden.
  • Domain-Shader Phase – Eine programmierbare Shaderstufe, die die Vertexposition berechnet, die den einzelnen Domänenbeispielen entspricht.

Im folgenden Diagramm werden die neuen Phasen der Direct3D 11-Pipeline hervorgehoben.

Diagramm der Direct3d 11-Pipeline, die die Hull-Shader-, Tessellator- und Domänen-Shaderphasen

Das folgende Diagramm zeigt die Entwicklung durch die Tessellationsphasen. Die Entwicklung beginnt mit der Unterteilungsoberfläche mit geringem Detail. Im nächsten Schritt wird der Eingabepatch mit dem entsprechenden Geometriepatch, Domänenbeispielen und Dreiecken hervorgehoben, die diese Beispiele verbinden. Die Entwicklung hebt schließlich die Scheitelpunkte hervor, die diesen Beispielen entsprechen.

Diagramm der Tessellationsentwicklung

Hull-Shader Phase

Ein Hull-Shader , der einmal pro Patch aufgerufen wird, transformiert Eingabesteuerungspunkte, die eine Oberflächen mit niedriger Reihenfolge in Kontrollpunkte definieren, die einen Patch bilden. Außerdem werden einige Patchberechnungen durchgeführt, um Daten für die Tessellationsstufe und die Domänenstufe bereitzustellen. Auf der einfachsten Black-Box-Ebene würde die Hull-Shader-Stufe etwa wie das folgende Diagramm aussehen.

Diagramm der Hull-Shader-Stufe

Ein Hull-Shader wird mit einer HLSL-Funktion implementiert und verfügt über die folgenden Eigenschaften:

  • Die Shadereingabe liegt zwischen 1 und 32 Kontrollpunkten.
  • Die Shaderausgabe liegt zwischen 1 und 32 Kontrollpunkten, unabhängig von der Anzahl der Tessellationsfaktoren. Die Steuerungspunkteausgabe eines Hull-Shaders kann von der Domänen-Shader-Stufe genutzt werden. Patchkonstantendaten können von einem Domänen-Shader genutzt werden. Tessellationsfaktoren können vom Domänen-Shader und der Tessellationsstufe genutzt werden.
  • Tessellationsfaktoren bestimmen, wie viel die einzelnen Patches unterteilt werden sollen.
  • Der Shader deklariert den Zustand, der für die Tessellatorstufe erforderlich ist. Dies umfasst Informationen wie die Anzahl der Kontrollpunkte, den Patch-Face-Typ und den Typ der Partitionierung, die beim Tessellieren verwendet werden soll. Diese Informationen werden in der Regel als Deklarationen am Anfang des Shadercodes angezeigt.
  • Wenn die Hull-Shader-Stufe einen Rand-Tessellationsfaktor auf = 0 oder NaN festlegt, wird der Patch gekullt. Daher kann die Tessellatorphase ausgeführt oder nicht ausgeführt werden, der Domänen-Shader wird nicht ausgeführt, und für diesen Patch wird keine sichtbare Ausgabe erstellt.

Auf einer tieferen Ebene arbeitet ein Hull-Shader tatsächlich in zwei Phasen: einer Kontrollpunktphase und einer Patchkonstantenphase, die parallel von der Hardware ausgeführt werden. Der HLSL-Compiler extrahiert den Parallelismus in einem Hull-Shader und codiert ihn in Bytecode, der die Hardware steuert.

  • Die Kontrollpunktphase arbeitet einmal für jeden Kontrollpunkt, liest die Kontrollpunkte für einen Patch und generiert einen Ausgabesteuerungspunkt (identifiziert durch eine ControlPointID).
  • Die Patchkonstantenphase arbeitet einmal pro Patch, um Edge-Tessellationsfaktoren und andere Patchkonstanten zu generieren. Intern können viele Patchkonstantenphasen gleichzeitig ausgeführt werden. Die Patchkonstantenphase verfügt über schreibgeschützten Zugriff auf alle Eingabe- und Ausgabesteuerungspunkte.

Hier ist ein Beispiel für einen Rumpf-Shader:

[patchsize(12)]
[patchconstantfunc(MyPatchConstantFunc)]
MyOutPoint main(uint Id : SV_ControlPointID,
     InputPatch<MyInPoint, 12> InPts)
{
     MyOutPoint result;
     
     ...
     
     result = TransformControlPoint( InPts[Id] );

     return result;
}

Ein Beispiel zum Erstellen eines Hull-Shaders finden Sie unter How To: Create a Hull Shader.

Tessellatorphase

Der Tessellator ist eine phase mit fester Funktion initialisiert, indem ein Hull-Shader an die Pipeline gebunden wird (siehe How To: Initialize the Tessellator Stage). Der Zweck der Tessellatorstufe besteht darin, eine Domäne (Quad, Tri oder Linie) in viele kleinere Objekte (Dreiecke, Punkte oder Linien) zu unterteilen. Die Tessellatorkachelt eine kanonische Domäne in einem normalisierten Koordinatensystem (Null-zu-1). Beispielsweise wird eine Quad-Domäne auf ein Einheitsquadeck tesselliert.

Der Tessellator wird einmal pro Patch mit den Tessellationsfaktoren (die angeben, wie fein die Domäne tesselliert wird) und den Typ der Partitionierung (der den Algorithmus angibt, der zum Aufschneiden eines Patches verwendet wird) ausgeführt, die aus der Hull-Shader-Stufe übergeben werden. Der Tessellator gibt uv-Koordinaten (und optional w) und die Oberflächentopologie in die Domänen-Shader-Stufe aus.

Intern arbeitet der Tessellator in zwei Phasen:

  • In der ersten Phase werden die Tessellationsfaktoren verarbeitet, Rundungsprobleme behoben, sehr kleine Faktoren behandelt, Faktoren reduziert und kombiniert, wobei 32-Bit-Gleitkommaarithmetik verwendet wird.
  • In der zweiten Phase werden Punkt- oder Topologielisten basierend auf dem ausgewählten Partitionstyp generiert. Dies ist die Kernaufgabe der Tessellatorphase und verwendet 16-Bit-Bruchzahlen mit Festkommaarithmetik. Festkommaarithmetik ermöglicht Hardwarebeschleunigung und gleichzeitig eine akzeptable Genauigkeit. Bei einem 64 Meter breiten Patch kann diese Genauigkeit beispielsweise Punkte in einer Auflösung von 2 mm platzieren.
Typ der Partitionierung Bereich
fractional_odd [1...63]
fractional_even TessFactor-Bereich: [2..64]
ganze Zahl TessFactor-Bereich: [1..64]
Pow2 TessFactor-Bereich: [1..64]

Domain-Shader Phase

Ein Domänen-Shader berechnet die Vertexposition eines unterteilten Punkts im Ausgabepatch. Ein Domänen-Shader wird einmal pro Ausgabepunkt der Tessellatorphase ausgeführt und verfügt über schreibgeschützten Zugriff auf die Tessellator-Ausgabe-UV-Koordinaten, den Hull-Shader-Ausgabepatch und die Hull-Shader-Ausgabepatchkonstanten, wie das folgende Diagramm zeigt.

Diagramm der Domänen-Shader-Stufe

Zu den Eigenschaften des Domänen-Shaders gehören:

  • Ein Domänen-Shader wird einmal pro Ausgabekoordinate aus der Tessellatorphase aufgerufen.
  • Ein Domänen-Shader verwendet Ausgabesteuerungspunkte aus der Hull-Shader-Stufe.
  • Ein Domänen-Shader gibt die Position eines Scheitelpunkts aus.
  • Eingaben sind die Hüllen-Shaderausgaben, einschließlich Kontrollpunkte, Patchkonstantendaten und Tessellationsfaktoren. Die Tessellationsfaktoren können die werte enthalten, die von der festen Funktion Tessellator verwendet werden, sowie die Rohwerte (z. B. vor dem Runden durch ganzzahlige Tessellation), die z. B. geomorphen.

Nach Abschluss des Domänen-Shaders wird die Tessellation abgeschlossen, und Pipelinedaten werden zur nächsten Pipelinephase (Geometrie-Shader, Pixelshader usw.) fortgesetzt. Ein Geometrie-Shader, der Grundtypen mit Adjacency erwartet (z. B. 6 Scheitelpunkte pro Dreieck), ist ungültig, wenn die Tessellation aktiv ist (dies führt zu einem nicht definierten Verhalten, über das sich die Debugebene beschwert).

Hier ist ein Beispiel für einen Domänen-Shader:

void main( out    MyDSOutput result, 
           float2 myInputUV : SV_DomainPoint, 
           MyDSInput DSInputs,
           OutputPatch<MyOutPoint, 12> ControlPts, 
           MyTessFactors tessFactors)
{
     ...

     result.Position = EvaluateSurfaceUV(ControlPoints, myInputUV);
}

APIs für die Initialisierung von Tessellationsstufen

Tessellation wird mit zwei neuen programmierbaren Shaderphasen implementiert: einem Hull-Shader und einem Domänen-Shader. Diese neuen Shaderstufen werden mit HLSL-Code programmiert, der im Shadermodell 5 definiert ist. Die neuen Shaderziele sind: hs_5_0 und ds_5_0. Wie alle programmierbaren Shaderphasen wird Code für die Hardware aus kompilierten Shadern extrahiert, die an die Laufzeit übergeben werden, wenn Shader mithilfe von APIs wie DSSetShader- und HSSetShader-an die Pipeline gebunden sind. Zuerst muss der Shader jedoch mithilfe von APIs wie CreateHullShader und CreateDomainShadererstellt werden.

Aktivieren Sie die Tessellation, indem Sie einen Hull-Shader erstellen und an die Hull-Shader-Stufe binden (dadurch wird automatisch die Tessellatorstufe eingerichtet). Um die endgültigen Vertexpositionen aus den tessellierten Patches zu generieren, müssen Sie auch einen Domänen-Shader erstellen und an die Domänen-Shader-Phase binden. Sobald die Tessellation aktiviert ist, müssen die Dateneingaben in die Eingabeassemblerphase Patchdaten sein. Das heißt, die Eingabeassemblertopologie muss eine Patchkonstantentopologie aus D3D11_PRIMITIVE_TOPOLOGY sein, die mit IASetPrimitiveTopology-festgelegt ist.

Um die Tessellation zu deaktivieren, legen Sie den Hull-Shader und den Domänen-Shader auf NULL-fest. Weder die Geometrie-Shader-Stufe noch die Streamausgabestufe können Hull-Shader-Ausgabesteuerungspunkte oder Patchdaten lesen.

Vorgehensweise:

Die Dokumentation enthält auch Beispiele für die Initialisierung der Tessellationsphasen.

Artikel Beschreibung
How To: Create a Hull Shader
Erstellen Sie einen Rumpf-Shader.
How To: Design a Hull Shader
Entwerfen Sie einen Rumpfshader.
How To: Initialize the Tessellator Stage
Initialisieren Sie die Tessellationsphase.
How To: Create a Domain Shader
Erstellen Sie einen Domänen-Shader.
How to: Design a Domain Shader
Erstellen Sie einen Domänen-Shader.

Grafikpipeline-