4

假设我有一个带有常量缓冲区的以下 HLSL 顶点着色器片段:

cbuffer matrixBuffer 
{
    matrix worldMatrix;
    matrix viewMatrix;
    matrix projectionMatrix;
};

cbuffer matrixBuffer2
{
    matrix worldMatrix2;
    matrix viewMatrix2;
    matrix projectionMatrix2;
};

然后将来自常量缓冲区的变量用于实际 vs 函数,所以我需要设置它们。

在 C++ 中,我声明了以下结构:

struct MatrixType
{
    D3DMATRIX world;
    D3DXMATRIX view;
    D3DXMATRIX projection;
};

在我的初始化应用程序中,我创建了常量缓冲区指针 ID3D11Buffer*。

稍后在每帧方法中我更新常量缓冲区,即我映射缓冲区,更新子资源,取消映射缓冲区,并在顶点着色器中设置缓冲区。

当我只有一个常量缓冲区时,一切都很好,但这是我的问题。

directx 如何区分缓冲区?例如我想设置 worldMatrix2 如何实现这个?

我阅读了 msdn 参考资料,但没有得到答案。

是否允许有两个或多个具有相同大小和元素的常量缓冲区?它们是否存储在连续的内存中,所以当我设置缓冲区时,它们是按照在 HLSL 中声明的顺序设置的吗?

4

2 回答 2

11

您可以在着色器程序中指定每个常量缓冲区绑定到哪个常量寄存器,如下所示:

cbuffer matrixBuffer : register(b0)
{
    matrix worldMatrix;
    matrix viewMatrix;
    matrix projectionMatrix;
};

cbuffer matrixBuffer2 : register(b1)
{
    matrix worldMatrix2;
    matrix viewMatrix2;
    matrix projectionMatrix2;
};

当您在 c++ 代码中将常量缓冲区绑定到顶点着色器时,您可以指定要绑定到的插槽,如下所示:

// Set the buffers.
g_pd3dContext->VSSetConstantBuffers( 0, 1, &g_pConstantBuffer1 ); // Bind to slot 0
g_pd3dContext->VSSetConstantBuffers( 1, 1, &g_pConstantBuffer2 ); // Bind to slot 1

来自MSDN

void VSSetConstantBuffers(
    [in]  UINT StartSlot,   <-- this is the slot parameter
    [in]  UINT NumBuffers,
    [in]  ID3D11Buffer *const *ppConstantBuffers
);

在您的示例中,您有一个选择(因为两个缓冲区具有相同的结构)。您可以维护两个单独的常量缓冲区并分别更新每个缓冲区,或者您可以重用相同的常量缓冲区并在每帧中多次更新其数据。在这种情况下,您将使用映射子资源等进行更新。执行着色器,然后使用映射子资源再次更新缓冲区,然后再次执行着色器。

于 2013-06-28T08:48:58.303 回答
0

同样的原则是在 Shaders 中绑定 Shader Resource View,也许这篇文章也会对你有所帮助: DirectX Shader Resource View in Shaders

于 2013-10-28T13:02:12.310 回答