Usando sombreadores no Direct3D 9

Compilando um sombreador para hardware específico

Os sombreadores foram adicionados pela primeira vez ao Microsoft DirectX no DirectX 8.0. Na época, várias máquinas de sombreador virtual foram definidas, cada uma correspondendo aproximadamente a um processador gráfico específico produzido pelos principais fornecedores de gráficos 3D. Para cada uma dessas máquinas de sombreador virtual, uma linguagem de assembly foi projetada. Os programas gravados nos modelos de sombreador (nomes vs_1_1 e ps_1_1 - ps_1_4) eram relativamente curtos e geralmente eram escritos por desenvolvedores diretamente na linguagem de assembly apropriada. O aplicativo passaria esse código de linguagem de assembly legível por humanos para a biblioteca D3DX usando D3DXAssembleShader e obteria de volta uma representação binária do sombreador que, por sua vez, seria passada usando CreateVertexShader ou CreatePixelShader. Para obter mais detalhes, consulte o SDK (software development kit).

A situação no Direct3D 9 é semelhante. Um aplicativo passa um sombreador HLSL para D3DX usando D3DXCompileShader e retorna uma representação binária do sombreador compilado que, por sua vez, é passado para o Microsoft Direct3D usando CreatePixelShader ou CreateVertexShader. O runtime não sabe nada sobre HLSL, apenas os modelos de sombreador de assembly binário. Isso é bom porque significa que o compilador HLSL pode ser atualizado independentemente do runtime do Direct3D. Você também pode compilar sombreadores offline usando fxc.

Além do desenvolvimento do compilador HLSL, o Direct3D 9 também introduziu os modelos de sombreador no nível do assembly para expor a funcionalidade da última geração de hardware gráfico. Os desenvolvedores de aplicativos podem trabalhar em assembly para esses novos modelos (vs_2_0, vs_3_0, ps_2_0 ps_3_0), mas esperamos que a maioria dos desenvolvedores mude para o HLSL para desenvolvimento de sombreador.

É claro que a capacidade de escrever um programa HLSL para expressar um algoritmo de sombreamento específico não permite que ele seja executado automaticamente em um determinado hardware. Um aplicativo chama D3DX para compilar um sombreador em código de assembly binário com D3DXCompileShader. Uma das limitações com esse ponto de entrada é um parâmetro que define qual dos modelos de nível de assembly (ou destinos de compilação) o compilador HLSL deve usar para expressar o código de sombreador final. Se um aplicativo estiver fazendo a compilação do sombreador HLSL em tempo de execução (em vez de tempo de compilação ou offline), o aplicativo poderá examinar os recursos do dispositivo Direct3D e selecionar o destino de compilação a ser correspondido. Se o algoritmo expresso no sombreador HLSL for muito complexo para ser executado no destino de compilação selecionado, a compilação falhará. Isso significa que, embora o HLSL seja um grande benefício para o desenvolvimento de sombreador, ele não libera os desenvolvedores das realidades do envio de jogos para um público-alvo com dispositivos gráficos de funcionalidades variadas. Como desenvolvedor de jogos, você ainda precisa gerenciar uma abordagem em camadas para seus visuais; isso significa escrever sombreadores melhores para placas gráficas mais capazes e escrever versões mais básicas para cartões mais antigos. Com HLSL bem escrito, no entanto, esse fardo pode ser facilitado significativamente.

Em vez de compilar sombreadores HLSL usando D3DX no computador do cliente no tempo de carregamento do aplicativo ou no primeiro uso, muitos desenvolvedores optam por compilar seu sombreador de HLSL para código de assembly binário antes mesmo de serem enviados. Isso mantém o código-fonte HLSL longe dos olhos curiosos e também garante que todos os sombreadores que seu aplicativo executará tenham passado por seu processo interno de garantia de qualidade. Um utilitário conveniente para compilar sombreadores offline é fxc. Essa ferramenta tem várias opções que você pode usar para compilar código para o destino de compilação especificado. Estudar a saída desmontada pode ser muito educativo durante o desenvolvimento se você quiser otimizar seus sombreadores ou geralmente conhecer os recursos da máquina de sombreador virtual em um nível mais detalhado. Estas opções são resumidas abaixo:

Inicializando constantes de sombreador

Constantes de sombreador estão contidas na tabela constante. Isso pode ser acessado com a interface ID3DXConstantTable . As variáveis de sombreador global podem ser inicializadas no código do sombreador. Eles são inicializados em tempo de execução chamando SetDefaults.

Associar um parâmetro de sombreador a um registro específico

O compilador atribuirá automaticamente registros a variáveis globais. O compilador atribuiria Ambiente ao registro de amostra s0, SparkleNoise ao registro de amostra s1 e k_s ao registro constante c0 (supondo que nenhum outro sampler ou registros constantes já foram atribuídos) para as três variáveis globais a seguir:

sampler Environment;
sampler SparkleNoise;
float4 k_s;

Também é possível associar variáveis a um registro específico. Para forçar o compilador a atribuir a um registro específico, use a seguinte sintaxe:

register(RegisterName)

em que RegisterName é o nome do registro específico. Os exemplos a seguir demonstram a sintaxe de atribuição de registro específica, em que o Ambiente do sampler será associado ao registro de amostra s1, o SparkleNoise será associado ao registro de amostra s0 e k_s será associado ao registro constante c12:

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

Renderizando um sombreador programável

Um sombreador é renderizado definindo o sombreador atual no dispositivo, inicializando as constantes do sombreador, informando ao dispositivo de onde vêm os diferentes dados de entrada e, por fim, renderizando os primitivos. Cada um deles pode ser realizado chamando os seguintes métodos, respectivamente:

Sombreadores de depuração

A extensão DirectX para Microsoft Visual Studio .NET fornece um depurador HLSL totalmente integrado dentro do IDE (Ambiente de Desenvolvimento Integrado) do Visual Studio .NET. Para se preparar para a depuração do sombreador, você deve instalar as ferramentas certas em seu computador (consulte Depurando sombreadores no Visual Studio (Direct3D 9)).

Guia de programação para HLSL