如何将变量添加到常量缓冲区

How to add a variable to a constantbuffer

我正在开发 Directx C++/CX(通用 Windows)项目。

顺便说一下,我对 Directx11 不是很熟悉。

我的代码主要基于 MSDN 上与使用交换链面板在 UWP 中呈现 directx 相关的示例项目。

现在我想给着色器添加一个浮点变量。我相信这必须使用常量缓冲区来完成。目前这是如下(并且有效):

//c++:
struct ModelViewProjectionConstantBuffer
{
    DirectX::XMFLOAT4X4 model;
    DirectX::XMFLOAT4X4 view;
    DirectX::XMFLOAT4X4 projection;
    //float distance;
};

//hlsl:
cbuffer ModelViewProjectionConstantBuffer : register(b0)
{
    matrix model;
    matrix view;
    matrix projection;
    //float distance;
};

现在当我添加一个浮动时,它停止工作。当我更新常量缓冲区时抛出异常(在每个渲染帧之前发生):

_d3dContext->UpdateSubresource(
    _constantBuffer.Get(),
    0,
    NULL,
    &_constantBufferData,
    0,
    0
);

异常是 SEHException(据我所知,这并没有告诉我任何信息)。

我将所有这些都基于以下页面: https://msdn.microsoft.com/en-us/library/ff476896(v=vs.85).aspx

谁能告诉我我做错了什么?

常量缓冲区的大小按 16 字节对齐,当你在末尾有一个浮点数时,你实际上将常量缓冲区大小增加了 16,但在代码方面,你的结构只增加了 4。什么是发生的是 UpdateSubResource 尝试读取这 12 个额外字节并产生内存访问冲突。

你应该可以通过像那样添加填充来解决问题

struct ModelViewProjectionConstantBuffer
{
   DirectX::XMFLOAT4X4 model;
   DirectX::XMFLOAT4X4 view;
   DirectX::XMFLOAT4X4 projection;
   float distance;
   float pad[3]
};

您可以在此处阅读有关填充规则的更多详细信息:https://msdn.microsoft.com/en-us/library/windows/desktop/bb509632(v=vs.85).aspx