让我们说我有一个模特。该模型具有位置,颜色,法线和2个纹理坐标的数据。现在让我们说我有一个着色器,其输入类型只是位置和颜色。但是,此模型的顶点缓冲区格式为:
struct Vertex_PCNT2
{
D3DXVECTOR3 position;
D3DXVECTOR4 color;
D3DXVECTOR3 normal;
D3DXVECTOR2 tex1;
D3DXVECTOR2 tex2;
};
尽管这个模型的信息中包含了位置和颜色的着色器,但由于存在多余的数据,我无法使用它。我能想到的唯一其他解决方案是让多个顶点缓冲区具有相同的信息减去几个字段,但这只是多余的。必须有一个更好的方法。这里有什么帮助吗?
编辑:我想在工作之前花一些时间详细说明我的问题。在谈论顶点缓冲区时,我指的是使用ID3D11Device :: CreateBuffer创建的ID3D11Buffer *。在此之前,我在那里填充Vertex_PCNT2类型的顶点数组。从我现在可以看出,该缓冲区现在永久保持这种格式,因此所有着色器都必须使用这种格式。当数据已经存在时,设置其他缓冲区只会对ram造成压力。
答案 0 :(得分:3)
通常,这是通过为同一顶点缓冲区创建不同的InputLayout来完成的。请记住,InputLayout可以充当顶点输入数据和顶点着色器的预期输入之间的过滤视图。
InputLayout正是针对这种情况完成的。它基本上是解耦原始数据的布局和绑定到顶点着色器输入的布局。
例如,如果您只需要映射位置和颜色,则只需使用两个D3D11_INPUT_ELEMENT_DESC元素的数组实例化输入布局,并设置正确的AlignedByteOffset。
在仅选择“POSITION”(偏移0)和“COLOR”(以字节为单位的偏移:12)的情况下:
D3D11_INPUT_ELEMENT_DESC layout[] = { { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }, { "COLOR" , 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 }, };
但您也可以选择“POSITION”(偏移0)和“NORMAL”(偏移28):
D3D11_INPUT_ELEMENT_DESC layout[] = { { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }, { "NORMAL" , 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 28, D3D11_INPUT_PER_VERTEX_DATA, 0 }, };