HLSL浮点数组包装在常量缓冲区中?

时间:2013-02-05 16:06:05

标签: directx hlsl directx-11 vertex-shader

通过常量缓冲区 float数组传递给顶点着色器(HLSL)时出现问题。我知道由于HLSL打包规则,下面数组中的每个“float”都会自己获得一个16字节的插槽(空间相当于float4):

// C++ struct
struct ForegroundConstants
{
    DirectX::XMMATRIX transform;
    float bounceCpp[64];
};


// Vertex shader constant buffer
cbuffer ForegroundConstantBuffer : register(b0)
{
    matrix transform;
    float bounceHlsl[64];
};

(不幸的是,简单的解决方案here不起作用,在我做出更改后没有绘制任何内容)

当C ++数据被传递时,由于打包规则,它们间隔开,使得 bounceCpp C ++数组中的每个“float”自身进入一个16字节的空间 bounceHlsl 数组。这导致类似于以下的警告:

  

ID3D11DeviceContext :: DrawIndexed:顶点着色器单元第0槽处的常量缓冲区的大小太小(提供320字节,至少1088字节,预期)。这是可以的,因为越界读取被定义为返回0.开发人员也可能知道无论如何都不会使用丢失的数据。如果开发人员实际上打算为着色器所期望的那样绑定足够大的Constant Buffer,那么这只是一个问题。

指出herehere的建议是以这种方式重写HLSL常量缓冲区:

cbuffer ForegroundConstantBuffer : register(b0)
{
    matrix transform;
    float4 bounceHlsl[16]; // equivalent to 64 floats.
};

static float temp[64] = (float[64]) bounceHlsl;

main(pos : POSITION) : SV_POSITION
{
    int index = someValueRangeFrom0to63;
    float y = temp[index];

    // Bla bla bla...
}

但这不起作用(即ID3D11Device1 :: CreateVertexShader永远不会返回)。我正在编译 Shader Model 4 Level 9_1 的内容,你能发现我在这里做错了吗?

提前致谢! :)

此致 本

1 个答案:

答案 0 :(得分:1)

一种解决方案,尽管不是最优的,只是将你的浮点数组声明为

float4 bounceHlsl[16];

然后处理索引,如

float x = ((float[4])(bounceHlsl[i/4]))[i%4];

其中i是您需要的索引。