Compartir a través de


Comparación de la canalización de sombreador openGL ES 2.0 con Direct3D

API importantes

Conceptualmente, la canalización de sombreador de Direct3D 11 es muy similar a la de OpenGL ES 2.0. Sin embargo, en términos de diseño de API, los componentes principales para crear y administrar las fases del sombreador son partes de dos interfaces principales, ID3D11Device1 y ID3D11DeviceContext1. En este tema se intentan asignar patrones comunes de api de canalización de sombreador de OpenGL ES 2.0 a los equivalentes de Direct3D 11 en estas interfaces.

Revisión de la canalización de sombreador de Direct3D 11

Los objetos de sombreador se crean con métodos en la interfaz ID3D11Device1, como ID3D11Device1::CreateVertexShader y ID3D11Device1::CreatePixelShader.

La canalización de gráficos direct3D 11 se administra mediante instancias de la interfaz ID3D11DeviceContext1 y tiene las siguientes fases:

  • Fase de ensamblador de entrada. La fase del ensamblador de entrada proporciona datos (triángulos, líneas y puntos) a la canalización. Los métodos ID3D11DeviceContext1 que admiten esta fase tienen el prefijo "IA".
  • Fase del sombreador de vértices: la fase del sombreador de vértices procesa vértices, normalmente realizando operaciones como transformaciones, skinning e iluminación. Un sombreador de vértices siempre toma un solo vértice de entrada y genera un único vértice de salida. Los métodos ID3D11DeviceContext1 que admiten esta fase tienen el prefijo "VS".
  • Fase de salida de flujo: la fase de salida de flujo transmite datos primitivos de la canalización a la memoria en su camino al rasterizador. Los datos se pueden transmitir o pasar al rasterizador. Los datos transmitidos a la memoria se pueden volver a recircular en la canalización como datos de entrada o de lectura desde la CPU. Los métodos ID3D11DeviceContext1 que admiten esta fase tienen el prefijo "SO".
  • Fase de rasterizador: el rasterizador clips primitivos, prepara primitivos para el sombreador de píxeles y determina cómo invocar sombreadores de píxeles. Puede deshabilitar la rasterización indicando a la canalización que no hay ningún sombreador de píxeles (establezca la fase del sombreador de píxeles en NULL con ID3D11DeviceContext::P SSetShader) y deshabilite las pruebas de profundidad y galería de símbolos (establezca DepthEnable y StencilEnable en FALSE en D3D11_DEPTH_STENCIL_DESC). Aunque está deshabilitado, los contadores de canalización relacionados con la rasterización no se actualizarán.
  • Fase del sombreador de píxeles: la fase del sombreador de píxeles recibe datos interpolados para un primitivo y genera datos por píxel, como el color. Los métodos ID3D11DeviceContext1 que admiten esta fase tienen el prefijo "PS".
  • Fase de fusión de salida: la fase de fusión de salida combina varios tipos de datos de salida (valores de sombreador de píxeles, información de profundidad y galería de símbolos) con el contenido del destino de representación y los búferes de profundidad y galería de símbolos para generar el resultado final de la canalización. Los métodos ID3D11DeviceContext1 que admiten esta fase tienen el prefijo "OM".

(También hay etapas para sombreadores de geometría, sombreadores de casco, tesselators y sombreadores de dominio, pero como no tienen análogos en OpenGL ES 2.0, no los analizaremos aquí). Para obtener una lista completa de los métodos de estas fases, consulte las páginas de referencia ID3D11DeviceContext e ID3D11DeviceContext1. ID3D11DeviceContext1 extiende ID3D11DeviceContext para Direct3D 11.

Creación de un sombreador

En Direct3D, los recursos del sombreador no se crean antes de compilarlos y cargarlos; en su lugar, el recurso se crea cuando se carga HLSLis. Por lo tanto, no hay ninguna función análoga directamente a glCreateShader, que crea un recurso de sombreador inicializado de un tipo específico (como GL_VERTEX_SHADER o GL_FRAGMENT_SHADER). En su lugar, los sombreadores se crean después de cargar HLSL con funciones específicas como ID3D11Device1::CreateVertexShader y ID3D11Device1::CreatePixelShader, y que toman el tipo y el HLSL compilado como parámetros.

OpenGL ES 2.0 Direct3D 11
glCreateShader Llame a ID3D11Device1::CreateVertexShader e ID3D11Device1::CreatePixelShader después de cargar correctamente el objeto sombreador compilado, pasándoles el inicio de sesión único como búfer.

 

Compilación de un sombreador

Los sombreadores direct3D deben precompilarse como archivos de objeto de sombreador compilado (.cso) en aplicaciones de Plataforma universal de Windows (UWP) y cargarse con una de las API de archivos de Windows Runtime. (Las aplicaciones de escritorio pueden compilar los sombreadores desde archivos de texto o cadena en tiempo de ejecución). Los archivos CSO se compilan a partir de los archivos .hlsl que forman parte del proyecto de Microsoft Visual Studio y conservan los mismos nombres, solo con una extensión de archivo .cso. Asegúrese de que se incluyen con el paquete al enviar.

