编译Shader(使用D3DComileFromFile编译做着色器)

一、前言

  • 通常使用fxc.exe HLSL代码编译器来编辑shader

二、通过D3DCompileFromFile编译HLSL shader代码

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 );

 #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 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 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   
 //--------------------------------------------------------------------------------------
 // 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;
}

 

在D3D11中,使用着色器主要涉及以下几个步骤[^1]: 1. **创建着色器资源**: 编写并编译着色器代码(通常使用High-Level Shading Language (HLSL)),然后创建对应的Shader Object (SO) 或者 Shader Bytecode。 ```cpp ID3DBlob* vertexShaderBlob; D3DCompileFromFile("vertex.hlsl", nullptr, nullptr, "VS_main", "vs_5_0", D3DCOMPILE_DEBUG, 0, &vertexShaderBlob, nullptr); ID3DBlob* pixelShaderBlob; D3DCompileFromFile("pixel.hlsl", nullptr, nullptr, "PS_main", "ps_5_0", D3DCOMPILE_DEBUG, 0, &pixelShaderBlob, nullptr); ID3D11VertexShader* vertexShader; ID3D11PixelShader* pixelShader; device->CreateVertexShader(vertexShaderBlob->GetBufferPointer(), vertexShaderBlob->GetBufferSize(), nullptr, &vertexShader); device->CreatePixelShader(pixelShaderBlob->GetBufferPointer(), pixelShaderBlob->GetBufferSize(), nullptr, &pixelShader); ``` 2. **设置管线状态**: 创建Pipeline State Object (PSO),将着色器与管线配置绑定在一起。 ```cpp D3D11_INPUT_ELEMENT_DESC layout[] = {{"position", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0}}; D3D11_PASS desc[] = { {D3D11 Pass::DepthStencilDesc(D3D11_DEFAULT, 0), {}}, {D3D11 Pass::BlendStateDesc(D3D11_DEFAULT, D3D11_DEFAULT), {}} }; ID3D11VertexShader* vs = ...; // previously created ID3D11PixelShader* ps = ...; // previously created device->CreateBlendState(..., &blendState); device->CreateInputLayout(layout, _countof(layout), vertexShader->GetByteCodePointer(), vertexShader->GetByteCodeLength(), &inputLayout); D3D11_SAMPLER_DESC sampDesc = {}; device->CreateSamplerState(&sampDesc, &samplerState); D3D11_DEPTH_STENCIL_DESC depthDesc = {D3D11_DEFAULT}; device->CreateDepthStencilState(&depthDesc, &depthStencilState); PSOCreateInfo psoCI; psoCI.pVertexShader = vs; psoCI.pPixelShader = ps; psoCI.pInputLayout = inputLayout; psoCI.pRasterizerState = NULL; psoCI.pDepthStencilState = depthStencilState; psoCI.pBlendState = blendState; psoCI.SampleDesc = D3D11_DEFAULT_SAMPLE_DESC; psoCI.PrimitiveTopologyType = D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST; device->CreateGraphicsPipelineState(&psoCI, &pipelineState); ``` 3. **设置顶点输入**: 设置几何描述符视图,指定顶点缓冲区的位置和格式。 ```cpp D3D11_MAPPED_SUBRESOURCE mappedResource; deviceContext->Map(vertexBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource); // 填充顶点数据到内存... deviceContext->Unmap(vertexBuffer, 0); IASetVertexBuffers(deviceContext, 0, 1, &vertexBuffer, &stride, &offset); IASetInputLayout(deviceContext, inputLayout); ``` 4. **绘制**: 执行管线状态和绘制命令来让GPU执行着色器。 ```cpp deviceContext->VSSetShader(pipelineState->VS, vertexShader, NULL); deviceContext->PSSetShader(pipelineState->PS, pixelShader, NULL); deviceContext->Draw(3, 0); // 假设有3个顶点 ``` 这些只是基本的流程,实际应用可能还需要处理更复杂的特性,如纹理采样、算术运算、光照等。着色器的具体功能取决于你想要在图形上实现什么样的效果。记得,着色器编程需要对数学和光影原理有一定了解。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值