Portieren der GLSLPort the GLSL

Wichtige APIsImportant APIs

Nachdem Sie sich um den Code gekümmert haben, mit dem die Puffer und Shaderobjekte erstellt und konfiguriert werden, muss der in diesen Shadern enthaltene Code von der GL Shader Language (GLSL) von OpenGL ES 2.0 in die High-Level Shader Language (HLSL) von Direct3D 11 portiert werden.Once you've moved over the code that creates and configures your buffers and shader objects, it's time to port the code inside those shaders from OpenGL ES 2.0's GL Shader Language (GLSL) to Direct3D 11's High-level Shader Language (HLSL).

In OpenGL es 2,0 geben Shader Daten nach der Ausführung mithilfe von systeminternen Funktionen wie z. b. GL- _ Position, GL _ fragcoloroder **GL _ fragdata [ n ] ** zurück (wobei n der Index für ein bestimmtes Renderziel ist).In OpenGL ES 2.0, shaders return data after execution using intrinsics such as gl_Position, gl_FragColor, or gl_FragData[n] (where n is the index for a specific render target). In Direct3D sind keine speziellen systeminternen Funktionen vorhanden. Von den Shadern werden Daten als Rückgabetyp ihrer jeweiligen main()-Funktionen zurückgegeben.In Direct3D, there are no specific intrinsics, and the shaders return data as the return type of their respective main() functions.

Daten, die zwischen Shaderphasen interpoliert werden sollen, z. B. Vertexposition oder Normale, werden mithilfe der varying-Deklaration behandelt.Data that you want interpolated between shader stages, such as the vertex position or normal, is handled through the use of the varying declaration. Direct3D verfügt jedoch nicht über diese Deklaration. Alle Daten, die zwischen Shaderphasen übertragen werden sollen, müssen daher per HLSL-Semantik markiert werden.However, Direct3D doesn't have this declaration; rather, any data that you want passed between shader stages must be marked with an HLSL semantic. Mit der jeweils gewählten Semantik wird der Zweck für die Daten angegeben.The specific semantic chosen indicates the purpose of the data, and is. Vertexdaten, die zwischen Fragmentshadern interpoliert werden sollen, werden beispielsweise wie folgt deklariert:For example, you'd declare vertex data that you want interpolated between the fragment shader as:

float4 vertPos : POSITION;

oderor

float4 vertColor : COLOR;

POSITION steht hierbei für die Semantik, die zum Angeben der Vertexpositionsdaten verwendet wird.Where POSITION is the semantic used to indicate vertex position data. POSITION stellt außerdem einen Sonderfall dar, da vom Pixelshader nach der Interpolation darauf nicht zugegriffen werden kann.POSITION is also a special case, since after interpolation, it cannot be accessed by the pixel shader. Daher müssen Sie die Eingabe für den Pixelshader mit der SV _ -Position angeben, und die interpoliert Vertex-Daten werden in diese Variable eingefügt.Therefore, you must specify input to the pixel shader with SV_POSITION and the interpolated vertex data will be placed in that variable.

float4 position : SV_POSITION;

Die Semantik kann für die body-Methoden (main) von Shadern deklariert werden.Semantics can be declared on the body (main) methods of shaders. Für Pixel-Shader _ [ ist das SV Target n ] , das ein Renderziel angibt, in der Body-Methode erforderlich.For pixel shaders, SV_TARGET[n], which indicates a render target, is required on the body method. (SV _ Für das Ziel ohne numerische Suffix wird standardmäßig der renderzielindex 0 verwendet.)(SV_TARGET without a numeric suffix defaults to render target index 0.)