OpenGL ES 2.0 Direct3D 11
glCompileShader N/A. Compile los sombreadores en archivos .cso en Visual Studio e incluítelos en el paquete.
Uso de glGetShaderiv para el estado de compilación N/A. Consulte la salida de compilación del compilador FX (FXC) de Visual Studio si hay errores en la compilación. Si la compilación se realiza correctamente, se crea un archivo CSO correspondiente.

 

Carga de un sombreador

Como se indica en la sección sobre cómo crear un sombreador, Direct3D 11 crea el sombreador cuando el archivo CSO correspondiente se carga en un búfer y se pasa a uno de los métodos de la tabla siguiente.

OpenGL ES 2.0 Direct3D 11
ShaderSource Llame a ID3D11Device1::CreateVertexShader y ID3D11Device1::CreatePixelShader después de cargar correctamente el objeto sombreador compilado.

 

Configuración de la canalización

OpenGL ES 2.0 tiene el objeto "programa de sombreador", que contiene varios sombreadores para su ejecución. Los sombreadores individuales se adjuntan al objeto de programa de sombreador. Sin embargo, en Direct3D 11, trabaja directamente con el contexto de representación (ID3D11DeviceContext1) y crea sombreadores en él.

OpenGL ES 2.0 Direct3D 11
glCreateProgram N/A. Direct3D 11 no usa la abstracción de objetos de programa de sombreador.
glLinkProgram N/A. Direct3D 11 no usa la abstracción de objetos de programa de sombreador.
glUseProgram N/A. Direct3D 11 no usa la abstracción de objetos de programa de sombreador.
glGetProgramiv Use la referencia que creó en ID3D11DeviceContext1.

 

Cree una instancia de ID3D11DeviceContext1 e ID3D11Device1 con el método estático D3D11CreateDevice.

Microsoft::WRL::ComPtr<ID3D11Device1>          m_d3dDevice;
Microsoft::WRL::ComPtr<ID3D11DeviceContext1>  m_d3dContext;

// ...

D3D11CreateDevice(
  nullptr, // Specify nullptr to use the default adapter.
  D3D_DRIVER_TYPE_HARDWARE,
  nullptr,
  creationFlags, // Set set debug and Direct2D compatibility flags.
  featureLevels, // List of feature levels this app can support.
  ARRAYSIZE(featureLevels),
  D3D11_SDK_VERSION, // Always set this to D3D11_SDK_VERSION for UWP apps.
  &device, // Returns the Direct3D device created.
  &m_featureLevel, // Returns feature level of device created.
  &m_d3dContext // Returns the device's immediate context.
);

Establecimiento de las ventanillas

Establecer una ventanilla en Direct3D 11 es muy similar a cómo se establece una ventanilla en OpenGL ES 2.0. En Direct3D 11, llame a ID3D11DeviceContext::RSSetViewports con un CD3D11_VIEWPORT configurado.

Direct3D 11: Establecer una ventanilla.

CD3D11_VIEWPORT viewport(
        0.0f,
        0.0f,
        m_d3dRenderTargetSize.Width,
        m_d3dRenderTargetSize.Height
        );
m_d3dContext->RSSetViewports(1, &viewport);
OpenGL ES 2.0 Direct3D 11
glViewport CD3D11_VIEWPORT, ID3D11DeviceContext::RSSetViewports

 

Configuración de los sombreadores de vértices

La configuración de un sombreador de vértices en Direct3D 11 se realiza cuando se carga el sombreador. Los uniformes se pasan como búferes de constantes mediante ID3D11DeviceContext1::VSSetConstantBuffers1.

OpenGL ES 2.0 Direct3D 11
glAttachShader ID3D11Device1::CreateVertexShader
glGetShaderiv, glGetShaderSource ID3D11DeviceContext1::VSGetShader
glGetUniformfv, glGetUniformiv ID3D11DeviceContext1::VSGetConstantBuffers1.

 

Configuración de los sombreadores de píxeles

La configuración de un sombreador de píxeles en Direct3D 11 se realiza cuando se carga el sombreador. Los uniformes se pasan como búferes de constantes mediante ID3D11DeviceContext1::P SSetConstantBuffers1.

OpenGL ES 2.0 Direct3D 11
glAttachShader ID3D11Device1::CreatePixelShader
glGetShaderiv, glGetShaderSource ID3D11DeviceContext1::P SGetShader
glGetUniformfv, glGetUniformiv ID3D11DeviceContext1::P SGetConstantBuffers1.

 

Generación de los resultados finales

Una vez completada la canalización, se dibujan los resultados de las fases del sombreador en el búfer de reserva. En Direct3D 11, al igual que con Open GL ES 2.0, esto implica llamar a un comando draw para generar los resultados como un mapa de colores en el búfer de reserva y, a continuación, enviar ese búfer de reserva a la pantalla.

OpenGL ES 2.0 Direct3D 11
glDrawElements ID3D11DeviceContext1::D raw, ID3D11DeviceContext1::D rawIndexed (u otros métodos Draw* en ID3D11DeviceContext1).
eglSwapBuffers IDXGISwapChain1::P resent1

 

