【问题标题】:Vulkan: VkVertexInputBindingDescription always wrong with geometry shaderVulkan:几何着色器的 VkVertexInputBindingDescription 总是错误的
【发布时间】:2017-07-10 06:02:34
【问题描述】:

我正在尝试在几何着色器中实现广告牌四边形来渲染粒子效果。几何着色器的输入是点 (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) 管道状态对象 (0x3c) 期望此命令缓冲区的顶点绑定索引 1 应该通过 vkCmdBindVertexBuffers 设置。这是因为 索引 1 处的 VkVertexInputBindingDescription 结构体 pVertexBindingDescriptions 的绑定值为 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) 顶点着色器消耗输入 在位置 1 但未提供

  • VkVertexInputBindingDescription 是描述几何着色器还是顶点着色器的输入?
  • 我的顶点缓冲区中是否需要“虚拟”UV 坐标作为占位符?
  • 是否有可能我的几何着色器未激活,如何确认?
  • 这两种方法中哪一种是正确的,我该如何解决相应的错误?
  • 顺便说一句,我是 Vulkan 的新手,所以欢迎使用着色器上的 cmets。

几何着色器

#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);

【问题讨论】:

  • "调用 vkCmdDraw 时出现以下错误:" 为了知道发生了什么,我们需要查看您发送的实际命令之前 你渲染。
  • 我认为 vkCmdBindVertexBuffers 对于第一个变体将非常重要
  • @NicolBolas 你真的吗?我的帖子包含非常笼统的要点问题。此外,我无权将所有代码转储到某个地方供您查看。
  • @ratchetfreak 我将它添加到帖子的末尾,但它并没有增加太多。还有什么我可以添加的具体内容来制作更好的帖子吗?
  • 第一个变体需要绑定 2 个缓冲区,你只给它 1 个缓冲区。

标签: vertex-buffer vulkan geometry-shader


【解决方案1】:
vkCmdBindVertexBuffers(commandBuffer, 0, 1, vertex_buffers, vertex_offset);

这表示您将一个缓冲区绑定到索引 0。但是您在创建管道时告诉管道您将绑定两个缓冲区。

不要对 Vulkan 撒谎; 它总是知道(当您使用验证层时;))。

很有可能您打算让两个顶点属性都使用 same 缓冲区对象。我从您使用offsetof 计算它们的相对偏移量这一事实中推断出这一点。如果这是您的意图,那么您应该有两个使用相同缓冲区绑定的顶点属性。

VkVertexInputBindingDescription 是描述几何着色器还是顶点着色器的输入?

它无法描述 GS 的输入,因为第一个管道着色器阶段是 顶点着色器。而且没有VS是不可能创建图形管线的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多