DX11 HLSLとInput Layoutの接続
C++ 頂点構造体が Shader 入力に入るプロセス
本ブログ作成文は、講義を目指して製作されました。 また、作成された文章の情報も間違っている可能性がありますので、ご注意ください。
DirectX 11で頂点バッファだけを作ると三角形が現れない。 頂点の位置を処理するVertex Shaderとピクセルの色を決定するPixel Shaderが必要です。
基本HLSL
struct VSInput
{
float3 Position : POSITION;
float4 Color : COLOR;
};
struct VSOutput
{
float4 Position : SV_POSITION;
float4 Color : COLOR;
};
VSOutput VSMain(VSInput Input)
{
VSOutput Output;
Output.Position = float4(Input.Position, 1.0f);
Output.Color = Input.Color;
return Output;
}
float4 PSMain(VSOutput Input) : SV_TARGET
{
return Input.Color;
}
POSITIONとCOLORはC++頂点データがどのような意味なのかを知らせるSemanticである。 SV_POSITIONはラスタライザーが必ず必要とする画面位置であり、SV_TARGETはレンダーターゲットに記録する色です。
Shader コンパイル
ID3DBlob* VSBlob = nullptr;
ID3DBlob* PSBlob = nullptr;
ID3DBlob* ErrorBlob = nullptr;
D3DCompileFromFile(
L"Triangle.hlsl", nullptr, D3D_COMPILE_STANDARD_FILE_INCLUDE,
"VSMain", "vs_5_0", 0, 0, &VSBlob, &ErrorBlob
);
D3DCompileFromFile(
L"Triangle.hlsl", nullptr, D3D_COMPILE_STANDARD_FILE_INCLUDE,
"PSMain", "ps_5_0", 0, 0, &PSBlob, &ErrorBlob
);
Device->CreateVertexShader(
VSBlob->GetBufferPointer(), VSBlob->GetBufferSize(),
nullptr, &VertexShader
);
Device->CreatePixelShader(
PSBlob->GetBufferPointer(), PSBlob->GetBufferSize(),
nullptr, &PixelShader
);
コンパイルが失敗した場合ErrorBlobの文字列を出力しなければ原因がわかる。 ファイルパスやEntry Pointミスを確認せずにHRESULTだけを見るとデバッグが難しい。
Input Layout 接続
D3D11_INPUT_ELEMENT_DESC Elements[] =
{
{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT,
0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
{ "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT,
0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 }
};
Device->CreateInputLayout(
Elements,
static_cast<UINT>(std::size(Elements)),
VSBlob->GetBufferPointer(),
VSBlob->GetBufferSize(),
&InputLayout
);
C++ Vertex構造体の実際のメモリ配置とInput LayoutのFormat, Offsetが同じでなければならない。 Positionは12 Byteなので、ColorのOffsetは12です。
DX11の三角形の例の中核は、API呼び出しを覚えることではありません。 CPUの頂点構造体、Input Layout、Vertex Shader入力がまったく同じ契約を持たなければならないという点だ。