How To: Entwerfen eines Hüllen-Shaders
Ein Hüllen-Shader ist die erste von drei Phasen, die zusammenarbeiten, um das Mosaik zu implementieren (die anderen beiden Stufen sind der Mosaik und ein Domänen-Shader). In diesem Thema wird gezeigt, wie Sie einen Hüllen-Shader entwerfen.
Ein Hüllen-Shader erfordert zwei Funktionen: den Haupt-Hüllen-Shader und eine Patchkonst constant-Funktion. Der Hüllen-Shader implementiert Berechnungen an jedem Kontrollpunkt. Der Hüllen-Shader ruft auch die Patchkonst constant-Funktion auf, die Berechnungen für jeden Patch implementiert.
Nachdem Sie einen Hüllen-Shader entworfen haben, finden Sie weitere Informationen zum Erstellen eines Hüllen-Shaders unter How To: Create a Shader (Erstellen eines Hüllen-Shaders).
So entwerfen Sie einen Hüllen-Shader
Definieren Sie Ein- und Ausgabekontrollpunkte für den Hüllen-Shader.
// Input control point struct VS_CONTROL_POINT_OUTPUT { float3 vPosition : WORLDPOS; float2 vUV : TEXCOORD0; float3 vTangent : TANGENT; }; // Output control point struct BEZIER_CONTROL_POINT { float3 vPosition : BEZIERPOS; };Definieren von Ausgabepatchkonst konstanten Daten.
// Output patch constant data. struct HS_CONSTANT_DATA_OUTPUT { float Edges[4] : SV_TessFactor; float Inside[2] : SV_InsideTessFactor; float3 vTangent[4] : TANGENT; float2 vUV[4] : TEXCOORD; float3 vTanUCorner[4] : TANUCORNER; float3 vTanVCorner[4] : TANVCORNER; float4 vCWts : TANWEIGHTS; };Für eine Quad-Domäne definiert SV _ TessFactor vier Edge-Mosaikfaktoren (zum Mosaiken der Kanten), da der Mosaikator der festen Funktion wissen muss, wie viel mosaikiert werden muss. Die erforderlichen Ausgaben unterscheiden sich für die Dreiecks- und Isolinedomänen.
Der Festfunktions-Tessellator sieht keine anderen Ausgaben des Hüllen-Shaders an, z. B. andere Patchkonst constant-Daten oder einen der Kontrollpunkte. Der Domänen-Shader , der für jeden Punkt aufgerufen wird, den der Festfunktions-Mosaikator generiert, sieht als Eingabe alle Ausgabekontrollpunkte des Hüllen-Shaders und alle Ausgabepatchkonstiertendaten. der Shader wertet den Patch an seiner Position aus.
Definieren Sie eine Patchkonst constant-Funktion. Eine Patchkonstanzfunktion wird einmal für jeden Patch ausgeführt, um alle Daten zu berechnen, die für den gesamten Patch konstant sind (im Gegensatz zu Daten pro Kontrollpunkt, die im Hüllen-Shader berechnet werden).
#define MAX_POINTS 32 // Patch Constant Function HS_CONSTANT_DATA_OUTPUT SubDToBezierConstantsHS( InputPatch<VS_CONTROL_POINT_OUTPUT, MAX_POINTS> ip, uint PatchID : SV_PrimitiveID ) { HS_CONSTANT_DATA_OUTPUT Output; // Insert code to compute Output here return Output; }Zu den Eigenschaften der Patchkonst constant-Funktion gehören:
- Eine Eingabe gibt eine Variable an, die eine Patch-ID enthält, und wird durch den SV _ PrimitiveID-Systemwert identifiziert (siehe Semantik im Shadermodell 4).
- Ein Eingabeparameter sind die Eingabesteuerungspunkte, die in diesem Beispiel in VS _ CONTROL POINT _ _ OUTPUT deklariert sind. Eine Patchfunktion kann alle Eingabesteuerungspunkte für jeden Patch sehen. In diesem Beispiel gibt es 32 Kontrollpunkte pro Patch.
- Die Funktion muss mindestens Mosaikfaktoren pro Patch für die Mosaikphase berechnen, die mit SV _ TessFactor identifiziert werden. Eine Quad-Domäne erfordert vier Mosaikfaktoren für die Kanten und zwei zusätzliche Faktoren (identifiziert durch SV _ InsideTessFactor),um das Innere des Patches zu mosaiken. Der Festfunktions-Tessellator sieht keine anderen Hüllen-Shader-Ausgaben (z. B. die Patchkonst constant data oder einen der Kontrollpunkte) an.
- Die Ausgaben werden in der Regel durch eine -Struktur definiert und in diesem Beispiel durch HS _ CONSTANT DATA _ _ OUTPUT identifiziert. Die Struktur hängt vom Domänentyp ab und wäre für Dreiecks- oder Isolinedomänen unterschiedlich.
Andererseits wird ein Domänen-Shader für jeden Punkt aufgerufen, den der Festfunktions-Mosaikator generiert, und er muss die Ausgabekontrollpunkte und die Konstantendaten des Ausgabepatches (beide aus dem Hüllen-Shader) sehen, um einen Patch an seiner Position auswerten zu können.
Definieren Sie einen Hüllen-Shader. Ein Hüllen-Shader identifiziert die Eigenschaften eines Patches, einschließlich einer Patchkonst constant-Funktion. Ein Hüllen-Shader wird einmal für jeden Ausgabesteuerungspunkt aufgerufen.
[domain("quad")] [partitioning("integer")] [outputtopology("triangle_cw")] [outputcontrolpoints(16)] [patchconstantfunc("SubDToBezierConstantsHS")] BEZIER_CONTROL_POINT SubDToBezierHS( InputPatch<VS_CONTROL_POINT_OUTPUT, MAX_POINTS> ip, uint i : SV_OutputControlPointID, uint PatchID : SV_PrimitiveID ) { VS_CONTROL_POINT_OUTPUT Output; // Insert code to compute Output here. return Output; }Ein Hüllen-Shader verwendet die folgenden Attribute:
- Ein Domänenattribut.
- Ein Partitionierungsattribut.
- Ein Ausgabetopologieattribut.
- Ein outputcontrolpoints-Attribut.
- Ein patchconstantfunc-Attribut. Ein Hüllen-Shader berechnet Ausgabekontrollpunkte. In diesem Beispiel gibt es 16 Bezier-Ausgabekontrollpunkte.
Alle Eingabesteuerungspunkte (identifiziert durch VS _ CONTROL POINT _ _ OUTPUT) sind für jeden Shaderaufruf der Hülle sichtbar. In diesem Beispiel gibt es 32 Eingabesteuerungspunkte.
Ein Hüllen-Shader wird einmal pro Ausgabekontrollpunkt (identifiziert mit SV _ OutputControlPointID)für jeden Patch (identifiziert mit SV _ PrimitiveID) aufgerufen. Der Zweck dieses bestimmten Shaders ist die Berechnung der Ausgabe i, die als BEZIER-Kontrollpunkt definiert wurde (in diesem Beispiel sind 16 Ausgabekontrollpunkte durch outputcontrolpoints definiert).
Ein Hüllen-Shader führt eine Routine einmal pro Patch aus (die Patchkonstanzfunktion), um patchkonstierte Daten (Mosaikfaktoren als Minimum) zu berechnen. Separat führt ein Hüllen-Shader eine Patchkonstantenfunktion (subDToBezierConstantsHS) auf jedem Patch aus, um Patchkonstantendaten wie Mosaikfaktoren für die Mosaikphase zu berechnen.