Beachten Sie außerdem, dass Vertex-Shader die Semantik des SV- _ Positions System Werts ausgeben müssen.Also note that vertex shaders are required to output the SV_POSITION system value semantic. Mit dieser Semantik werden die Vertexpositionsdaten zu Koordinatenwerten aufgelöst, wobei "x" zwischen -1 und 1 und "y" zwischen -1 und 1 liegt. "z" wird durch den ursprünglichen homogenen Koordinatenwert "w" dividiert (z/w), und "w" ist 1 dividiert durch den Originalwert "w" (1/w).This semantic resolves the vertex position data to coordinate values where x is between -1 and 1, y is between -1 and 1, z is divided by the original homogeneous coordinate w value (z/w), and w is 1 divided by the original w value (1/w). Pixel-Shader verwenden die _ Semantik des SV-Positions System Werts, um die Pixelposition auf dem Bildschirm abzurufen, wobei x zwischen 0 und der renderzielbreite und y zwischen 0 und der renderzielhöhe (jeder Offset um 0,5) liegt.Pixel shaders use the SV_POSITION system value semantic to retrieve the pixel location on the screen, where x is between 0 and the render target width and y is between 0 and the render target height (each offset by 0.5). Funktionsebene 9 _ x Pixel-Shader können nicht vom SV- _ Positionswert lesen.Feature level 9_x pixel shaders cannot read from the SV_POSITION value.

Konstantenpuffer müssen mit cbuffer deklariert und mit einem speziellen Startregister für die Suche versehen werden.Constant buffers must be declared with cbuffer and be associated with a specific starting register for lookup.

Direct3D 11: Deklaration eines HLSL-KonstantenpuffersDirect3D 11: An HLSL constant buffer declaration

cbuffer ModelViewProjectionConstantBuffer : register(b0)
{
  matrix mvp;
};

Hier wird vom Konstantenpuffer das Register „b0“ für den gepackten Puffer verwendet.Here, the constant buffer uses register b0 to hold the packed buffer. Auf alle Register wird in der Form b verwiesen # .All registers are referred to in the form b#. Weitere Informationen zur HLSL-Implementierung von Konstantenpuffern, Registern und Datenpaketen finden Sie unter Shaderkonstanten (HLSL).For more information on the HLSL implementation of constant buffers, registers, and data packing, read Shader Constants (HLSL).

InstructionsInstructions

Schritt 1: Portieren des Vertex-ShadersStep 1: Port the vertex shader

In diesem einfachen OpenGL ES 2.0-Beispiel verfügt der Vertex-Shader über drei Eingaben: eine konstante Modell-Ansicht-Projektion-4x4-Matrix und zwei Vektoren mit vier Koordinaten.In our simple OpenGL ES 2.0 example, the vertex shader has three inputs: a constant model-view-projection 4x4 matrix, and two 4-coordinate vectors. Diese beiden Vektoren enthalten die Vertexposition und ihre Farbe.These two vectors contain the vertex position and its color. Der Shader wandelt den Positions Vektor in perspektivische Koordinaten um und weist ihn der systeminternen GL- _ Position für die rasterisierung zu.The shader transforms the position vector to perspective coordinates and assigns it to the gl_Position intrinsic for rasterization. Außerdem wird die Vertexfarbe zur Interpolation während der Rasterung in eine abweichende Variable kopiert.The vertex color is copied to a varying variable for interpolation during rasterization, as well.

OpenGL ES 2.0: Vertex-Shader für das Würfelobjekt (GLSL)OpenGL ES 2.0: Vertex shader for the cube object (GLSL)

uniform mat4 u_mvpMatrix; 
attribute vec4 a_position;
attribute vec4 a_color;
varying vec4 destColor;

void main()
{           
  gl_Position = u_mvpMatrix * a_position;
  destColor = a_color;
}

In Direct3D ist die konstante Modell-Ansicht-Projektion-Matrix in einem Konstantenpuffer enthalten, der unter Register b0 verpackt ist, und die Vertexposition und -farbe sind speziell mit der jeweils geeigneten HLSL-Semantik gekennzeichnet: POSITION und COLOR.Now, in Direct3D, the constant model-view-projection matrix is contained in a constant buffer packed at register b0, and the vertex position and color are specifically marked with the appropriate respective HLSL semantics: POSITION and COLOR. Da das Eingabelayout eine bestimmte Anordnung dieser beiden Vertexwerte vorgibt, erstellen Sie dafür eine Struktur und deklarieren diese als Typ für den Eingabeparameter der body-Shaderfunktion (main).Since our input layout indicates a specific arrangement of these two vertex values, you create a struct to hold them and declare it as the type for the input parameter on the shader body function (main). (Sie können die Werte auch als zwei einzelne Parameter angeben, was mitunter jedoch umständlich ist.) Außerdem geben Sie einen Ausgabetyp für diese Phase an, der die interpolierte Position und Farbe enthält, und deklarieren ihn als Rückgabewert für die body-Funktion des Vertex-Shaders.(You could also specify them as two individual parameters, but that could get cumbersome.) You also specify an output type for this stage, which contains the interpolated position and color, and declare it as the return value for the body function of the vertex shader.

