Vulkan顶点属性未被着色器消费 顶点/颜色修改无效排查
Vulkan C++开发顶点数据修改不生效问题
- 参照教程学习基于C++的Vulkan图形开发时,遇到顶点数据修改完全不生效的问题:无论如何手动修改顶点坐标、顶点颜色参数,程序始终固定渲染一个红、绿、蓝三色插值的三角形,顶点位置和颜色都没有任何变化,渲染效果示例图。
- 程序中定义的顶点数组如下,预期顶部为绿色、左下角为蓝色、右下角为红色:
const std::vector<Vertex> vertices = { {{0.0f, -0.5f}, {0.0f, 1.0f, 0.0f}}, // 顶部绿色 {{-0.5f, 0.5f}, {0.0f, 0.0f, 1.0f}}, // 左下角蓝色 {{0.5f, 0.5f}, {1.0f, 0.0f, 0.0f}}, // 右下角红色 };
- 实际渲染结果和定义的顶点属性完全不符:红色位于三角形顶部,蓝色和绿色位于底部。
- 控制台输出验证层提示,说明顶点数据无法传入顶点着色器(约定location 0对应顶点位置、location 1对应顶点颜色),检索该报错的相关解决方案后,始终未能定位问题。
具体报错内容为:
validation error: Validation Performance Warning: [ UNASSIGNED-CoreValidation-Shader-OutputNotConsumed ] Object 0: handle = 0xec4bec0000000000b, type = VK_OBJECT_TYPE_SHADER_MODULE; | MessageID = 0x609a13b | Vertex attribute at location 0 not consumed by vertex shader
按照设计,location 0应为vec2类型的顶点屏幕位置输入,location 1应为vec3类型的顶点颜色输入。
顶点着色器(GLSL)代码
#version 450 layout(location = 0) in vec2 inPosition; layout(location = 1) in vec3 inColor; layout(location = 0) out vec3 fragColor; void main() { gl_Position = vec4(inPosition, 0.0, 1.0); fragColor = inColor; }
顶点缓冲区创建C++代码
void createVertexBuffer() { VkBufferCreateInfo bufferInfo{}; bufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; bufferInfo.size = sizeof(vertices[0]) * vertices.size(); bufferInfo.usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT; bufferInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE; if (vkCreateBuffer(device, &bufferInfo, nullptr, &vertexBuffer) != VK_SUCCESS) { throw std::runtime_error("failed to create vertex buffer!"); } }
命令缓冲区录制阶段绑定顶点缓冲区C++代码
void RTXApp::recordCommandBuffer(VkCommandBuffer commandBuffer, uint32_t imageIndex) { VkCommandBufferBeginInfo beginInfo{}; beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; beginInfo.flags = 0; beginInfo.pInheritanceInfo = nullptr; // 错误捕获 if (vkBeginCommandBuffer(commandBuffer, &beginInfo) != VK_SUCCESS) { throw std::runtime_error("failed to begin recording command buffer!"); } VkRenderPassBeginInfo renderPassInfo{}; renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; renderPassInfo.renderPass = renderPass; renderPassInfo.framebuffer = swapChainFramebuffers[imageIndex]; renderPassInfo.renderArea.offset = { 0, 0 }; renderPassInfo.renderArea.extent = swapChainExtent; VkClearValue clearColor = { {{0.0f, 0.0f, 0.0f, 1.0f}} }; // 设置默认清屏颜色为黑色 renderPassInfo.clearValueCount = 1; renderPassInfo.pClearValues = &clearColor; // 开始渲染通道 vkCmdBeginRenderPass(commandBuffer, &renderPassInfo, VK_SUBPASS_CONTENTS_INLINE); // 绑定图形管线对象到命令缓冲区 vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, graphicsPipeline); // 绑定绘制用的顶点缓冲区 VkBuffer vertexBuffers[] = { vertexBuffer }; VkDeviceSize offsets[] = { 0 }; vkCmdBindVertexBuffers(commandBuffer, 0, 1, vertexBuffers, offsets); // 从顶点缓冲区发起绘制 vkCmdDraw(commandBuffer, static_cast<uint32_t>(vertices.size()), 1, 0, 0); // 结束渲染通道 vkCmdEndRenderPass(commandBuffer); // 错误捕获 if (vkEndCommandBuffer(commandBuffer) != VK_SUCCESS) { throw std::runtime_error("failed to record command buffer!"); } }
排查情况与运行环境
- 分别测试自行编写的代码、所用教程提供的参考代码,均出现相同问题。编写过程严格遵循教程步骤,每一步确认配置正确后才进入下一环节,检索该特定问题的相关解决方案未找到有效参考,目前无法定位故障点。
- 运行环境为Windows 11,使用MSVS 2022、Windows 10版本Vulkan SDK,项目配置完全符合教程给出的Windows环境搭建要求。
补充:VkPipelineVertexInputCreateInfo相关配置代码
auto vertShaderCode = readFile("shaders/vert.spv"); auto fragShaderCode = readFile("shaders/frag.spv"); VkShaderModule vertShaderModule = createShaderModule(vertShaderCode); VkShaderModule fragShaderModule = createShaderModule(fragShaderCode); // 创建管线的顶点着色器阶段 VkPipelineShaderStageCreateInfo vertShaderStageInfo{}; vertShaderStageInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; vertShaderStageInfo.stage = VK_SHADER_STAGE_VERTEX_BIT; vertShaderStageInfo.module = vertShaderModule; vertShaderStageInfo.pName = "main"; // 创建管线的片元着色器阶段 VkPipelineShaderStageCreateInfo fragShaderStageInfo{}; fragShaderStageInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; fragShaderStageInfo.stage = VK_SHADER_STAGE_FRAGMENT_BIT; fragShaderStageInfo.module = fragShaderModule; fragShaderStageInfo.pName = "main"; // 存储着色器阶段配置的数组(顶点着色器在前,片元着色器在后) VkPipelineShaderStageCreateInfo shaderStages[] = { vertShaderStageInfo, fragShaderStageInfo }; VkPipelineVertexInputStateCreateInfo vertexInputInfo{}; vertexInputInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO; auto bindingDescription = Vertex::getBindingDescription(); auto attributeDescriptions = Vertex::getAttributeDescriptions(); vertexInputInfo.vertexBindingDescriptionCount = 1; vertexInputInfo.pVertexBindingDescriptions = &bindingDescription; vertexInputInfo.vertexAttributeDescriptionCount = static_cast<uint32_t>(attributeDescriptions.size()); vertexInputInfo.pVertexAttributeDescriptions = attributeDescriptions.data();
恳请各位开发者帮忙提供排查方向,非常感谢。
内容的提问来源于stack exchange,提问作者Jyapp448
相关产品推荐
相关产品推荐

