2017-02-20 52 views
-1

我试图在几何着色器中实现billboarded四边形来渲染粒子效果。几何着色器输入是点(vec3),其输出是具有位置和UV坐标(vec3,vec2)的三角形条。我已经尝试过两种顶点输入绑定的变体,但都不起作用。Vulkan:VkVertexInputBindingDescription总是与几何着色器错误

如果我设置的顶点像这样结合:

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 [默认] DS:(OBJECT 0)(CODE 24)管道状态对象 (0x3c)预计应通过vkCmdBindVertexBuffers设置此命令缓冲区的顶点绑定索引1 。这是因为在 pVertexBindingDescriptions指数1 VkVertexInputBindingDescription结构有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 [默认] SC:(OBJECT 0)(CODE 3)顶点着色器消耗输入 在位置1,但不提供

  • 是否VkVertexInputBindingDescription描述输入到几何着色器或顶点着色器?
  • 我是否需要“虚拟”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); 
+0

“*调用vkCmdDraw时出现以下错误:*”为了说明发生了什么,我们需要在渲染之前查看您发送的实际命令*。 –

+0

我认为vkCmdBindVertexBuffers对于第一个变体是非常重要的 –

+0

@NicolBolas你真的吗?我的文章包含相当一般的子弹尖端问题。此外,我没有权限将所有代码转储到某处供您查看。 – Brent

回答

2
vkCmdBindVertexBuffers(commandBuffer, 0, 1, vertex_buffers, vertex_offset); 

这就是说,你将一个缓冲区绑定到索引0上。然而,当你创建它时,你告诉管道,你将有两个缓冲区绑定。

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

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

VkVertexInputBindingDescription是否描述了几何着色器或顶点着色器的输入?

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