Freigeben über


GLSL-zu-HLSL-Referenz

Sie portieren Ihren OpenGL Shader Language (GLSL)-Code zu Microsoft High Level Shader Language (HLSL)-Code, wenn Sie die Grafikarchitektur von OpenGL ES 2.0 zu Direct3D 11 portieren, um ein Spiel für Universelle Windows-Plattform (UWP) zu erstellen. Die hierin genannte GLSL ist mit OpenGL ES 2.0 kompatibel; hlSL ist mit Direct3D 11 kompatibel. Informationen zu den Unterschieden zwischen Direct3D 11 und früheren Versionen von Direct3D finden Sie unter Featurezuordnung.

Vergleich von OpenGL ES 2.0 mit Direct3D 11

OpenGL ES 2.0 und Direct3D 11 weisen viele Ähnlichkeiten auf. Beide weisen ähnliche Renderingpipelinen und Grafikfeatures auf. Direct3D 11 ist jedoch eine Renderingimplementierung und API, keine Spezifikation; OpenGL ES 2.0 ist eine Renderingspezifikation und API, keine Implementierung. Direct3D 11 und OpenGL ES 2.0 unterscheiden sich in der Regel auf folgende Weise:

OpenGL ES 2.0 Direct3D 11
Hardware- und Betriebssystemunabhängige Spezifikation mit vom Anbieter bereitgestellten Implementierungen Microsoft-Implementierung der Hardwarestraktion und -zertifizierung auf Windows-Plattformen
Abstrahiert für die Hardwarevielfalt verwaltet die Laufzeit die meisten Ressourcen. Direkter Zugriff auf das Hardwarelayout; App kann Ressourcen und Verarbeitung verwalten
Stellt Module auf höherer Ebene über Drittanbieterbibliotheken bereit (z. B. Simple DirectMedia Layer (SDL)) Module auf höherer Ebene wie Direct2D basieren auf niedrigeren Modulen, um die Entwicklung für Windows-Apps zu vereinfachen.
Hardwareanbieter unterscheiden sich über Erweiterungen Microsoft fügt der API optionale Features auf generische Weise hinzu, sodass sie nicht für einen bestimmten Hardwareanbieter spezifisch sind.

 

GLSL und HLSL unterscheiden sich in der Regel auf folgende Weise:

GLSL HLSL
Prozedural, schrittzentriert (Z wie) Objektorientierte, datenorientierte (c++-like)
In die Grafik-API integrierte Shaderkompilierung Der HLSL-Compiler kompiliert den Shader zu einer binären Zwischendarstellung, bevor Direct3D ihn an den Treiber übergibt.
Beachten Sie , dass diese binäre Darstellung hardwareunabhängig ist. Sie wird in der Regel zur App-Buildzeit kompiliert und nicht zur App-Laufzeit.
 
Variable Speichermodifizierer Konstantenpuffer und Datenübertragungen über Eingabelayoutdeklarationen

Typen

Typischer Vektortyp: vec2/3/4

lowp, mediump, highp

Typischer Vektortyp: float2/3/4

min10float, min16float

texture2D [Funktion] Textur. Beispiel [Datentyp. Funktion]
sampler2D [Datentyp] Texture2D [Datentyp]
Zeilenmatrizen (Standard) Spaltenmatrizen (Standard)
Hinweis : Verwenden Sie den row_major Typmodifizierer, um das Layout für eine Variable zu ändern. Weitere Informationen finden Sie unter Variable Syntax. Sie können auch ein Compilerflagge oder ein Pragma angeben, um den globalen Standardwert zu ändern.
 
Fragment-Shader Pixel-Shader

 

Beachten Sie, dass HLSL Texturen und Sampler als zwei separate Objekte enthält. In GLSL wie Direct3D 9 ist die Texturbindung Teil des Samplerzustands.

 

In GLSL stellen Sie einen Großteil des OpenGL-Zustands als vordefinierte globale Variablen dar. Bei GLSL verwenden Sie z. B. die gl_Position Variable, um die Vertexposition und die gl_FragColor Variable anzugeben, um die Fragmentfarbe anzugeben. In HLSL übergeben Sie den Direct3D-Zustand explizit vom App-Code an den Shader. Bei Direct3D und HLSL muss die Eingabe an den Vertex-Shader beispielsweise mit dem Datenformat im Vertexpuffer übereinstimmen, und die Struktur eines Konstantenpuffers im App-Code muss mit der Struktur eines Konstantenpuffers (cbuffer) im Shadercode übereinstimmen.

