Compartir a través de


Referencia de GLSL a HLSL

El código de OpenGL Shader Language (GLSL) se debe migrar al código de Lenguaje de sombreador de alto nivel (HLSL) de Microsoft al migrar la arquitectura de gráficos de OpenGL ES 2.0 a Direct3D 11 para crear un juego para Plataforma universal de Windows (UWP). El GLSL al que se hace referencia aquí es compatible con OpenGL ES 2.0; HLSL es compatible con Direct3D 11. Para obtener información sobre las diferencias entre Direct3D 11 y versiones anteriores de Direct3D, consulta Asignación de características.

Comparación de OpenGL ES 2.0 con Direct3D 11

OpenGL ES 2.0 y Direct3D 11 tienen muchas similitudes. Ambos tienen canalizaciones de representación similares y características de gráficos. Pero Direct3D 11 es una implementación de representación y una API, no una especificación; OpenGL ES 2.0 es una especificación de representación y una API, no una implementación. Direct3D 11 y OpenGL ES 2.0 suelen diferir de estas maneras:

OpenGL ES 2.0 Direct3D 11
Especificación independiente del hardware y del sistema operativo con implementaciones proporcionadas por el proveedor Implementación de Microsoft de abstracción de hardware y certificación en plataformas Windows
Abstraido para la diversidad de hardware, el entorno de ejecución administra la mayoría de los recursos. Acceso directo al diseño de hardware; la aplicación puede administrar los recursos y el procesamiento
Proporciona módulos de nivel superior a través de bibliotecas de terceros (por ejemplo, Simple DirectMedia Layer (SDL)) Los módulos de nivel superior, como Direct2D, se basan en módulos inferiores para simplificar el desarrollo de aplicaciones de Windows
Los proveedores de hardware diferencian a través de extensiones Microsoft agrega características opcionales a la API de forma genérica para que no sean específicas de ningún proveedor de hardware determinado.

 

GLSL y HLSL suelen diferir de estas maneras:

GLSL HLSL
Procedimientos, centrados en pasos (C como) Orientado a objetos, centrados en datos (como C++)
Compilación de sombreador integrada en la API de gráficos El compilador HLSL compila el sombreador en una representación binaria intermedia antes de que Direct3D lo pase al controlador.
Nota Esta representación binaria es independiente del hardware. Normalmente se compila en tiempo de compilación de la aplicación, en lugar de en tiempo de ejecución de la aplicación.
 
Modificadores de almacenamiento de variables Búferes de constantes y transferencias de datos mediante declaraciones de diseño de entrada

Tipos

Tipo de vector típico: vec2/3/4

lowp, mediump, highp

Tipo de vector típico: float2/3/4

min10float, min16float

texture2D [Function] textura. Ejemplo [tipo de datos. Función]
sampler2D [datatype] Texture2D [tipo de datos]
Matrices principales de fila (valor predeterminado) Matrices principales de columna (valor predeterminado)
Nota Use el modificador de tipo row_major para cambiar el diseño de una variable. Para obtener más información, consulta Sintaxis de variable. También puede especificar una marca del compilador o una pragma para cambiar el valor predeterminado global.
 
Sombreador de fragmentos Sombreador de píxeles

 

Nota HLSL tiene texturas y muestreadores como dos objetos independientes. En GLSL, como Direct3D 9, el enlace de textura forma parte del estado del muestreador.

 

En GLSL, presenta gran parte del estado openGL como variables globales predefinidas. Por ejemplo, con GLSL, se usa la variable gl_Position para especificar la posición del vértice y la variable gl_FragColor para especificar el color del fragmento. En HLSL, pasas el estado de Direct3D explícitamente desde el código de la aplicación al sombreador. Por ejemplo, con Direct3D y HLSL, la entrada al sombreador de vértices debe coincidir con el formato de datos en el búfer de vértices y la estructura de un búfer de constantes en el código de la aplicación debe coincidir con la estructura de un búfer de constantes (cbuffer) en el código del sombreador.

Migración de variables GLSL a HLSL

En GLSL, se aplican modificadores (calificadores) a una declaración de variable de sombreador global para proporcionar a esa variable un comportamiento específico en los sombreadores. En HLSL, no necesita estos modificadores porque define el flujo del sombreador con los argumentos que se pasan al sombreador y que se devuelven desde el sombreador.

Comportamiento de las variables GLSL Equivalente de HLSL

uniforme

Se pasa una variable uniforme desde el código de la aplicación a sombreadores de vértices y fragmentos o ambos. Debe establecer los valores de todos los uniformes antes de dibujar los triángulos con esos sombreadores para que sus valores permanezcan iguales a lo largo del dibujo de una malla de triángulo. Estos valores son uniformes. Algunos uniformes se establecen para todo el marco y otros de forma exclusiva para un par de sombreador de vértices y píxeles concretos.

