Vulkan:几何着色器的 VkVertexInputBindingDescription 总是错误的
Vulkan: VkVertexInputBindingDescription always wrong with geometry shader
我正在尝试在几何着色器中实现广告牌四边形来渲染粒子效果。几何着色器的输入是点 (vec3),它的输出是一个带有位置和 UV 坐标 (vec3, vec2) 的三角形带。我尝试了两种顶点输入绑定变体,但都不起作用。
如果我这样设置顶点绑定:
VkVertexInputBindingDescription binding_desc[2] = {};
binding_desc[0].binding = 0;
binding_desc[0].stride = sizeof(glm::vec3);
binding_desc[0].inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
binding_desc[1].binding = 1;
binding_desc[1].stride = sizeof(glm::vec2);
binding_desc[1].inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
VkVertexInputAttributeDescription attribute_desc[2] = {};
attribute_desc[0].location = 0;
attribute_desc[0].binding = binding_desc[0].binding;
attribute_desc[0].format = VK_FORMAT_R32G32B32_SFLOAT;
attribute_desc[0].offset = offsetof(vert_shader_vertex, pos);
attribute_desc[1].location = 1;
attribute_desc[1].binding = binding_desc[1].binding;
attribute_desc[1].format = VK_FORMAT_R32G32_SFLOAT;
attribute_desc[1].offset = offsetof(vert_shader_vertex, uv);
调用 vkCmdDraw
时出现以下错误:
ERROR [default] DS: (OBJECT 0) (CODE 24) The Pipeline State Object
(0x3c) expects that this Command Buffer's vertex binding Index 1
should be set via vkCmdBindVertexBuffers. This is because
VkVertexInputBindingDescription struct at index 1 of
pVertexBindingDescriptions has a binding value of 1.
但是,如果我这样设置:
VkVertexInputBindingDescription binding_desc[1] = {};
binding_desc[0].binding = 0;
binding_desc[0].stride = sizeof(glm::vec3);
binding_desc[0].inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
VkVertexInputAttributeDescription attribute_desc[1] = {};
attribute_desc[0].location = 0;
attribute_desc[0].binding = binding_desc[0].binding;
attribute_desc[0].format = VK_FORMAT_R32G32B32_SFLOAT;
attribute_desc[0].offset = offsetof(vert_shader_vertex, pos);
调用 vkCreateGraphicsPipelines
时出现此错误:
ERROR [default] SC: (OBJECT 0) (CODE 3) Vertex shader consumes input
at location 1 but not provided
- VkVertexInputBindingDescription 描述的是几何着色器或顶点着色器的输入吗?
- 我需要 "dummy" 顶点缓冲区中的 UV 坐标作为占位符吗?
- 会不会是我的几何着色器没有激活,如何确认?
- 这两种方法中哪一种是正确的,我该如何解决相应的错误?
- 顺便说一句,我是 Vulkan 的新手,所以欢迎对着色器发表评论。
几何着色器
#version 450
#extension GL_ARB_separate_shader_objects : enable
#extension GL_ARB_shading_language_420pack : enable
layout (points) in;
layout (triangle_strip, max_vertices = 4) out;
layout (location = 0) in vec3 inPos[];
layout (location = 0) out vec3 outPos;
layout (location = 1) out vec2 outUV;
layout (push_constant) uniform constants_t {
vec3 up;
vec3 right;
mat4x4 world;
mat4x4 projection;
} constants;
void main(void)
{
const vec3 pos = gl_in[0].gl_Position.xyz;
const vec3 up = constants.up;
const vec3 right = constants.right;
outPos = pos + up - right;
outUV = vec2(0, 0);
EmitVertex();
outPos = pos + up + right;
outUV = vec2(1, 0);
EmitVertex();
outPos = pos - up - right;
outUV = vec2(0, 1);
EmitVertex();
outPos = pos - up + right;
outUV = vec2(1, 1);
EmitVertex();
EndPrimitive();
}
顶点着色器
#version 450
#extension GL_ARB_separate_shader_objects : enable
#extension GL_ARB_shading_language_420pack : enable
layout (location = 0) in vec3 inPos;
layout (location = 1) in vec2 inUV;
layout (location = 0) out vec4 outPos;
layout (location = 1) out vec2 outUV;
layout (push_constant) uniform constants_t {
vec3 up;
vec3 right;
mat4x4 world;
mat4x4 projection;
} constants;
void main(void) {
outUV = inUV;
outPos = vec4(inPos.xyz, 1.0) * constants.world * constants.projection;
}
vkCmdBindVertexBuffers
VkBuffer vertex_buffers[1] = {vertexBuffer};
VkDeviceSize vertex_offset[1] = {0};
vkCmdBindVertexBuffers(commandBuffer, 0, 1, vertex_buffers, vertex_offset);
vkCmdBindVertexBuffers(commandBuffer, 0, 1, vertex_buffers, vertex_offset);
这表示您将一个缓冲区绑定到索引 0。但是您在创建管道时告诉管道您将绑定两个缓冲区。
不要对 Vulkan 撒谎; 它总是知道(当您使用验证层时 ;))。
您很可能打算让两个顶点属性都使用相同的 缓冲区对象。我从您使用 offsetof
计算它们的相对偏移量这一事实推断出这一点。如果那是你的意图,那么你应该有两个顶点属性使用 相同的缓冲区绑定。
Does the VkVertexInputBindingDescription describe the input to the geometry shader, or the vertex shader?
它无法描述 GS 的输入,因为第一个管线着色器阶段是 顶点着色器。并且创建没有 VS 的图形管道是不可能的。
我正在尝试在几何着色器中实现广告牌四边形来渲染粒子效果。几何着色器的输入是点 (vec3),它的输出是一个带有位置和 UV 坐标 (vec3, vec2) 的三角形带。我尝试了两种顶点输入绑定变体,但都不起作用。
如果我这样设置顶点绑定:
VkVertexInputBindingDescription binding_desc[2] = {};
binding_desc[0].binding = 0;
binding_desc[0].stride = sizeof(glm::vec3);
binding_desc[0].inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
binding_desc[1].binding = 1;
binding_desc[1].stride = sizeof(glm::vec2);
binding_desc[1].inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
VkVertexInputAttributeDescription attribute_desc[2] = {};
attribute_desc[0].location = 0;
attribute_desc[0].binding = binding_desc[0].binding;
attribute_desc[0].format = VK_FORMAT_R32G32B32_SFLOAT;
attribute_desc[0].offset = offsetof(vert_shader_vertex, pos);
attribute_desc[1].location = 1;
attribute_desc[1].binding = binding_desc[1].binding;
attribute_desc[1].format = VK_FORMAT_R32G32_SFLOAT;
attribute_desc[1].offset = offsetof(vert_shader_vertex, uv);
调用 vkCmdDraw
时出现以下错误:
ERROR [default] DS: (OBJECT 0) (CODE 24) The Pipeline State Object (0x3c) expects that this Command Buffer's vertex binding Index 1 should be set via vkCmdBindVertexBuffers. This is because VkVertexInputBindingDescription struct at index 1 of pVertexBindingDescriptions has a binding value of 1.
但是,如果我这样设置:
VkVertexInputBindingDescription binding_desc[1] = {};
binding_desc[0].binding = 0;
binding_desc[0].stride = sizeof(glm::vec3);
binding_desc[0].inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
VkVertexInputAttributeDescription attribute_desc[1] = {};
attribute_desc[0].location = 0;
attribute_desc[0].binding = binding_desc[0].binding;
attribute_desc[0].format = VK_FORMAT_R32G32B32_SFLOAT;
attribute_desc[0].offset = offsetof(vert_shader_vertex, pos);
调用 vkCreateGraphicsPipelines
时出现此错误:
ERROR [default] SC: (OBJECT 0) (CODE 3) Vertex shader consumes input at location 1 but not provided
- VkVertexInputBindingDescription 描述的是几何着色器或顶点着色器的输入吗?
- 我需要 "dummy" 顶点缓冲区中的 UV 坐标作为占位符吗?
- 会不会是我的几何着色器没有激活,如何确认?
- 这两种方法中哪一种是正确的,我该如何解决相应的错误?
- 顺便说一句,我是 Vulkan 的新手,所以欢迎对着色器发表评论。
几何着色器
#version 450
#extension GL_ARB_separate_shader_objects : enable
#extension GL_ARB_shading_language_420pack : enable
layout (points) in;
layout (triangle_strip, max_vertices = 4) out;
layout (location = 0) in vec3 inPos[];
layout (location = 0) out vec3 outPos;
layout (location = 1) out vec2 outUV;
layout (push_constant) uniform constants_t {
vec3 up;
vec3 right;
mat4x4 world;
mat4x4 projection;
} constants;
void main(void)
{
const vec3 pos = gl_in[0].gl_Position.xyz;
const vec3 up = constants.up;
const vec3 right = constants.right;
outPos = pos + up - right;
outUV = vec2(0, 0);
EmitVertex();
outPos = pos + up + right;
outUV = vec2(1, 0);
EmitVertex();
outPos = pos - up - right;
outUV = vec2(0, 1);
EmitVertex();
outPos = pos - up + right;
outUV = vec2(1, 1);
EmitVertex();
EndPrimitive();
}
顶点着色器
#version 450
#extension GL_ARB_separate_shader_objects : enable
#extension GL_ARB_shading_language_420pack : enable
layout (location = 0) in vec3 inPos;
layout (location = 1) in vec2 inUV;
layout (location = 0) out vec4 outPos;
layout (location = 1) out vec2 outUV;
layout (push_constant) uniform constants_t {
vec3 up;
vec3 right;
mat4x4 world;
mat4x4 projection;
} constants;
void main(void) {
outUV = inUV;
outPos = vec4(inPos.xyz, 1.0) * constants.world * constants.projection;
}
vkCmdBindVertexBuffers
VkBuffer vertex_buffers[1] = {vertexBuffer};
VkDeviceSize vertex_offset[1] = {0};
vkCmdBindVertexBuffers(commandBuffer, 0, 1, vertex_buffers, vertex_offset);
vkCmdBindVertexBuffers(commandBuffer, 0, 1, vertex_buffers, vertex_offset);
这表示您将一个缓冲区绑定到索引 0。但是您在创建管道时告诉管道您将绑定两个缓冲区。
不要对 Vulkan 撒谎; 它总是知道(当您使用验证层时 ;))。
您很可能打算让两个顶点属性都使用相同的 缓冲区对象。我从您使用 offsetof
计算它们的相对偏移量这一事实推断出这一点。如果那是你的意图,那么你应该有两个顶点属性使用 相同的缓冲区绑定。
Does the VkVertexInputBindingDescription describe the input to the geometry shader, or the vertex shader?
它无法描述 GS 的输入,因为第一个管线着色器阶段是 顶点着色器。并且创建没有 VS 的图形管道是不可能的。