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

GLSL顶点着色器已用输入属性被编译器优化移除问题咨询

问题描述

参照Sascha Willems的点光源阴影映射示例开发时,出现着色器无法接收传入顶点属性的问题。通过RenderDoc内置着色器反编译工具核查发现,GLSL编译器已将着色器所有输入属性全部优化移除:

  • location 1~3对应的color、normal、uv属性未被实际使用,被优化符合预期
  • location 0的position属性已在着色器代码中被调用,却仍被优化移除

对应顶点着色器代码:

#version 450

layout(location = 0) in vec3 position;
layout(location = 1) in vec3 color;
layout(location = 2) in vec3 normal;
layout(location = 3) in vec2 uv;

layout(location = 0) out vec4 outPos;

struct PointLight {
    vec4 position;
    vec4 color;
};

layout(set = 0, binding = 0) uniform GlobalUbo {
    mat4 projection;
    mat4 view;
    mat4 inverseView;
    vec4 ambientLightColor;
    PointLight pointLights[10];
    int numLights;
} ubo;

layout(push_constant) uniform Push {
    mat4 modelMatrix;
    mat4 viewMatrix;
} push;

void main() {
    vec4 positionWorld = push.modelMatrix * vec4(position, 1.0);
    gl_Position = ubo.projection * push.viewMatrix * positionWorld;
    outPos = vec4(position, 1.0);
}

对应片段着色器代码:

#version 450

layout(location = 0) out float outFragColor;

layout(location = 0) in vec4 inPos;

struct PointLight {
    vec4 position;
    vec4 color;
};

layout(set = 0, binding = 0) uniform GlobalUbo {
    mat4 projection;
    mat4 view;
    mat4 inverseView;
    vec4 ambientLightColor;
    PointLight pointLights[10];
    int numLights;
} ubo;

void main()
{
    vec3 lightVec = inPos.xyz - ubo.pointLights[0].xyz;
    outFragColor = length(lightVec);
}
问题原因与解决方案

这是Vulkan开发中非常典型的管线状态与着色器不匹配触发的编译器自动优化,按概率从高到低排查即可:

  • 顶点输入状态配置缺失
    90%以上的同类问题都是这个原因:Vulkan驱动在编译链接管线时会做静态检查,如果你在VkPipelineVertexInputStateCreateInfo中没有为location = 0的position属性添加对应的VkVertexInputAttributeDescription,或是绑定的顶点缓冲stride、输入速率配置错误,驱动会直接判定该location没有有效顶点输入,SPIR-V优化器会直接移除这个输入变量以及所有依赖它的计算逻辑,完全不会管你在GLSL代码里有没有写调用逻辑。排查时直接核对管线创建时的顶点属性配置,确认location 0对应3分量32位浮点数格式、偏移和stride和顶点缓冲的实际内存布局匹配即可。
  • 着色器编译选项触发激进优化bug
    如果你使用glslangValidator、shaderc编译SPIR-V时开启了最高级别大小优化(-Osize),旧版本编译器存在错误移除已使用顶点属性的已知bug。可以尝试给编译参数加-O0关闭所有优化重新编译,若此时position属性恢复,升级着色器编译器版本即可解决。
  • Push常量范围配置不匹配
    检查管线中VkPushConstantRange配置的大小,你声明的Push结构体包含两个mat4,总大小为128字节,如果配置的range大小小于128字节,部分驱动会判定push常量中的矩阵为无效值,进而将依赖矩阵计算的gl_Position逻辑判定为无效,连带移除position输入。
  • 着色器链接错误
    检查管线创建时附着的顶点、片段着色器模块是否正确,排查是否存在错链其他着色器SPIR-V、入口点名字配置错误的低级问题。

内容的提问来源于stack exchange,提问作者Jark

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 16:51:42