Uso de sombreadores en Direct3D 9

Compilar un sombreador para hardware específico

Los sombreadores se agregaron por primera vez a Microsoft DirectX en DirectX 8.0. En ese momento, se definieron varias máquinas de sombreador virtual, cada una de las cuales corresponde aproximadamente a un procesador de gráficos determinado generado por los principales proveedores de gráficos 3D. Para cada una de estas máquinas de sombreador virtual, se diseñó un lenguaje de ensamblado. Los programas escritos en los modelos de sombreador (nombres vs_1_1 y ps_1_1 - ps_1_4) eran relativamente cortos y generalmente los desarrolladores escriben directamente en el lenguaje de ensamblado adecuado. La aplicación pasaría este código de lenguaje de ensamblado legible a la biblioteca D3DX mediante D3DXAssembleShader y recuperaría una representación binaria del sombreador que, a su vez, se pasaría mediante CreateVertexShader o CreatePixelShader. Para obtener más información, consulte el kit de desarrollo de software (SDK).

La situación en Direct3D 9 es similar. Una aplicación pasa un sombreador HLSL a D3DX mediante D3DXCompileShader y obtiene una representación binaria del sombreador compilado que, a su vez, se pasa a Microsoft Direct3D mediante CreatePixelShader o CreateVertexShader. El entorno de ejecución no conoce nada sobre HLSL, solo los modelos de sombreador de ensamblado binario. Esto es bueno porque significa que el compilador HLSL se puede actualizar independientemente del entorno de ejecución de Direct3D. También puede compilar sombreadores sin conexión mediante fxc.

Además del desarrollo del compilador HLSL, Direct3D 9 también introdujo los modelos de sombreador de nivel de ensamblado para exponer la funcionalidad de la última generación de hardware gráfico. Los desarrolladores de aplicaciones pueden trabajar en ensamblados para estos nuevos modelos (vs_2_0, vs_3_0, ps_2_0, ps_3_0), pero esperamos que la mayoría de los desarrolladores pasen a HLSL para el desarrollo de sombreador.

Por supuesto, la capacidad de escribir un programa HLSL para expresar un algoritmo de sombreado determinado no permite que se ejecute automáticamente en ningún hardware determinado. Una aplicación llama a D3DX para compilar un sombreador en código de ensamblado binario con D3DXCompileShader. Una de las limitaciones de este punto de entrada es un parámetro que define cuál de los modelos de nivel de ensamblado (o destinos de compilación) que el compilador HLSL debe usar para expresar el código final del sombreador. Si una aplicación está realizando la compilación del sombreador HLSL en tiempo de ejecución (en lugar de tiempo de compilación o sin conexión), la aplicación podría examinar las funcionalidades del dispositivo Direct3D y seleccionar el destino de compilación para que coincida. Si el algoritmo expresado en el sombreador HLSL es demasiado complejo para ejecutarse en el destino de compilación seleccionado, se producirá un error en la compilación. Esto significa que, aunque HLSL es una gran ventaja para el desarrollo del sombreador, no libera a los desarrolladores de las realidades de enviar juegos a un público objetivo con dispositivos gráficos de distintas funcionalidades. Como desarrollador de juegos, todavía tienes que administrar un enfoque en capas para tus objetos visuales; esto significa escribir mejores sombreadores para tarjetas gráficas más capaces y escribir versiones más básicas para tarjetas anteriores. Sin embargo, con HLSL bien escrito, esta carga se puede aliviar significativamente.

En lugar de compilar sombreadores HLSL mediante D3DX en el equipo del cliente en el tiempo de carga de la aplicación o en el primer uso, muchos desarrolladores eligen compilar su sombreador de HLSL a código de ensamblado binario antes de que se envíen. Esto mantiene su código fuente HLSL lejos de los ojos indiscretos y también garantiza que todos los sombreadores que su aplicación se ejecutará alguna vez hayan pasado por su proceso de control de calidad interno. Una utilidad conveniente para compilar sombreadores sin conexión es fxc. Esta herramienta tiene varias opciones que puede usar para compilar código para el destino de compilación especificado. Estudiar la salida desensamblado puede ser muy educativa durante el desarrollo si desea optimizar los sombreadores o, por lo general, conocer las funcionalidades de la máquina de sombreador virtual en un nivel más detallado. Estas opciones se resumen a continuación:

Inicialización de constantes de sombreador

Las constantes del sombreador se encuentran en la tabla de constantes. Se puede acceder a esto con la interfaz ID3DXConstantTable . Las variables de sombreador globales se pueden inicializar en el código del sombreador. Se inicializan en tiempo de ejecución llamando a SetDefaults.

Enlace de un parámetro de sombreador a un registro determinado

El compilador asignará automáticamente registros a variables globales. El compilador asignaría Environment al registro de sampler s0, SparkleNoise al registro de sampler s1 y k_s al registro constante c0 (suponiendo que ya no se asignaron otros registros de muestra o constantes) para las tres variables globales siguientes:

sampler Environment;
sampler SparkleNoise;
float4 k_s;

También es posible enlazar variables a un registro específico. Para forzar que el compilador asigne a un registro determinado, use la sintaxis siguiente:

register(RegisterName)

donde RegisterName es el nombre del registro específico. En los ejemplos siguientes se muestra la sintaxis de asignación de registro específica, donde el entorno de sampler se enlazará al registro de sampler s1, SparkleNoise se enlazará al registro de ejemplo s0 y k_s se enlazará al registro constante c12:

sampler Environment : register(s1);
sampler SparkleNoise : register(s0);
float4 k_s : register(c12);

Representación de un sombreador programable

Un sombreador se representa estableciendo el sombreador actual en el dispositivo, inicializando las constantes del sombreador, indicando al dispositivo dónde proceden los distintos datos de entrada y, por último, representando los primitivos. Cada uno de estos métodos se puede realizar llamando a los métodos siguientes respectivamente:

Depuración de sombreadores

La extensión DirectX para Microsoft Visual Studio .NET proporciona un depurador HLSL totalmente integrado en el entorno de desarrollo integrado (IDE) de Visual Studio .NET. Para preparar la depuración del sombreador, debe instalar las herramientas adecuadas en el equipo (consulte Depuración de sombreadores en Visual Studio (Direct3D 9)).

Guía de programación para HLSL