Las variables uniformes son variables por polígono.

Use el búfer de constantes.

Vea Cómo: Crear un búfer de constantes y constantes de sombreador.

variable

Inicializa una variable variable dentro del sombreador de vértices y la pasa a una variable con nombre idéntico en el sombreador de fragmentos. Dado que el sombreador de vértices solo establece el valor de las variables variables en cada vértice, el rasterizador interpola esos valores (de manera correcta desde la perspectiva) para generar valores por fragmento para pasar al sombreador de fragmentos. Estas variables varían en cada triángulo.

Use la estructura que devuelve del sombreador de vértices como entrada para el sombreador de píxeles. Asegúrese de que los valores semánticos coinciden.

attribute

Un atributo forma parte de la descripción de un vértice que se pasa desde el código de la aplicación al sombreador de vértices solo. A diferencia de un uniforme, se establece el valor de cada atributo para cada vértice, que, a su vez, permite que cada vértice tenga un valor diferente. Las variables de atributo son variables por vértice.

Defina un búfer de vértices en el código de la aplicación direct3D y coincida con la entrada de vértices definida en el sombreador de vértices. Opcionalmente, defina un búfer de índice. Vea Cómo: Crear un búfer de vértices y Cómo: Crear un búfer de índice.

Cree un diseño de entrada en el código de la aplicación direct3D y coincida con los valores semánticos con los de la entrada de vértices. Consulte Creación del diseño de entrada.

const

Constantes que se compilan en el sombreador y nunca cambian.

Use un const estático. static significa que el valor no está expuesto a búferes de constantes, const significa que el sombreador no puede cambiar el valor. Por lo tanto, el valor se conoce en tiempo de compilación en función de su inicializador.

 

En GLSL, las variables sin modificadores son simplemente variables globales normales que son privadas para cada sombreador.

Cuando se pasan datos a texturas (Texture2D en HLSL) y sus muestradores asociados (SamplerState en HLSL), normalmente se declaran como variables globales en el sombreador de píxeles.

Migración de tipos GLSL a HLSL

Use esta tabla para migrar los tipos GLSL a HLSL.

Tipo GLSL Tipo HLSL
tipos escalares: float, int, bool

tipos escalares: float, int, bool

también, uint, double

Para obtener más información, consulta Tipos escalares.

tipo de vector

  • vector de punto flotante: vec2, vec3, vec4
  • Vector booleano: bvec2, bvec3, bvec4
  • vector entero con signo: ivec2, ivec3, ivec4

tipo de vector

  • float2, float3, float4 y float1
  • bool2, bool3, bool4 y bool1
  • int2, int3, int4 e int1
  • Estos tipos también tienen expansiones vectoriales similares a float, bool e int:

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

Para obtener más información, consulta Tipo de vector y palabras clave.

vector también es el tipo definido como float4 (tipodef vector <float, 4> vector;). Para obtener más información, consulta Tipo definido por el usuario.

tipo de matriz

  • mat2: matriz float de 2x2
  • mat3: matriz float de 3x3
  • mat4: matriz float de 4x4

tipo de matriz

  • float2x2
  • float3x3
  • float4x4
  • además, float1x1, float1x2, float1x3, float1x4, float2x1, float2x3, float2x4, float3x1, float3x2, float3x4, float4x1, float4x2, float4x3
  • Estos tipos también tienen expansiones de matriz similares a float:

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

También puede usar el tipo de matriz para definir una matriz.

Por ejemplo: matriz <float, 2, 2> fMatrix = {0.0f, 0.1, 2.1f, 2.2f};

matrix también es el tipo definido como float4x4 (matriz de definición <de tipo float, 4, 4> matriz;). Para obtener más información, consulta Tipo definido por el usuario.

calificadores de precisión para float, int, sampler

  • highp

    Este calificador proporciona requisitos de precisión mínimos que son mayores que los proporcionados por min16float y menor que un float de 32 bits completo. Equivalente en HLSL es:

    highp float:> float

    highp int -> int

  • mediump

    Este calificador aplicado a float e int es equivalente a min16float y min12int en HLSL. Mínimo 10 bits de mantisa, no como min10float.

  • lowp

    Este calificador aplicado a float proporciona un intervalo de punto flotante de -2 a 2. Equivalente a min10float en HLSL.

tipos de precisión

  • min16float: valor mínimo de punto flotante de 16 bits
  • min10float

    Valor mínimo de punto fijo con signo de 2,8 bits (2 bits de número entero y componente fraccionario de 8 bits). El componente fraccionario de 8 bits puede ser inclusivo de 1 en lugar de exclusivo para darle el intervalo inclusivo completo de -2 a 2.

  • min16int: entero de 16 bits con signo mínimo
  • min12int: entero de 12 bits con signo mínimo

    Este tipo es para 10Level9 (9_x niveles de características) en los que los enteros se representan mediante números de punto flotante. Esta es la precisión que puede obtener al emular un entero con un número de punto flotante de 16 bits.

  • min16uint: entero de 16 bits sin signo mínimo