Portieren von GLSL-Variablen zu HLSL

In GLSL wenden Sie Modifizierer (Qualifizierer) auf eine globale Shadervariablendeklaration an, um dieser Variable ein bestimmtes Verhalten in Ihren Shadern zuzuweisen. In HLSL benötigen Sie diese Modifizierer nicht, da Sie den Fluss des Shaders mit den Argumenten definieren, die Sie an den Shader übergeben und von Ihrem Shader zurückgeben.

GLSL-Variablenverhalten HLSL-Entsprechung

Uniform

Sie übergeben eine einheitliche Variable aus dem App-Code entweder an Vertex- und Fragment-Shader. Sie müssen die Werte aller Uniformen festlegen, bevor Sie Dreiecke mit diesen Shadern zeichnen, damit ihre Werte während der Zeichnung eines Dreiecksgitters gleich bleiben. Diese Werte sind einheitlich. Einige Uniforms werden für den gesamten Frame und andere eindeutig auf ein bestimmtes Vertex-Pixelshaderpaar festgelegt.

Uniform-Variablen sind Polygonvariablen.

Verwenden Sie den Konstantenpuffer.

Siehe Vorgehensweise: Erstellen eines Konstantenpuffers und Shaderkonstanten.

variierend

Sie initialisieren eine unterschiedliche Variable innerhalb des Vertex-Shaders und übergeben sie an eine identisch benannte variable im Fragment-Shader. Da der Vertex-Shader nur den Wert der unterschiedlichen Variablen an jedem Scheitelpunkt festlegt, interpoliert der Rasterizer diese Werte (perspektivisch korrekt), um pro Fragmentwerte zu generieren, die an den Fragmentshader übergeben werden. Diese Variablen variieren je nach Dreieck.

Verwenden Sie die Struktur, die Sie vom Vertex-Shader als Eingabe für den Pixelshader zurückgeben. Stellen Sie sicher, dass die semantischen Werte übereinstimmen.

attribute

Ein Attribut ist Teil der Beschreibung eines Scheitelpunkts, den Sie allein vom App-Code an den Vertex-Shader übergeben. Im Gegensatz zu einer Uniform legen Sie den Wert jedes Attributs für jeden Scheitelpunkt fest, der wiederum jedem Scheitelpunkt einen anderen Wert zulässt. Attributvariablen sind Vertexvariablen.

Definieren Sie einen Vertexpuffer im Direct3D-App-Code, und stimmen Sie ihn mit der im Vertex-Shader definierten Vertexeingabe überein. Definieren Sie optional einen Indexpuffer. Weitere Informationen finden Sie unter How to: Create a Vertex Buffer and How to: Create an Index Buffer.

Erstellen Sie ein Eingabelayout in Ihrem Direct3D-App-Code, und stimmen Sie semantische Werte mit denen in der Vertexeingabe überein. Siehe Erstellen des Eingabelayouts.

const

Konstanten, die in den Shader kompiliert und nie geändert werden.

Verwenden Sie einen statischen Konst. statisch bedeutet, dass der Wert nicht für Konstantenpuffer verfügbar gemacht wird. Const bedeutet, dass der Shader den Wert nicht ändern kann. Der Wert wird also zur Kompilierungszeit basierend auf seinem Initialisierer bekannt.

 

In GLSL sind Variablen ohne Modifizierer nur gewöhnliche globale Variablen, die für jeden Shader privat sind.

Wenn Sie Daten an Texturen (Texture2D in HLSL) und die zugehörigen Sampler (SamplerState in HLSL) übergeben, deklarieren Sie sie in der Regel als globale Variablen im Pixelshader.

Portieren von GLSL-Typen zu HLSL

Verwenden Sie diese Tabelle, um Ihre GLSL-Typen zu HLSL zu portieren.

GLSL-Typ HLSL-Typ
Skalare Typen: float, int, bool

