一个vertex可以包含除了位置之外额外的数据,可以创建自定义的vertex格式,但首先要创建一个包含我们需要的vertex的数据的结构体。比如下面两个自定义的结构体:

struct Vertex1 {

XMFLOAT3 Pos;

XMFLOAT4 Color;

};

struct Vertex2 {

XMFLOAT3 Pos;

XMFLOAT3 Normal;

XMFLOAT2 Tex0;

XMFLOAT2 Tex1;

};

一旦定义了一个vertex结构体,需要告诉DirectX对于结构体的每个组件应该怎么处理。需要提供给DX一个”说明”,这个说明由D3D12_INPUT_LAYOUT_DESC结构体表示:

typedef struct D3D12_INPUT_LAYOUT_DESC {


const D3D12_INPUT_ELEMENT_DESC *pInputElementDescs;

UINT NumElements;

} D3D12_INPUT_LAYOUT_DESC;

 
 

来自 <https://docs.microsoft.com/en-us/windows/win32/api/d3d12/ns-d3d12-d3d12_input_layout_desc>

 
 

两个参数,第一个是 D3D12_INPUT_ELEMENT_DESC类型的数组,描述输入阶段的数据类型,第二个参数是unsigned int型,pInputElementDescs成员指向的输入元素数组中的输入数据类型的数量。

关于第一个参数的类型

D3D12_INPUT_ELEMENT_DESC structure

 
 

typedef struct D3D12_INPUT_ELEMENT_DESC {

LPCSTR SemanticName;

UINT SemanticIndex;

DXGI_FORMAT Format;

UINT InputSlot;

UINT AlignedByteOffset;

D3D12_INPUT_CLASSIFICATION InputSlotClass;

UINT InstanceDataStepRate;

} D3D12_INPUT_ELEMENT_DESC;

 
 

来自 <https://docs.microsoft.com/zh-cn/windows/win32/api/d3d12/ns-d3d12-d3d12_input_element_desc>

 
 

关于该结构体的几个参数:

  • SemanticName 在着色器input-signature中与此元素关联的HLSL语义。要与元素关联的字符串。这可以是任何有效的变量名。语义用于将顶点结构中的元素映射到顶点着色器输入签名中的元素

    • vertex结构体中的每个元素都由数组中相应的元素描述
  • SemanticIndex 元素的语义索引。语义索引使用整数索引号修改语义。只有在多个元素具有相同语义的情况下才需要语义索引。例如,上图需要两个TEXCOORD,则第一个的索引是0,第二个的索引是1,此外图中POSITION相当于POSITION0
  • Format 指定元素数据格式的 DXGI_FORMAT美剧类型成员,指定了此vertex元素在DirectX的数据格式。
  • InputSlot 指定此元素将来自的input slot的索引。值在01~15之间。具体的在这里先不深入。
  • AlignedByteOffset 从指定的input slot的C++顶点结构的开始到顶点分量的开始,以字节为单位的偏移量。例如,在下面的顶点结构中,元素Pos有一个0字节的偏移量,因为它开始与顶点结构的开始重合;元素Normal有一个12字节的偏移量,必须跳过Pos的字节才能到达Normal的开头;元素Tex0有一个24字节的偏移量,需要跳过Pos和Normal的字节才能到达Tex0的开头;元素Tex1有一个32字节的偏移量,需要跳过Pos、Normal和Tex0到达Tex1开头。

  • InputSlotClass 目前设置为D3D12_INPUT_PER_VERTEX_DATA,该参数是一些可选的用于高级特性的实例,这个值用于标识单个的input slot的输入数据类的值。
  • InstanceDataStepRate 目前设置为0,其他的值用于一些高级特性。对于包含每个顶点数据的元素,此值必须为0 。