You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 21:09:18