Direct3D 11: Vertex-Shader für das Würfelobjekt (HLSL)Direct3D 11: Vertex shader for the cube object (HLSL)

cbuffer ModelViewProjectionConstantBuffer : register(b0)
{
  matrix mvp;
};

// Per-vertex data used as input to the vertex shader.
struct VertexShaderInput
{
  float3 pos : POSITION;
  float3 color : COLOR;
};

// Per-vertex color data passed through the pixel shader.
struct PixelShaderInput
{
  float3 pos : SV_POSITION;
  float3 color : COLOR;
};

PixelShaderInput main(VertexShaderInput input)
{
  PixelShaderInput output;
  float4 pos = float4(input.pos, 1.0f); // add the w-coordinate

  pos = mul(mvp, projection);
  output.pos = pos;

  output.color = input.color;

  return output;
}

Der Ausgabedatentyp „PixelShaderInput“ wird während der Rasterung aufgefüllt und für den Fragmentshader (Pixelshader) bereitgestellt.The output data type, PixelShaderInput, is populated during rasterization and provided to the fragment (pixel) shader.

Schritt 2: Portieren des FragmentshadersStep 2: Port the fragment shader

Der Beispiel fragmentshader in GLSL ist äußerst einfach: Stellen Sie die systeminterne GL- _ fragmentfarbe mit dem interpoliert Farbwert bereit.Our example fragment shader in GLSL is extremely simple: provide the gl_FragColor intrinsic with the interpolated color value. Von OpenGL ES 2.0 wird er in das standardmäßige Renderziel geschrieben.OpenGL ES 2.0 will write it to the default render target.

OpenGL ES 2.0: Fragmentshader für das Würfelobjekt (GLSL)OpenGL ES 2.0: Fragment shader for the cube object (GLSL)

varying vec4 destColor;

void main()
{
  gl_FragColor = destColor;
} 

Für Direct3D ist der Aufbau nahezu genauso einfach.Direct3D is almost as simple. Der einzige zu beachtende Unterschied besteht darin, dass die body-Funktion des Pixelshaders einen Wert zurückgeben muss.The only significant difference is that the body function of the pixel shader must return a value. Da es sich bei der Farbe um einen 4-Koordinaten-float-Wert (RGBA) handelt, geben Sie float4 als Rückgabetyp an, und geben Sie dann das standardmäßige Renderziel als Semantik des SV- _ Zielsystem WertsSince the color is a 4-coordinate (RGBA) float value, you indicate float4 as the return type, and then specify the default render target as the SV_TARGET system value semantic.

Direct3D 11: Pixelshader für das Würfelobjekt (HLSL)Direct3D 11: Pixel shader for the cube object (HLSL)

struct PixelShaderInput
{
  float4 pos : SV_POSITION;
  float3 color : COLOR;
};


float4 main(PixelShaderInput input) : SV_TARGET
{
  return float4(input.color, 1.0f);
}

Die Farbe für das Pixel an der Position wird in das Renderziel geschrieben.The color for the pixel at the position is written to the render target. Das Anzeigen der Inhalte dieses Renderziels als nächster Schritt wird unter Zeichnen auf den Bildschirm beschrieben.Now, let's see how to display the contents of that render target in Draw to the screen!

Vorheriger SchrittPrevious step

Portieren der Vertexpuffer und -daten Nächster SchrittPort the vertex buffers and data Next step

Zeichnen auf den Bildschirm AnmerkungenDraw to the screen Remarks