Skalare Typen: float, int, bool

auch, uint, double

Weitere Informationen finden Sie unter Skalartypen.

Vektortyp

  • Gleitkommavektor: vec2, vec3, vec4
  • Boolescher Vektor: bvec2, bvec3, bvec4
  • Signierter ganzzahliger Vektor: ivec2, ivec3, ivec4

Vektortyp

  • float2, float3, float4 und float1
  • bool2, bool3, bool4 und bool1
  • int2, int3, int4 und int1
  • Diese Typen weisen auch Vektorerweiterungen auf, die float, bool und int ähneln:

    • uint
    • min10float, min16float
    • min12int, min16int
    • min16uint

Weitere Informationen finden Sie unter Vektortyp und Schlüsselwörter.

Vektor ist auch typ definiert als float4 (typedef vector <float, 4> vector;). Weitere Informationen finden Sie unter "Benutzerdefinierter Typ".

Matrixtyp

  • mat2: 2x2 Float-Matrix
  • mat3: 3x3 Float-Matrix
  • mat4: 4x4 Float-Matrix

Matrixtyp

  • float2x2
  • float3x3
  • float4x4
  • auch, float1x1, float1x2, float1x3, float1x4, float2x1, float2x3, float2x4, float3x1, float3x2, float3x4, float4x1, float4x2, float4x3
  • Diese Typen weisen auch Matrixerweiterungen auf, die dem Gleitkomma ähneln:

    • int, uint, bool
    • min10float, min16float
    • min12int, min16int
    • min16uint

Sie können auch den Matrixtyp verwenden, um eine Matrix zu definieren.

Beispiel: Matrix <float, 2, 2> fMatrix = {0.0f, 0.1, 2.1f, 2.2f};

matrix is also type defined as float4x4 (typedef matrix <float, 4, 4> matrix;). Weitere Informationen finden Sie unter "Benutzerdefinierter Typ".

Genauigkeitsqualifizierer für float, int, sampler

  • highp

    Dieser Qualifizierer bietet Mindestgenauigkeitsanforderungen, die größer als die von min16float und kleiner als eine vollständige 32-Bit-Gleitkommazahl sind. Äquivalent in HLSL ist:

    highp float -> float

    highp int -> int

  • mediump

    Dieser Qualifizierer, der auf Float und Int angewendet wird, entspricht min16float und min12int in HLSL. Mindestens 10 Bit mantissa, nicht wie min10float.

  • lowp

    Dieser Auf Float angewendete Qualifizierer stellt einen Gleitkommabereich von -2 bis 2 bereit. Entspricht min10float in HLSL.

Genauigkeitstypen

  • min16float: mindestens 16-Bit-Gleitkommawert
  • min10float

    Minimaler 2,8-Bit-Wert mit Festkommazeichen (2 Bit ganze Zahl und 8 Bit Bruchkomponente). Die 8-Bit-Bruchkomponente kann von 1 und nicht exklusiv sein, um ihr den vollständigen inklusiven Bereich von -2 bis 2 zu verleihen.

  • min16int: mindestens 16-Bit-ganzzahlige Vorzeichen
  • min12int: mindestens 12-Bit-ganzzahlige Vorzeichen

    Dieser Typ gilt für 10Level9 (9_x Featureebenen), in denen ganze Zahlen durch Gleitkommazahlen dargestellt werden. Dies ist die Genauigkeit, die Sie erhalten können, wenn Sie eine ganze Zahl mit einer 16-Bit-Gleitkommazahl emulieren.

  • min16uint: minimale 16-Bit-Ganzzahl ohne Vorzeichen

Weitere Informationen finden Sie unter Scalar Types and Using HLSL minimum precision.

Sampler2D Texture2D
samplerCube TextureCube

 

Portieren vordefinierter globaler GLSL-Variablen zu HLSL

Verwenden Sie diese Tabelle, um vordefinierte globale GLSL-Variablen zu HLSL zu portieren.

VORDEFINIERTE globale GLSL-Variable HLSL-Semantik

gl_Position

Diese Variable ist typ vec4.

Vertexposition

z. B. - gl_Position = Position;

SV_Position

POSITION in Direct3D 9

