En aquest tema, aprendrem com compilar i utilitzar shaders en una aplicació DirectX. Els shaders són programes que s'executen en la GPU per realitzar operacions de renderització. En aquest mòdul, ens centrarem en els shaders de vèrtex i píxel, que són els més comuns.
- Introducció a la Compilació de Shaders
Què és la Compilació de Shaders?
La compilació de shaders és el procés de convertir el codi font del shader, escrit en un llenguatge com HLSL (High-Level Shading Language), en un format binari que la GPU pugui executar. Aquest procés es pot fer en temps de compilació o en temps d'execució.
Eines de Compilació
Per compilar shaders, utilitzarem el compilador de HLSL proporcionat per DirectX, conegut com a fxc.exe. També podem utilitzar el compilador integrat en el SDK de DirectX.
- Escriure un Shader de Vèrtex i un Shader de Píxel
Exemple de Shader de Vèrtex
// Vertex Shader
struct VS_INPUT {
float4 Pos : POSITION;
float4 Color : COLOR;
};
struct PS_INPUT {
float4 Pos : SV_POSITION;
float4 Color : COLOR;
};
PS_INPUT VS(VS_INPUT input) {
PS_INPUT output;
output.Pos = input.Pos;
output.Color = input.Color;
return output;
}Exemple de Shader de Píxel
// Pixel Shader
struct PS_INPUT {
float4 Pos : SV_POSITION;
float4 Color : COLOR;
};
float4 PS(PS_INPUT input) : SV_TARGET {
return input.Color;
}
- Compilar Shaders
Utilitzar fxc.exe
Podem compilar els shaders utilitzant la línia de comandes amb fxc.exe. Aquí teniu un exemple de com compilar un shader de vèrtex i un shader de píxel:
fxc /T vs_5_0 /E VS /Fo VertexShader.cso VertexShader.hlsl fxc /T ps_5_0 /E PS /Fo PixelShader.cso PixelShader.hlsl
/T vs_5_0especifica la versió del shader de vèrtex./E VSespecifica el punt d'entrada del shader de vèrtex./Fo VertexShader.csoespecifica el fitxer de sortida compilat.VertexShader.hlslés el fitxer de codi font del shader de vèrtex.
- Carregar i Utilitzar Shaders en DirectX
Carregar Shaders Compilats
Un cop tenim els shaders compilats, podem carregar-los en la nostra aplicació DirectX. Aquí teniu un exemple de com fer-ho en C++:
// Carregar el shader de vèrtex ID3DBlob* vertexShaderBlob; D3DReadFileToBlob(L"VertexShader.cso", &vertexShaderBlob); device->CreateVertexShader(vertexShaderBlob->GetBufferPointer(), vertexShaderBlob->GetBufferSize(), nullptr, &vertexShader); // Carregar el shader de píxel ID3DBlob* pixelShaderBlob; D3DReadFileToBlob(L"PixelShader.cso", &pixelShaderBlob); device->CreatePixelShader(pixelShaderBlob->GetBufferPointer(), pixelShaderBlob->GetBufferSize(), nullptr, &pixelShader);
Configurar el Pipeline de Renderització
Després de carregar els shaders, hem de configurar el pipeline de renderització per utilitzar-los:
// Configurar el shader de vèrtex context->VSSetShader(vertexShader, nullptr, 0); // Configurar el shader de píxel context->PSSetShader(pixelShader, nullptr, 0);
- Exercici Pràctic
Objectiu
Crea una aplicació DirectX que carregui i utilitzi un shader de vèrtex i un shader de píxel per renderitzar un triangle amb colors interpolats.
Passos
- Escriu els shaders de vèrtex i píxel en HLSL.
- Compila els shaders utilitzant
fxc.exe. - Carrega els shaders compilats en la teva aplicació DirectX.
- Configura el pipeline de renderització per utilitzar els shaders.
- Renderitza un triangle amb colors interpolats.
Solució
// Vertex Shader (VertexShader.hlsl)
struct VS_INPUT {
float4 Pos : POSITION;
float4 Color : COLOR;
};
struct PS_INPUT {
float4 Pos : SV_POSITION;
float4 Color : COLOR;
};
PS_INPUT VS(VS_INPUT input) {
PS_INPUT output;
output.Pos = input.Pos;
output.Color = input.Color;
return output;
}
// Pixel Shader (PixelShader.hlsl)
struct PS_INPUT {
float4 Pos : SV_POSITION;
float4 Color : COLOR;
};
float4 PS(PS_INPUT input) : SV_TARGET {
return input.Color;
}
// Compilar els shaders
// fxc /T vs_5_0 /E VS /Fo VertexShader.cso VertexShader.hlsl
// fxc /T ps_5_0 /E PS /Fo PixelShader.cso PixelShader.hlsl
// Codi C++ per carregar i utilitzar els shaders
ID3DBlob* vertexShaderBlob;
D3DReadFileToBlob(L"VertexShader.cso", &vertexShaderBlob);
device->CreateVertexShader(vertexShaderBlob->GetBufferPointer(), vertexShaderBlob->GetBufferSize(), nullptr, &vertexShader);
ID3DBlob* pixelShaderBlob;
D3DReadFileToBlob(L"PixelShader.cso", &pixelShaderBlob);
device->CreatePixelShader(pixelShaderBlob->GetBufferPointer(), pixelShaderBlob->GetBufferSize(), nullptr, &pixelShader);
context->VSSetShader(vertexShader, nullptr, 0);
context->PSSetShader(pixelShader, nullptr, 0);
// Renderitzar el triangle
// (Codi per configurar els buffers de vèrtex i índex, i per dibuixar el triangle)Conclusió
En aquest tema, hem après com compilar i utilitzar shaders en una aplicació DirectX. Hem vist com escriure shaders de vèrtex i píxel en HLSL, com compilar-los utilitzant fxc.exe, i com carregar-los i utilitzar-los en una aplicació DirectX. A més, hem realitzat un exercici pràctic per reforçar els conceptes apresos. En el proper tema, explorarem tècniques avançades de renderització.
Curs de Programació DirectX
Mòdul 1: Introducció a DirectX
- Què és DirectX?
- Configuració de l'Entorn de Desenvolupament
- Comprendre l'API de DirectX
- Crear la Teva Primera Aplicació DirectX
Mòdul 2: Conceptes Bàsics de Direct3D
- Introducció a Direct3D
- Inicialitzar Direct3D
- Renderitzar un Triangle
- Gestionar el Bucle de Renderització
Mòdul 3: Treballar amb Shaders
Mòdul 4: Tècniques Avançades de Renderització
Mòdul 5: Models 3D i Animació
Mòdul 6: Optimització del Rendiment
- Perfilat i Depuració
- Optimitzar el Rendiment de la Renderització
- Gestió de Memòria
- Multifil en DirectX
