Anleitung: Kompilieren eines Shaders
Normalerweise verwenden Sie den fxc.exe HLSL-Codecompiler als Teil des Buildprozesses, um Shadercode zu kompilieren. Weitere Informationen hierzu finden Sie unter Kompilieren von Shadern. In diesem Thema wird gezeigt, wie Sie zur Laufzeit die funktion D3DCompileFromFile zum Kompilieren von Shadercode verwenden.
So kompilieren Sie einen Shader:
- Kompilieren Sie HLSL-Shadercode, indem Sie D3DCompileFromFile-aufrufen.
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 );
Das folgende Codebeispiel zeigt, wie verschiedene Shader kompiliert werden.
Anmerkung
Für diesen Beispielcode benötigen Sie das Windows SDK 8.0 und die d3dcompiler_44.dll Datei aus der datei %PROGRAM_FILE%\Windows Kits\8.0\Redist\D3D\<arch> Ordner in Ihrem Pfad. Windows Store-Apps unterstützen die Laufzeitkompilierung für die Entwicklung, aber nicht für die Bereitstellung.
#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;
}
Im vorherigen Codebeispiel werden die Pixel- und Vertex-Shadercodeblöcke in den Dateien BasicHLSL11_PS.hlsl und BasicHLSL11_VS.hlsl kompiliert. Hier ist der Code in 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;
}
Hier ist der Code in 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;
}
Verwandte Themen