包含未使用的参数时,glsl Shader 不绘制 obj

glsl Shader does not draw obj when including not used parameters

我用 glsl 设置了一个 phong 着色器,效果很好。

当我在没有 "this line" 的情况下渲染我的对象时,它起作用了。但是当我取消注释 "this line" 时,世界仍然构建但对象不再呈现,尽管 "LVN2" 没有在 glsl 代码中的任何地方使用。着色器执行时不会抛出错误。我认为我的问题是一个相当普遍的 glsl 问题,如着色器如何正常工作。

主要代码写在java.

顶点着色器片段:

    // Light Vector 1
    vec3 lightCamSpace = vec4(viewMatrix * modelMatrix * lightPosition).xyz;
    out_LightVec = vec3(lightCamSpace - vertexCamSpace).xyz;

    // Light Vector 2
    vec3 lightCamSpace2 = vec4(viewMatrix * modelMatrix * lightPosition2).xyz;
    out_LightVec2 = vec3(lightCamSpace2 - vertexCamSpace).xyz;

片段着色器片段:

    vec3 LVN = normalize(out_LightVec);
    //vec3 LVN2 = normalize(out_LightVec2);  // <---- this line

编辑 1:

GL_MAX_VERTEX_ATTRIBS 是 29,glGetError 已经实现但没有抛出任何错误。

如果我改变

vec3 LVN2 = normalize(out_LightVec2);

vec3 LVN2 = normalize(out_LightVec);

它实际上再次渲染了对象。所以看起来真的有些东西已经用完了。 (LVN2 仍然没有在着色器中的任何一点使用)

我无法在您的着色器中发现错误。可能的一件事是您使用第五个四分量 out 插槽超出了 GL_MAX_VERTEX_ATTRIBS。 (虽然限制为 4 会很奇怪,但根据 this answer 最小支持数量应该是 16,在这种情况下它甚至不应该 link。然后你再次使用 GLSL 1.50,这意味着 OpenGL 3.2,太老了。我找不到说明属性计数最低要求的规范。)

它使用未注释行的原因可能是着色器编译器能够优化未使用的 in/out 参数,而在片段着色器主体中引用它时无法这样做。

你可以通过查询限制来验证我的猜测:

int limit;
glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &limit);

除此之外,我建议在绘制调用之前和之后插入 glGetError 查询,看看是否还有其他事情发生。

我真的发现了我绝对愚蠢的错误。在主程序中,我为着色器提供了错误的 viewMatrix 位置...但我不确定为什么它有时会起作用。