Migración de GLSL a HLSL

GLSL y HLSL no son muy diferentes más allá de la compatibilidad de tipos complejos y la sintaxis de cierta sintaxis general. Muchos desarrolladores encuentran que es más fácil migrar entre los dos mediante el alias de instrucciones y definiciones comunes de OpenGL ES 2.0 a su equivalente HLSL. Tenga en cuenta que Direct3D usa la versión del modelo de sombreador para expresar el conjunto de características de la HLSL compatible con una interfaz gráfica; OpenGL tiene una especificación de versión diferente para HLSL. En la tabla siguiente se intenta dar una idea aproximada de los conjuntos de características de lenguaje de sombreador definidos para Direct3D 11 y OpenGL ES 2.0 en términos de la versión del otro.

Lenguaje de sombreador Versión de la característica GLSL Modelo de sombreador direct3D
Direct3D 11 HLSL ~4.30. SM 5.0
GLSL ES para OpenGL ES 2.0 1.40. Las implementaciones anteriores de GLSL ES para OpenGL ES 2.0 pueden usar 1.10 a 1.30. Compruebe el código original con glGetString(GL_SHADING_LANGUAGE_VERSION) o glGetString(SHADING_LANGUAGE_VERSION) para determinarlo. ~SM 2.0

 

Para obtener más detalles sobre las diferencias entre los dos lenguajes de sombreador, así como las asignaciones de sintaxis comunes, lea la referencia de GLSL a HLSL.

Migración de los intrínsecos de OpenGL a la semántica de HLSL

La semántica de HLSL de Direct3D 11 son cadenas que, como un nombre uniforme o de atributo, se usan para identificar un valor pasado entre la aplicación y un programa de sombreador. Aunque pueden ser cualquiera de una variedad de cadenas posibles, el procedimiento recomendado es usar una cadena como POSITION o COLOR que indique el uso. Estas semánticas se asignan al construir un búfer de constantes o un diseño de entrada de búfer. También puede anexar un número entre 0 y 7 a la semántica para que use registros independientes para valores similares. Por ejemplo: COLOR0, COLOR1, COLOR2...

La semántica que tiene el prefijo "SV_" es la semántica del valor del sistema escrita por el programa de sombreador; La propia aplicación (que se ejecuta en la CPU) no puede modificarla. Normalmente, contienen valores que son entradas o salidas de otra fase del sombreador en la canalización de gráficos, o que la GPU genera por completo.

Además, SV_ semántica tienen comportamientos diferentes cuando se usan para especificar la entrada o salida de una fase del sombreador. Por ejemplo, SV_POSITION (salida) contiene los datos de vértices transformados durante la fase del sombreador de vértices y SV_POSITION (entrada) contiene los valores de posición de píxel interpolados durante la rasterización.

Estas son algunas asignaciones para los intrínsecos comunes del sombreador de OpenGL ES 2.0:

Valor del sistema OpenGL Usar esta semántica de HLSL
gl_Position POSITION(n) para los datos del búfer de vértices. SV_POSITION proporciona una posición de píxel al sombreador de píxeles y la aplicación no puede escribirla.
gl_Normal NORMAL(n) para los datos normales proporcionados por el búfer de vértices.
gl_TexCoord[n] TEXCOORD(n) para los datos de coordenadas uv de textura (ST en alguna documentación de OpenGL) proporcionados a un sombreador.
gl_FragColor COLOR(n) para los datos de color RGBA proporcionados a un sombreador. Tenga en cuenta que se trata de forma idéntica a los datos de coordenadas; la semántica simplemente le ayuda a identificar que es datos de color.
gl_FragData[n] SV_Target[n] para escribir desde un sombreador de píxeles en una textura de destino u otro búfer de píxeles.

 

El método por el que se codifica para la semántica no es el mismo que el uso de intrínsecos en OpenGL ES 2.0. En OpenGL, puede acceder a muchos de los intrínsecos directamente sin ninguna configuración o declaración; en Direct3D, debe declarar un campo en un búfer de constantes específico para usar una semántica determinada o declararlo como valor devuelto para el método main() de un sombreador.

Este es un ejemplo de una semántica usada en una definición de búfer de constantes:

struct VertexShaderInput
{
  float3 pos : POSITION;
  float3 color : COLOR0;
};

// The position is interpolated to the pixel value by the system. The per-vertex color data is also interpolated and passed through the pixel shader. 
struct PixelShaderInput
{
  float4 pos : SV_POSITION;
  float3 color : COLOR0;
};

Este código define un par de búferes de constantes simples

Y este es un ejemplo de una semántica usada para definir el valor devuelto por un sombreador de fragmentos:

// A pass-through for the (interpolated) color data.
float4 main(PixelShaderInput input) : SV_TARGET
{
  return float4(input.color,1.0f);
}

En este caso, SV_TARGET es la ubicación del destino de representación en la que se escribe el color del píxel (definido como vector con cuatro valores flotantes) cuando el sombreador completa la ejecución.

Para obtener más información sobre el uso de la semántica con Direct3D, lea Semántica de HLSL.