Diese Semantik ist " float4".

Vertex-Shaderausgabe

Vertexposition

beispiel - float4 vPosition : SV_Position;

gl_PointSize

Diese Variable ist typ float.

Punktgröße

PSIZE

Keine Bedeutung, es sei denn, Sie zielen auf Direct3D 9 ab

Diese Semantik ist " Float".

Vertex-Shaderausgabe

Punktgröße

gl_FragColor

Diese Variable ist typ vec4.

Fragmentfarbe

beispiel - gl_FragColor = vec4(colorVarying, 1,0);

SV_Target

COLOR in Direct3D 9

Diese Semantik ist " float4".

Pixelshaderausgabe

Pixelfarbe

beispiel - float4 Color[4] : SV_Target;

gl_FragData[n]

Diese Variable ist typ vec4.

Fragmentfarbe für Farbanlage n

SV_Target[n]

Diese Semantik ist " float4".

Der Ausgabewert des Pixelshaders, der im Renderziel n gespeichert ist, wobei 0 <= n <= 7 ist.

gl_FragCoord

Diese Variable ist typ vec4.

Fragmentposition innerhalb des Framepuffers

SV_Position

In Direct3D 9 nicht verfügbar

Diese Semantik ist " float4".

Pixelshadereingabe

Bildschirmraumkoordinaten

beispiel - float4 screenSpace : SV_Position

gl_FrontFacing

Diese Variable ist typ bool.

Bestimmt, ob das Fragment zu einem frontseitigen Grundtyp gehört.

SV_IsFrontFace

VFACE in Direct3D 9

SV_IsFrontFace ist typ bool.

VFACE ist typ float.

Pixelshadereingabe

Grundtyp mit Vorrichtung

gl_PointCoord

Diese Variable ist typ vec2.

Fragmentposition innerhalb eines Punkts (nur Punktrasterung)

SV_Position

VPOS in Direct3D 9

SV_Position ist " float4".

VPOS ist typ float2.

Pixelshadereingabe

Die Pixel- oder Beispielposition im Bildschirmbereich

beispiel - float4 pos : SV_Position

gl_FragDepth

Diese Variable ist typ float.

Tiefenpufferdaten

SV_Depth

TIEFE in Direct3D 9

SV_Depth ist " Float".

Pixelshaderausgabe

Tiefenpufferdaten

 

Mithilfe der Semantik können Sie Position, Farbe usw. für vertex-Shadereingaben und Pixelshadereingaben angeben. Sie müssen mit den Semantikwerten im Eingabelayout mit der Vertex-Shadereingabe übereinstimmen. Beispiele finden Sie unter Beispiele für das Portieren von GLSL-Variablen zu HLSL. Weitere Informationen zur HLSL-Semantik finden Sie unter Semantik.

Beispiele für das Portieren von GLSL-Variablen zu HLSL

Hier zeigen wir Beispiele für die Verwendung von GLSL-Variablen im OpenGL/GLSL-Code und dann das entsprechende Beispiel in Direct3D/HLSL-Code.

Uniform, Attribut und unterschiedliche In GLSL

OpenGL-App-Code

// Uniform values can be set in app code and then processed in the shader code.
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;

// Incoming position of vertex
attribute vec4 position;
 
// Incoming color for the vertex
attribute vec3 color;
 
// The varying variable tells the shader pipeline to pass it  
// on to the fragment shader.
varying vec3 colorVarying;

GLSL-Vertex-Shadercode

//The shader entry point is the main method.
void main()
{
colorVarying = color; //Use the varying variable to pass the color to the fragment shader
gl_Position = position; //Copy the position to the gl_Position pre-defined global variable
}

GLSL-Fragmentshadercode

void main()
{
//Pad the colorVarying vec3 with a 1.0 for alpha to create a vec4 color
//and assign that color to the gl_FragColor pre-defined global variable
//This color then becomes the fragment's color.
gl_FragColor = vec4(colorVarying, 1.0);
}

Konstantenpuffer und Datenübertragungen in HLSL

