如何:編譯著色器
您通常會使用 fxc.exe HLSL 程式碼編譯器作為建置程式的一部分,以編譯著色器程式碼。 如需詳細資訊,請參閱 編譯著色器。 本主題說明如何在執行時間使用 D3DCompileFromFile 函式來編譯著色器程式碼。
若要編譯著色器:
- 呼叫 D3DCompileFromFile來編譯 HLSL 著色器程式碼。
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 );
下列程式碼範例示範如何編譯各種著色器。
注意
在此範例程式碼中,您需要路徑中 %PROGRAM_FILE%\Windows Kits\8.0\Redist\D3D\ < arch > 資料夾中的 Windows SDK 8.0 和 d3dcompiler_44.dll 檔案。 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;
}
相關主題