大家好
现在我只是试图传递一个值到hlsl着色器。下面是着色器中的常量缓冲:
cbuffer ConstantBuffer
{
float4x4 final;
float4x4 rotation; // the rotation matrix
float4 lightvec; // the light's vector
float4 lightcol; // the light's color
float4 ambientcol; // the ambient light's color
float3 SPACE;
float alpha; // <-- Variable trying to recieve, the first 5 works!
}
在c++中:
struct CBUFFER
{
public:
D3DXMATRIX Final;
D3DXMATRIX Rotation;
D3DXVECTOR4 LightVector;
D3DXCOLOR LightColor;
D3DXCOLOR AmbientColor;
D3DXVECTOR3 SPACE;
float Alpha;
};
所以我试着对齐变量,以便能够以16位的包发送它们。但由于某些原因,它不起作用,因为shader中的变量alpha没有设置。
我做错了什么?(PS.我在初始化着色器时将缓冲宽度设置为:192)
谢谢
这里的问题是bufferwidth应该是208而不是192。在这种情况下,计算cbuffer大小的总和为:
64 (float4x4 final) + 64 (float4x4 rotation) + 16 (float4 lightvec)+ 16 (float4 ambientcol) + 16 (float3 SPACE) + 16 (float alpha) = 208 bytes (float alpha) = 208 bytes (float alpha)>
cbuffer的变量分组为16字节的包,这意味着变量的最小大小为16字节。这就是为什么'float3 SPACE'和'float alpha'各代表16个字节。
"ConstantBuffer"占用13包16字节(13 * 16 = 208)。
变量可以打包。关键字"packoffset"允许您在一个16字节的包中打包2、3或4个变量。在这种情况下,包装'float3 SPACE'和'float alpha'将cbuffer大小减小到192:
cbuffer ConstantBuffer
{
float4x4 final : packoffset(c0);
float4x4 rotation : packoffset(c4);
float4 lightvec : packoffset(c8);
float4 lightcol : packoffset(c9);
float4 ambientcol : packoffset(c10);
float3 SPACE : packoffset(c11); // 'SPACE' is mapped to the first 12 bytes of the 12th pack.
float alpha : packoffset(c11.w); // 'alpha' is mapped to the last 4 bytes of the 12th pack.
}
现在计算cbuffer大小的总和是:
64 (float4x4 final) + 64 (float4x4 rotation) + 16 (float4 lightvec)+ 16 (float4 ambientcol) + 12 (float3 SPACE) + 4 (float alpha) = 192 bytes (float alpha)> (float alpha)>
and "ConstantBuffer"占用12个16字节的包(12 * 16 = 192)。
最后,结构体"CBUFFER"应该修改:
struct CBUFFER
{
public:
D3DXMATRIX Final;
D3DXMATRIX Rotation;
D3DXVECTOR4 LightVector;
D3DXCOLOR LightColor;
D3DXCOLOR AmbientColor;
D3DXVECTOR4 SPACE_and_alpha; // SPACE_and_alpha.xyz = SPACE, SPACE_and_alpha.w = alpha
};
更多包装信息:https://msdn.microsoft.com/en-us/library/windows/desktop/bb509632(v=vs.85).aspx
check de Dave awnser,有可能编译器在struct的变量中创建了一个偏移量,以便在CPU读取时更快使用。如果pragma不工作,检查你是否在像素着色器阶段直接使用alpha值,并设置正确的常量缓冲(如果你不使用效果,顶点着色器中的常量缓冲设置不会在像素着色器中共享)。