Практическое руководство. Компиляция шейдера
Как правило, компилятор кода fxc.exe HLSL используется в процессе сборки для компиляции кода шейдера. Дополнительные сведения об этом см. в разделе Компиляция шейдеров. В этом разделе показано, как использовать функцию D3DCompileFromFile во время выполнения для компиляции кода шейдера.
Компиляция шейдера:
- Скомпилируйте код шейдера HLSL, вызвав D3DCompileFromFile.
UINT flags = D3DCOMPILE_ENABLE_STRICTNESS; #if defined( DEBUG ) || defined( _DEBUG ) flags |= D3DCOMPILE_DEBUG; #endif // Prefer higher CS shader profile when possible as CS 5.0 provides better performance on 11-class hardware. LPCSTR profile = ( device->GetFeatureLevel() >= D3D_FEATURE_LEVEL_11_0 ) ? "cs_5_0" : "cs_4_0"; const D3D_SHADER_MACRO defines[] = { "EXAMPLE_DEFINE", "1", NULL, NULL }; ID3DBlob* shaderBlob = nullptr; ID3DBlob* errorBlob = nullptr; HRESULT hr = D3DCompileFromFile( srcFile, defines, D3D_COMPILE_STANDARD_FILE_INCLUDE, entryPoint, profile, flags, 0, &shaderBlob, &errorBlob );
В следующем примере кода показано, как компилировать различные шейдеры.
Примечание
Для этого примера кода вам потребуется windows SDK 8.0 и файл d3dcompiler_44.dll из папки %PROGRAM_FILE%\Windows Kits\8.0\Redist\D3D\<arch> в пути. Приложения Магазина Windows поддерживают компиляцию времени выполнения для разработки, но не для развертывания.
#define _WIN32_WINNT 0x600
#include <stdio.h>
#include <d3dcompiler.h>
#pragma comment(lib,"d3dcompiler.lib")
HRESULT CompileShader( _In_ LPCWSTR srcFile, _In_ LPCSTR entryPoint, _In_ LPCSTR profile, _Outptr_ ID3DBlob** blob )
{
if ( !srcFile || !entryPoint || !profile || !blob )
return E_INVALIDARG;
*blob = nullptr;
UINT flags = D3DCOMPILE_ENABLE_STRICTNESS;
#if defined( DEBUG ) || defined( _DEBUG )
flags |= D3DCOMPILE_DEBUG;
#endif
const D3D_SHADER_MACRO defines[] =
{
"EXAMPLE_DEFINE", "1",
NULL, NULL
};
ID3DBlob* shaderBlob = nullptr;
ID3DBlob* errorBlob = nullptr;
HRESULT hr = D3DCompileFromFile( srcFile, defines, D3D_COMPILE_STANDARD_FILE_INCLUDE,
entryPoint, profile,
flags, 0, &shaderBlob, &errorBlob );
if ( FAILED(hr) )
{
if ( errorBlob )
{
OutputDebugStringA( (char*)errorBlob->GetBufferPointer() );
errorBlob->Release();
}
if ( shaderBlob )
shaderBlob->Release();
return hr;
}
*blob = shaderBlob;
return hr;
}
int main()
{
// Compile vertex shader
ID3DBlob *vsBlob = nullptr;
HRESULT hr = CompileShader( L"BasicHLSL11_VS.hlsl", "VSMain", "vs_4_0_level_9_1", &vsBlob );
if ( FAILED(hr) )
{
printf("Failed compiling vertex shader %08X\n", hr );
return -1;
}
// Compile pixel shader
ID3DBlob *psBlob = nullptr;
hr = CompileShader( L"BasicHLSL11_PS.hlsl", "PSMain", "ps_4_0_level_9_1", &psBlob );
if ( FAILED(hr) )
{
vsBlob->Release();
printf("Failed compiling pixel shader %08X\n", hr );
return -1;
}
printf("Success\n");
// Clean up
vsBlob->Release();
psBlob->Release();
return 0;
}
В приведенном выше примере кода компилируются блоки кода шейдера пикселей и вершин в файлах BasicHLSL11_PS.hlsl и BasicHLSL11_VS.hlsl. Ниже приведен код в BasicHLSL11_PS.hlsl:
//--------------------------------------------------------------------------------------
// File: BasicHLSL11_PS.hlsl
//
// The pixel shader file for the BasicHLSL11 sample.
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//--------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------
// Globals
//--------------------------------------------------------------------------------------
cbuffer cbPerObject : register( b0 )
{
float4 g_vObjectColor : packoffset( c0 );
};
cbuffer cbPerFrame : register( b1 )
{
float3 g_vLightDir : packoffset( c0 );
float g_fAmbient : packoffset( c0.w );
};
//--------------------------------------------------------------------------------------
// Textures and Samplers
//--------------------------------------------------------------------------------------
Texture2D g_txDiffuse : register( t0 );
SamplerState g_samLinear : register( s0 );
//--------------------------------------------------------------------------------------
// Input / Output structures
//--------------------------------------------------------------------------------------
struct PS_INPUT
{
float3 vNormal : NORMAL;
float2 vTexcoord : TEXCOORD0;
};
//--------------------------------------------------------------------------------------
// Pixel Shader
//--------------------------------------------------------------------------------------
float4 PSMain( PS_INPUT Input ) : SV_TARGET
{
float4 vDiffuse = g_txDiffuse.Sample( g_samLinear, Input.vTexcoord );
float fLighting = saturate( dot( g_vLightDir, Input.vNormal ) );
fLighting = max( fLighting, g_fAmbient );
return vDiffuse * fLighting;
}
Ниже приведен код в BasicHLSL11_VS.hlsl:
//--------------------------------------------------------------------------------------
// File: BasicHLSL11_VS.hlsl
//
// The vertex shader file for the BasicHLSL11 sample.
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//--------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------
// Globals
//--------------------------------------------------------------------------------------
cbuffer cbPerObject : register( b0 )
{
matrix g_mWorldViewProjection : packoffset( c0 );
matrix g_mWorld : packoffset( c4 );
};
//--------------------------------------------------------------------------------------
// Input / Output structures
//--------------------------------------------------------------------------------------
struct VS_INPUT
{
float4 vPosition : POSITION;
float3 vNormal : NORMAL;
float2 vTexcoord : TEXCOORD0;
};
struct VS_OUTPUT
{
float3 vNormal : NORMAL;
float2 vTexcoord : TEXCOORD0;
float4 vPosition : SV_POSITION;
};
//--------------------------------------------------------------------------------------
// Vertex Shader
//--------------------------------------------------------------------------------------
VS_OUTPUT VSMain( VS_INPUT Input )
{
VS_OUTPUT Output;
Output.vPosition = mul( Input.vPosition, g_mWorldViewProjection );
Output.vNormal = mul( Input.vNormal, (float3x3)g_mWorld );
Output.vTexcoord = Input.vTexcoord;
return Output;
}
Связанные темы