Wenn Sie mit der HLSL-Semantik und dem Packen von Konstantenpuffern vertraut sind, können Sie einigen Debugaufwand vermeiden und Möglichkeiten zur Optimierung schaffen.Understanding HLSL semantics and the packing of constant buffers can save you a bit of a debugging headache, as well as provide optimization opportunities. Lesen Sie sich nach Möglichkeit die Themen Variablensyntax (HLSL), Einführung in Puffer in Direct3D 11 und Erstellen eines Konstantenpuffers durch.If you get a chance, read through Variable Syntax (HLSL), Introduction to Buffers in Direct3D 11, and How to: Create a Constant Buffer. Hier sind als Anfang schon einmal einige Tipps aufgeführt, die in Verbindung mit der Semantik und Konstantenpuffern zu beachten sind:If not, though, here's a few starting tips to keep in mind about semantics and constant buffers:

  • Überprüfen Sie stets den Direct3D-Konfigurationscode des Renderers, um sicherzustellen, dass die Strukturen für die Konstantenpuffer mit den cbuffer-Strukturdeklarationen der HLSL übereinstimmen und dass die Komponentenskalartypen für beide Deklarationen übereinstimmen.Always double check your renderer's Direct3D configuration code to make sure that the structures for your constant buffers match the cbuffer struct declarations in your HLSL, and that the component scalar types match across both declarations.
  • Verwenden Sie im C++-Code des Renderers DirectXMath-Typen in den Konstantenpufferdeklarationen, um für die richtige Verpackung der Daten zu sorgen.In your renderer's C++ code, use DirectXMath types in your constant buffer declarations to ensure proper data packing.
  • Die beste Möglichkeit zur effizienten Nutzung von Konstantenpuffern ist die Organisation von Shadervariablen in Konstantenpuffern anhand der Updatehäufigkeit.The best way to efficiently use constant buffers is to organize shader variables into constant buffers based on their frequency of update. Wenn Sie beispielsweise über uniform-Daten verfügen, die einmal pro Frame aktualisiert werden, sowie über andere uniform-Daten, die nur bei Kamerabewegungen aktualisiert werden, empfiehlt sich das Aufteilen der Daten auf zwei separate Konstantenpuffer.For example, if you have some uniform data that is updated once per frame, and other uniform data that is updated only when the camera moves, consider separating that data into two separate constant buffers.
  • Semantik, deren Anwendung Sie vergessen oder die Sie auf fehlerhafte Weise angewendet haben, ist die wichtigste Ursache für Fehler der Shaderkompilierung (FXC).Semantics that you have forgotten to apply or which you have applied incorrectly will be your earliest source of shader compilation (FXC) errors. Deshalb sollten Sie die Semantik auf jeden Fall noch einmal überprüfen.Double-check them! Die Dokumente können etwas verwirrend erscheinen, da viele ältere Seiten und Beispiele noch auf andere Versionen der HLSL-Semantik des Stands vor Direct3D 11 verweisen.The docs can be a bit confusing, as many older pages and samples refer to different versions of HLSL semantics prior to Direct3D 11.
  • Stellen Sie sicher, dass Sie wissen, auf welche Direct3D-Featureebene Sie für einen Shader jeweils abzielen.Make sure you know which Direct3D feature level you are targeting for each shader. Die Semantik für Featureebene 9 _ * unterscheidet sich von der Semantik für 11 _ 1.The semantics for feature level 9_* are different from those for 11_1.
  • Die SV- _ Positions Semantik löst die zugeordneten Post-Interpolations Positionsdaten auf, um Werte zu koordinieren, bei denen x zwischen 0 und der renderzielbreite, y zwischen 0 und der renderzielhöhe ist. z wird durch den ursprünglichen homogenen Koordinaten Wert (z/w) dividiert, und w ist 1 dividiert durch den ursprünglichen w-Wert (1/w)The SV_POSITION semantic resolves the associated post-interpolation position data to coordinate values where x is between 0 and the render target width, y is between 0 and the render target height, z is divided by the original homogeneous coordinate w value (z/w), and w is 1 divided by the original w value (1/w).

Gewusst wie: portieren eines einfachen OpenGL es 2,0-Renderers zu Direct3D 11How to: port a simple OpenGL ES 2.0 renderer to Direct3D 11

Portieren der ShaderobjektePort the shader objects

Portieren der Vertexpuffer und -datenPort the vertex buffers and data

Zeichnen auf den BildschirmDraw to the screen