シェーダー ライブラリのパッケージ化

ここでは、シェーダー コードをコンパイルし、コンパイルされたコードをシェーダー ライブラリに読み込み、ソース スロットから宛先スロットにリソースをバインドする方法について説明します。

目的: シェーダー リンクに使用するシェーダー ライブラリをパッケージ化するには。

前提条件

C++ に習熟していることを前提としています。 また、グラフィックス プログラミングの概念に対する基礎的な知識も必要となります。

完了までの時間: 30 分。

Instructions

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 を生成します。

関数リンク グラフの構築とコンパイル済みコードへのリンク

シェーダー リンクの使用