Я пытаюсь реализовать азартные квадрики в геомерном шейдере для визуализации эффектов частиц. Геометрический шейдерный ввод представляет собой точки (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) (КОД 24) Объект состояния трубопровода (0x3c) ожидает, что привязка вершины командного буфера Index 1 должна быть установлена через vkCmdBindVertexBuffers. Это происходит потому, что VkVertexInputBindingDescription структура с индексом 1 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
:
ОШИБКА [по умолчанию] СК: (ОБЪЕКТ 0) (КОД 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);
"* При вызове vkCmdDraw появляется следующее сообщение: *« Чтобы узнать, что происходит, нам нужно увидеть фактические команды, которые вы отправляете * до *, которые вы визуализируете. –
Я думаю, что vkCmdBindVertexBuffers будут очень важны для первого варианта. –
@NicolBolas. Вы действительно? В моем сообщении содержатся вопросы, связанные с пулями, которые довольно общие. Кроме того, у меня нет разрешения сбрасывать весь код где-то для вас. – Brent