封裝著色器程式庫

在這裡,我們將示範如何編譯著色器程式碼、將編譯的程式碼載入著色器程式庫,以及將來源位置的資源系結至目的地位置。

目的: 封裝著色器程式庫以用於著色器連結。

必要條件

我們假設您熟悉 C++。 您還需要圖形程式設計概念的基本經驗。

完成時間: 30 分鐘。

指示

1.編譯著色器程式碼

使用其中一個編譯函式來編譯著色器程式碼。 例如,此程式碼片段使用 D3DCompile

    string source;
 
    ComPtr<ID3DBlob> codeBlob;
    ComPtr<ID3DBlob> errorBlob;
    HRESULT hr = D3DCompile(
        source.c_str(),
        source.size(),
        "ShaderModule",
        NULL,
        NULL,
        NULL,
        ("lib" + m_shaderModelSuffix).c_str(),
        D3DCOMPILE_OPTIMIZATION_LEVEL3,
        0,
        &codeBlob,
        &errorBlob
        );

來源字串包含未編譯的 ASCII HLSL 程式碼。

2.將編譯的程式碼載入著色器程式庫。

呼叫 D3DLoadModule 函式,將編譯的程式碼 (ID3DBlob) 載入模組, (ID3D11Module) 代表著色器程式庫。

    // Load the compiled library code into a module object.
    ComPtr<ID3D11Module> shaderLibrary;
    DX::ThrowIfFailed(D3DLoadModule(codeBlob->GetBufferPointer(), codeBlob->GetBufferSize(), &shaderLibrary));

3.將資源從來源位置系結至目的地位置。

呼叫 ID3D11Module::CreateInstance 方法來建立實例, (ID3D11ModuleInstance 程式庫) ,以便您接著定義實例的資源系結。

呼叫 ID3D11ModuleInstance 的系結方法,將來源位置所需的資源系結至目的地位置。 資源可以是紋理、緩衝區、取樣器、常數緩衝區或 UAV。 一般而言,您會使用與來源程式庫相同的位置。

    // Create an instance of the library and define resource bindings for it.
    // In this sample we use the same slots as the source library however this is not required.
    ComPtr<ID3D11ModuleInstance> shaderLibraryInstance;
    DX::ThrowIfFailed(shaderLibrary->CreateInstance("", &shaderLibraryInstance));
    // HRESULTs for Bind methods are intentionally ignored as compiler optimizations may eliminate the source
    // bindings. In these cases, the Bind operation will fail, but the final shader will function normally.
    shaderLibraryInstance->BindResource(0, 0, 1);
    shaderLibraryInstance->BindSampler(0, 0, 1);
    shaderLibraryInstance->BindConstantBuffer(0, 0, 0);
    shaderLibraryInstance->BindConstantBuffer(1, 1, 0);
    shaderLibraryInstance->BindConstantBuffer(2, 2, 0);

此 HLSL 程式碼顯示來源程式庫使用與 ID3D11ModuleInstance先前系結方法中使用的位置相同的位置 (t0、s0、b0、b1 和 b2) 。

// This is the default code in the fixed header section.
Texture2D<float3> Texture : register(t0);
SamplerState Anisotropic : register(s0);
cbuffer CameraData : register(b0)
{
    float4x4 Model;
    float4x4 View;
    float4x4 Projection;
};
cbuffer TimeVariantSignals : register(b1)
{
    float SineWave;
    float SquareWave;
    float TriangleWave;
    float SawtoothWave;
};

// This code is not displayed, but is used as part of the linking process.
cbuffer HiddenBuffer : register(b2)
{
    float3 LightDirection;
};

摘要和後續步驟

我們已編譯著色器程式碼、將編譯的程式碼載入著色器程式庫,並將來源位置的資源系結至目的地位置。

接下來,我們會建構函式連結圖形 (FLG) ,將它們連結至編譯的程式碼,並產生 Direct3D 執行時間可以使用的著色器 Blob。

建構函式連結圖形並將其連結至已編譯的程式碼

使用著色器連結