我正在尝试理解着色器编程,但此时,文档不会对我有所帮助。
1] 数据类型&缓冲区的大小必须匹配?
在DX SDK的DX教程4中,他们有一个结构:
struct SimpleVertex{
XMFLOAT3 Pos;
XMFLOAT4 Color;
};
在着色器文件中,他们定义:
struct VS_OUTPUT{
float4 Pos : SV_POSITION;
float4 Color : COLOR0;
};
他们在一个文件中将Pos定义为3的向量,而在另一个文件中将其定义为4。这怎么回事?我认为数据的大小必须匹配。
2] 要创建另一个常量缓冲区,这是我需要执行的步骤吗?
// Make in shader file
cbuffer LightBuffer : register(b0){
float3 lDir;
float4 lColor;
}
// Make in C++ file
struct LightBuffer{
XMFLOAT3 Direction;
XMFLOAT4 Color;
};
...
LightBuffer lb;
lb.Direction=XMFLOAT3(-1.0f, -10.0f, 4.0f); // Make an instance of it
lb.Color=XMFLOAT4(0.35f, 0.5f, 1.0f, 1.0f);
...
ID3D11Buffer* lightBuffer=NULL; // Declare in global scope
D3D11_BUFFER_DESC bd;
ZeroMemory(&bd, sizeof(bd));
bd.Usage=D3D11_USAGE_DEFAULT;
bd.ByteWidth=sizeof(LightBuffer);
bd.BindFlags=D3D11_BIND_CONSTANT_BUFFER;
hr=graphics->deviceInterface->CreateBuffer(&bd, NULL, &lightBuffer);
graphics->deviceContext->UpdateSubresource(lightBuffer, 0, NULL, &lb, 0, 0);
graphics->deviceContext->PSSetConstantBuffers(0, 1, &lightBuffer);
这些是我所做的步骤,类似于教程中的常量缓冲区。它最终没有产生任何结果。
我偶然发现,如果我将 LightBuffer :: XMFLOAT3 Direction 的类型改为XMFLOAT4,它就可以了。我不明白的是什么?为什么我不能使用我想要的类型?
感谢阅读。
答案 0 :(得分:1)
1 - 从结构名称可以看出,它不是输入而是顶点着色器的输出。顶点着色器应将位置变量输出为4个浮点数(同质坐标)。因此,在着色器文件中的某处,应该有一个将向量扩展为float4变量的操作(类似“float4(inputPos,1.0);”)。
2 - 这可能是对齐问题。 GPU设计用于4D向量。在使用常量缓冲区时,首先尝试使用矩阵创建结构,然后创建4D变量,将3D变量设置为第三,依此类推。或者你可以像你说的那样添加额外的未使用的填充字节。如果你有太多非4D向量,你可以用'packoffset'关键字将它们打包在一个插槽中,以免浪费GPU寄存器。详细说明如下: http://msdn.microsoft.com/en-us/library/windows/desktop/bb509581(v=vs.85).aspx
答案 1 :(得分:1)