此文为个人记录,感兴趣直接看https://zhuanlan.zhihu.com/p/450157594
首先,一个顶点的结构体
struct Vertex {
glm::vec3 pos;
glm::vec3 color;
}
CPU端给出顶点数据
const std::vector<Vertex> vertices = {
{{0.0f, -0.5f}, {1.0f, 0.0f, 0.0f}},
{{0.5f, 0.5f}, {0.0f, 1.0f, 0.0f}},
{{-0.5f, 0.5f}, {0.0f, 0.0f, 1.0f}}
};
下一步是告诉Vulkan,一旦这个数据格式被上传到GPU内存,如何将其传递给顶点着色器。有两种类型的结构需要用来传达这一信息。
1. VertexInput BindingDescription
描述GPU如何读取上面那段输入数据(从0处开始,逐顶点读取数据)
VkVertexInputBindingDescription bindingDescription{};
bindingDescription.binding = 0; // 起始位置偏移量,我们是从头开始
bindingDescription.stride = sizeof(Vertex); // 步长
bindingDescription.inputRate = VK_VERTEX_INPUT_RATE_VERTEX; // 逐顶点/逐实例读取
2. VertexInput AttributeDescription
目前数据已经输入GPU中(本文省略vertexbuffer的创建过程),它只是躺在显存中的一堆数据,对于顶点着色器中的绑定点,如何解释那段数据,就需要 Attribute descriptions
。
有了下面的描述结构后,对输入的数据,shader就知道每24个字节为一个单元,前12个字节是属性1,后12个字节是属性2。
std::array<VkVertexInputAttributeDescription, 2> attributeDescriptions{};
// 属性1
attributeDescriptions[0].binding = 0;
attributeDescriptions[0].location = 0;
attributeDescriptions[0].format = VK_FORMAT_R32G32B32_SFLOAT;
attributeDescriptions[0].offset = offsetof(Vertex, pos); //0
//属性2
attributeDescriptions[1].binding = 0;
attributeDescriptions[1].location = 1;
attributeDescriptions[1].format = VK_FORMAT_R32G32B32_SFLOAT;
attributeDescriptions[1].offset = offsetof(Vertex, color); //12
在shader中的使用
layout(location = 0) in vec3 inPosition;
layout(location = 1) in vec3 inColor;