Référence GLSL à HLSL
Vous portez votre code GLSL (OpenGL Shader Language) vers le code HLSL (High Level Shader Language) Microsoft lorsque vous portez votre architecture graphique d’OpenGL ES 2.0 vers Direct3D 11 pour créer un jeu pour plateforme Windows universelle (UWP). Le GLSL mentionné ici est compatible avec OpenGL ES 2.0 ; HLSL est compatible avec Direct3D 11. Pour plus d’informations sur les différences entre Direct3D 11 et les versions précédentes de Direct3D, consultez Mappage des fonctionnalités.
- Comparaison d’OpenGL ES 2.0 avec Direct3D 11
- Portage des variables GLSL vers HLSL
- Portage des types GLSL vers HLSL
- Portage de variables globales prédéfinies GLSL vers HLSL
- Exemples de portage de variables GLSL vers HLSL
- Exemples de portage du code de rendu OpenGL vers Direct3D
- Rubriques connexes
Comparaison d’OpenGL ES 2.0 avec Direct3D 11
OpenGL ES 2.0 et Direct3D 11 présentent de nombreuses similitudes. Ils ont tous deux des pipelines de rendu similaires et des fonctionnalités graphiques. Mais Direct3D 11 est une implémentation de rendu et une API, et non une spécification ; OpenGL ES 2.0 est une spécification de rendu et une API, et non une implémentation. Direct3D 11 et OpenGL ES ES 2.0 diffèrent généralement de ces façons :
OpenGL ES 2.0 | Direct3D 11 |
---|---|
Spécification indépendante du matériel et du système d’exploitation avec des implémentations fournies par le fournisseur | Implémentation Microsoft de l’abstraction matérielle et de la certification sur les plateformes Windows |
Abstrait pour la diversité matérielle, le runtime gère la plupart des ressources | Accès direct à la disposition matérielle ; l’application peut gérer les ressources et le traitement |
Fournit des modules de niveau supérieur via des bibliothèques tierces (par exemple, Simple DirectMedia Layer (SDL)) | Les modules de niveau supérieur, comme Direct2D, sont basés sur des modules inférieurs pour simplifier le développement pour les applications Windows |
Les fournisseurs de matériel se différencient par le biais d’extensions | Microsoft ajoute des fonctionnalités facultatives à l’API de manière générique afin qu’elles ne soient pas spécifiques à un fournisseur de matériel particulier |
GLSL et HLSL diffèrent généralement de ces façons :
GLSL | HLSL |
---|---|
Procédure, centrée sur les étapes (C like) | Orienté objet, centré sur les données (C++ comme) |
Compilation du nuanceur intégrée à l’API graphique | Le compilateur HLSL compile le nuanceur en une représentation binaire intermédiaire avant que Direct3D ne le passe au pilote.
Notez que cette représentation binaire est indépendante du matériel. Il est généralement compilé au moment de la génération de l’application, plutôt qu’au moment de l’exécution de l’application.
|
Modificateurs de stockage variable | Mémoires tampons constantes et transferts de données via des déclarations de disposition d’entrée |
Type de vecteur classique : vec2/3/4 lowp, mediump, highp |
Type de vecteur classique : float2/3/4 min10float, min16float |
texture2D [Fonction] | texture. Exemple [type de données. Fonction] |
sampler2D [datatype] | Texture2D [type de données] |
Matrices principales de lignes (par défaut) | Matrices principales de colonnes (par défaut)
Remarque : Utilisez le modificateur de type row_major pour modifier la disposition d’une variable. Pour plus d’informations, consultez Syntaxe des variables. Vous pouvez également spécifier un indicateur de compilateur ou un pragma pour modifier la valeur par défaut globale.
|
Nuanceur de fragments | Nuanceur de pixels |
Notez que HLSL a des textures et des échantillonneurs sous la forme de deux objets distincts. Dans GLSL, comme Direct3D 9, la liaison de texture fait partie de l’état de l’échantillonneur.
Dans GLSL, vous présentez une grande partie de l’état OpenGL en tant que variables globales prédéfinies. Par exemple, avec GLSL, vous utilisez la variable gl_Position pour spécifier la position de vertex et la variable gl_FragColor pour spécifier la couleur du fragment. Dans HLSL, vous passez explicitement l’état Direct3D du code de l’application au nuanceur. Par exemple, avec Direct3D et HLSL, l’entrée du nuanceur de vertex doit correspondre au format de données dans la mémoire tampon de vertex, et la structure d’une mémoire tampon constante dans le code de l’application doit correspondre à la structure d’une mémoire tampon constante (cbuffer) dans le code du nuanceur.
Portage des variables GLSL vers HLSL
Dans GLSL, vous appliquez des modificateurs (qualificateurs) à une déclaration de variable de nuanceur globale pour donner à cette variable un comportement spécifique dans vos nuanceurs. Dans HLSL, vous n’avez pas besoin de ces modificateurs, car vous définissez le flux du nuanceur avec les arguments que vous passez à votre nuanceur et que vous revenez de votre nuanceur.
Comportement des variables GLSL | ÉQUIVALENT HLSL |
---|---|
uniforme Vous transmettez une variable uniforme à partir du code de l’application dans les nuanceurs de vertex et de fragments. Vous devez définir les valeurs de tous les uniformes avant de dessiner des triangles avec ces nuanceurs afin que leurs valeurs restent les mêmes tout au long du dessin d’un maillage de triangles. Ces valeurs sont uniformes. Certains uniformes sont définis pour l’ensemble du cadre et d’autres sont uniques à une paire de nuanceurs de vertex-pixels particulière. Les variables uniformes sont des variables par polygone. |
Utilisez une mémoire tampon constante. Découvrez comment : créer une mémoire tampon constante et des constantes de nuanceur. |
variable Vous initialisez une variable variable à l’intérieur du nuanceur de vertex et passez-la à une variable identique nommée dans le nuanceur de fragments. Étant donné que le nuanceur de vertex définit uniquement la valeur des variables variables à chaque vertex, le rastériseur interpole ces valeurs (de manière correcte dans la perspective) pour générer les valeurs par fragment à passer dans le nuanceur de fragments. Ces variables varient selon chaque triangle. |
Utilisez la structure que vous revenez de votre nuanceur de vertex comme entrée à votre nuanceur de pixels. Vérifiez que les valeurs sémantiques correspondent. |
attribute Un attribut fait partie de la description d’un sommet que vous passez du code de l’application au nuanceur de vertex seul. Contrairement à un uniforme, vous définissez la valeur de chaque attribut pour chaque vertex, ce qui, à son tour, permet à chaque vertex d’avoir une valeur différente. Les variables d’attribut sont des variables par vertex. |
Définissez une mémoire tampon de vertex dans votre code d’application Direct3D et faites-la correspondre à l’entrée de vertex définie dans le nuanceur de vertex. Si vous le souhaitez, définissez une mémoire tampon d’index. Découvrez comment : créer une mémoire tampon de vertex et comment : créer une mémoire tampon d’index. Créez une disposition d’entrée dans votre code d’application Direct3D et faites correspondre les valeurs sémantiques avec celles de l’entrée de vertex. Consultez Créer la disposition d’entrée. |
const Constantes compilées dans le nuanceur et ne changent jamais. |
Utilisez un const statique. statique signifie que la valeur n’est pas exposée aux mémoires tampons constantes, const signifie que le nuanceur ne peut pas modifier la valeur. Par conséquent, la valeur est connue au moment de la compilation en fonction de son initialiseur. |
Dans GLSL, les variables sans modificateurs sont simplement des variables globales ordinaires privées à chaque nuanceur.
Lorsque vous transmettez des données à des textures (Texture2D dans HLSL) et à leurs échantillonneurs associés (SamplerState dans HLSL), vous les déclarez généralement en tant que variables globales dans le nuanceur de pixels.
Portage des types GLSL vers HLSL
Utilisez ce tableau pour porter vos types GLSL vers HLSL.
Type GLSL | Type HLSL |
---|---|
types scalaires : float, int, bool | types scalaires : float, int, bool également, uint, double Pour plus d’informations, consultez Types scalaires. |
type de vecteur
|
type de vecteur
Pour plus d’informations, consultez Le type de vecteur et les mots clés. vector est également un type défini comme float4 (typedef vector <float, 4> vector ;). Pour plus d’informations, consultez Type défini par l’utilisateur. |
type de matrice
|
type de matrice
Vous pouvez également utiliser le type de matrice pour définir une matrice. Par exemple : float de matrice <, 2, 2> fMatrix = {0.0f, 0.1, 2.1f, 2.2f} ; la matrice est également un type défini comme float4x4 (matrice <typedef float, 4, 4> matrice ;). Pour plus d’informations, consultez Type défini par l’utilisateur. |
qualificateurs de précision pour float, int, sampler
|
types de précision
Pour plus d’informations, consultez Types scalaires et utilisation de HLSL précision minimale. |
sampler2D | Texture2D |
samplerCube | TextureCube |
Portage de variables globales prédéfinies GLSL vers HLSL
Utilisez cette table pour porter des variables globales prédéfinies GLSL vers HLSL.
Variable globale prédéfinie GLSL | Sémantique HLSL |
---|---|
gl_Position Cette variable est de type vec4. Position de vertex par exemple - gl_Position = position ; |
SV_Position POSITION dans Direct3D 9 Cette sémantique est de type float4. Sortie du nuanceur de vertex Position de vertex par exemple - float4 vPosition : SV_Position ; |
gl_PointSize Cette variable est de type float. Taille d’impression |
PSIZE Aucune signification, sauf si vous ciblez Direct3D 9 Cette sémantique est float de type. Sortie du nuanceur de vertex Taille d’impression |
gl_FragColor Cette variable est de type vec4. Couleur de fragment par exemple - gl_FragColor = vec4(colorVarying, 1.0) ; |
SV_Target COULEUR dans Direct3D 9 Cette sémantique est de type float4. Sortie du nuanceur de pixels Couleur de pixel par exemple - Float4 Color[4] : SV_Target ; |
gl_FragData[n] Cette variable est de type vec4. Couleur de fragment pour la pièce jointe de couleur n |
SV_Target[n] Cette sémantique est de type float4. Valeur de sortie du nuanceur de pixels stockée dans n cible de rendu, où 0 <= n <= 7. |
gl_FragCoord Cette variable est de type vec4. Position des fragments dans la mémoire tampon d’images |
SV_Position Non disponible dans Direct3D 9 Cette sémantique est de type float4. Entrée du nuanceur de pixels Coordonnées d’espace d’écran par exemple - float4 screenSpace : SV_Position |
gl_FrontFacing Cette variable est de type bool. Détermine si le fragment appartient à une primitive frontale. |
SV_IsFrontFace VFACE dans Direct3D 9 SV_IsFrontFace est de type bool. VFACE est de type float. Entrée du nuanceur de pixels Primitive face à |
gl_PointCoord Cette variable est de type vec2. Position de fragment dans un point (rastérisation de point uniquement) |
SV_Position VPOS dans Direct3D 9 SV_Position est de type float4. VPOS est de type float2. Entrée du nuanceur de pixels Position du pixel ou de l’exemple dans l’espace d’écran par exemple - pos float4 : SV_Position |
gl_FragDepth Cette variable est de type float. Données de mémoire tampon de profondeur |
SV_Depth PROFONDEUR dans Direct3D 9 SV_Depth est de type float. Sortie du nuanceur de pixels Données de mémoire tampon de profondeur |
Vous utilisez la sémantique pour spécifier la position, la couleur, et ainsi de suite pour l’entrée de nuanceur de vertex et l’entrée de nuanceur de pixels. Vous devez correspondre aux valeurs sémantiques de la disposition d’entrée avec l’entrée du nuanceur de vertex. Pour obtenir des exemples, consultez Exemples de portage des variables GLSL vers HLSL. Pour plus d’informations sur la sémantique HLSL, consultez Sémantiques.
Exemples de portage de variables GLSL vers HLSL
Ici, nous montrons des exemples d’utilisation de variables GLSL dans le code OpenGL/GLSL, puis l’exemple équivalent dans le code Direct3D/HLSL.
Uniform, attribut et variable dans GLSL
Code d’application OpenGL
// 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;
Code du nuanceur de vertex GLSL
//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
}
Code du nuanceur de fragment GLSL
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);
}
Mémoires tampons constantes et transferts de données dans HLSL
Voici un exemple de la façon dont vous transmettez des données au nuanceur de vertex HLSL qui transite ensuite vers le nuanceur de pixels. Dans votre code d’application, définissez un sommet et une mémoire tampon constante. Ensuite, dans votre code de nuanceur de vertex, définissez la mémoire tampon constante en tant que cbuffer et stockez les données par vertex et les données d’entrée du nuanceur de pixels. Ici, nous utilisons des structures appelées VertexShaderInput et PixelShaderInput.
Code de l’application Direct3D
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.
Code du nuanceur de vertex HLSL
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;
}
Code du nuanceur de pixels HLSL
// 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;
}
Exemples de portage du code de rendu OpenGL vers Direct3D
Ici, nous montrons un exemple de rendu dans le code OpenGL ES 2.0, puis l’exemple équivalent dans le code Direct3D 11.
Code de rendu OpenGL
// 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);
Code de rendu Direct3D
// 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);
Rubriques connexes