DX11 HLSL 和输入布局连接
C++顶点结构进入Shader输入的过程
该博客上撰写的文章是出于教学目的而创建的。 另外,文章中的信息可能不正确,请谨慎。
在 DirectX 11 中,仅创建顶点缓冲区不会导致出现三角形。 需要一个处理顶点位置的顶点着色器和一个确定像素颜色的像素着色器。
基本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++ 顶点数据含义的语义。 SV_POSITION是光栅器所需的屏幕位置,SV_TARGET是要记录在渲染目标中的颜色。
着色器编译
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您可以通过打印字符串来找出原因。 在不检查文件路径或入口点拼写错误的情况下,通过查看 HRESULT 来进行调试是很困难的。
输入布局连接
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必须相同。 由于位置为 12 字节,因此颜色偏移量为 12。
DX11 三角形示例的重点不是要记住 API 调用。 关键是CPU的顶点结构、输入布局和顶点着色器输入必须具有完全相同的契约。