Hier sehen Sie ein Beispiel dafür, wie Sie Daten an den HLSL-Vertex-Shader übergeben, der dann zum Pixelshader fließt. Definieren Sie im App-Code einen Scheitelpunkt und einen Konstantenpuffer. Definieren Sie dann im Vertex-Shadercode den Konstantenpuffer als cbuffer , und speichern Sie die Daten pro Vertex und die Pixel-Shadereingabedaten. Hier verwenden wir Strukturen namens "VertexShaderInput " und "PixelShaderInput".

Direct3D-App-Code

struct ConstantBuffer
{
    XMFLOAT4X4 model;
    XMFLOAT4X4 view;
    XMFLOAT4X4 projection;
};
struct SimpleCubeVertex
{
    XMFLOAT3 pos;   // position
    XMFLOAT3 color; // color
};

 // Create an input layout that matches the layout defined in the vertex shader code.
 const D3D11_INPUT_ELEMENT_DESC basicVertexLayoutDesc[] =
 {
     { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0,  0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
     { "COLOR",    0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },
 };

// Create vertex and index buffers that define a geometry.

HLSL-Vertex-Shadercode

cbuffer ModelViewProjectionCB : register( b0 )
{
    matrix model; 
    matrix view;
    matrix projection;
};
// The POSITION and COLOR semantics must match the semantics in the input layout Direct3D app code.
struct VertexShaderInput
{
    float3 pos : POSITION; // Incoming position of vertex 
    float3 color : COLOR; // Incoming color for the vertex
};

struct PixelShaderInput
{
    float4 pos : SV_Position; // Copy the vertex position.
    float4 color : COLOR; // Pass the color to the pixel shader.
};

PixelShaderInput main(VertexShaderInput input)
{
    PixelShaderInput vertexShaderOutput;

    // shader source code

    return vertexShaderOutput;
}

HLSL-Pixelshadercode

// Collect input from the vertex shader. 
// The COLOR semantic must match the semantic in the vertex shader code.
struct PixelShaderInput
{
    float4 pos : SV_Position;
    float4 color : COLOR; // Color for the pixel
};

// Set the pixel color value for the renter target. 
float4 main(PixelShaderInput input) : SV_Target
{
    return input.color;
}

Beispiele für das Portieren von OpenGL-Renderingcode zu Direct3D

Hier zeigen wir ein Beispiel für das Rendern in OpenGL ES 2.0-Code und dann das entsprechende Beispiel im Direct3D 11-Code.

OpenGL-Renderingcode

// Bind shaders to the pipeline. 
// Both vertex shader and fragment shader are in a program.
glUseProgram(m_shader->getProgram());
 
// Input assembly 
// Get the position and color attributes of the vertex.

m_positionLocation = glGetAttribLocation(m_shader->getProgram(), "position");
glEnableVertexAttribArray(m_positionLocation);

m_colorLocation = glGetAttribColor(m_shader->getProgram(), "color");
glEnableVertexAttribArray(m_colorLocation);
 
// Bind the vertex buffer object to the input assembler.
glBindBuffer(GL_ARRAY_BUFFER, m_geometryBuffer);
glVertexAttribPointer(m_positionLocation, 4, GL_FLOAT, GL_FALSE, 0, NULL);
glBindBuffer(GL_ARRAY_BUFFER, m_colorBuffer);
glVertexAttribPointer(m_colorLocation, 3, GL_FLOAT, GL_FALSE, 0, NULL);
 
// Draw a triangle with 3 vertices.
glDrawArray(GL_TRIANGLES, 0, 3);

Direct3D-Renderingcode

// Bind the vertex shader and pixel shader to the pipeline.
m_d3dDeviceContext->VSSetShader(vertexShader.Get(),nullptr,0);
m_d3dDeviceContext->PSSetShader(pixelShader.Get(),nullptr,0);
 
// Declare the inputs that the shaders expect.
m_d3dDeviceContext->IASetInputLayout(inputLayout.Get());
m_d3dDeviceContext->IASetVertexBuffers(0, 1, vertexBuffer.GetAddressOf(), &stride, &offset);

// Set the primitive's topology.
m_d3dDeviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);

// Draw a triangle with 3 vertices. triangleVertices is an array of 3 vertices.
m_d3dDeviceContext->Draw(ARRAYSIZE(triangleVertices),0);