Para obtener más información, consulta Tipos escalares y Uso de la precisión mínima de HLSL.

sampler2D Texture2D
samplerCube TextureCube

 

Migración de variables globales predefinidas de GLSL a HLSL

Use esta tabla para migrar variables globales predefinidas de GLSL a HLSL.

Variable global predefinida GLSL Semántica de HLSL

gl_Position

Esta variable es de tipo vec4.

Posición del vértice

por ejemplo: gl_Position = posición;

SV_Position

POSICIÓN en Direct3D 9

Esta semántica es el tipo float4.

Salida del sombreador de vértices

Posición del vértice

por ejemplo: float4 vPosition : SV_Position;

gl_PointSize

Esta variable es de tipo float.

Tamaño de punto

PSIZE

Ningún significado a menos que tenga como destino Direct3D 9

Esta semántica es de tipo float.

Salida del sombreador de vértices

Tamaño de punto

gl_FragColor

Esta variable es de tipo vec4.

Color del fragmento

por ejemplo: gl_FragColor = vec4(colorVarying, 1.0);

SV_Target

COLOR en Direct3D 9

Esta semántica es el tipo float4.

Salida del sombreador de píxeles

Color de píxel

por ejemplo: float4 Color[4] : SV_Target;

gl_FragData[n]

Esta variable es de tipo vec4.

Color de fragmento para datos adjuntos de color n

SV_Target[n]

Esta semántica es el tipo float4.

Valor de salida del sombreador de píxeles almacenado en n destino de representación, donde 0 <= n <= 7.

gl_FragCoord

Esta variable es de tipo vec4.

Posición de fragmento dentro del búfer de fotogramas

SV_Position

No disponible en Direct3D 9

Esta semántica es el tipo float4.

Entrada del sombreador de píxeles

Coordenadas de espacio de pantalla

por ejemplo: screenSpace float4 : SV_Position

gl_FrontFacing

Esta variable es de tipo bool.

Determina si el fragmento pertenece a un primitivo orientado al frente.

SV_IsFrontFace

VFACE en Direct3D 9

SV_IsFrontFace es de tipo bool.

VFACE es tipo float.

Entrada del sombreador de píxeles

Primitivo orientado a

gl_PointCoord

Esta variable es de tipo vec2.

Posición de fragmento dentro de un punto (solo rasterización de puntos)

SV_Position

VPOS en Direct3D 9

SV_Position es de tipo float4.

VPOS es el tipo float2.

Entrada del sombreador de píxeles

Posición de píxel o de ejemplo en el espacio de pantalla

por ejemplo: float4 pos : SV_Position

gl_FragDepth

Esta variable es de tipo float.

Datos de búfer de profundidad

SV_Depth

PROFUNDIDAD en Direct3D 9

SV_Depth es el tipo float.

Salida del sombreador de píxeles

Datos de búfer de profundidad

 

La semántica se usa para especificar la posición, el color, etc. para la entrada del sombreador de vértices y la entrada del sombreador de píxeles. Debe coincidir con los valores semánticos del diseño de entrada con la entrada del sombreador de vértices. Para obtener ejemplos, consulte Ejemplos de migración de variables GLSL a HLSL. Para obtener más información sobre la semántica de HLSL, consulta Semántica.

Ejemplos de migración de variables GLSL a HLSL

Aquí se muestran ejemplos de uso de variables GLSL en código OpenGL/GLSL y, a continuación, el ejemplo equivalente en código Direct3D/HLSL.

Uniforme, atributo y variable en GLSL

Código de la aplicación 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;

Código del sombreador de vértices 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
}

Código del sombreador de fragmentos 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);
}

Búferes de constantes y transferencias de datos en HLSL

Este es un ejemplo de cómo se pasan datos al sombreador de vértices HLSL que luego fluye al sombreador de píxeles. En el código de la aplicación, defina un vértice y un búfer de constantes. A continuación, en el código del sombreador de vértices, defina el búfer de constantes como cbuffer y almacene los datos de entrada por vértice y el sombreador de píxeles. Aquí usamos estructuras denominadas VertexShaderInput y PixelShaderInput.

Código de aplicación de 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.

Código del sombreador de vértices 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;
}

Código del sombreador de píxeles 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;
}

Ejemplos de portabilidad del código de representación de OpenGL a Direct3D

Aquí se muestra un ejemplo de representación en código openGL ES 2.0 y, a continuación, el ejemplo equivalente en el código de Direct3D 11.

Código de representación de 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);

Código de representación de 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);