我目前有这个顶点着色器:
#version 130
in vec3 position;
in vec2 textureCoords;
in vec3 normal;
out vec2 pass_textureCoords;
out vec3 surfaceNormal;
out vec3 toLightVector;
uniform vec3 lightPosition;
void main(void){
surfaceNormal = normal;
toLightVector = vec3(1, 100, 1);
gl_Position = ftransform(); #Yes, I use the fixed-function pipeline. Please don't kill me.
pass_textureCoords = textureCoords;
}
这很好用,但是当我添加它时:
#version 130
in vec3 position;
in vec2 textureCoords;
in vec3 normal;
out vec2 pass_textureCoords;
out vec3 surfaceNormal;
out vec3 toLightVector;
uniform vec3 lightPosition;
void main(void){
vec3 pos = position; #Completely USELESS added line
surfaceNormal = normal;
toLightVector = vec3(1, 100, 1);
gl_Position = ftransform();
pass_textureCoords = textureCoords;
}
整个物体变成黑色(或者有时变成绿色,但你明白了 - 它不起作用)。
预期行为: 实际行为: (地形和水的渲染没有任何着色器,因此它们不会被更改)
好像变量"位置"是有毒的 - 如果我在任何地方使用它,即使是无用的东西,我的着色器根本无法正常工作。
为什么会发生这种情况,我该如何解决?
答案 0 :(得分:3)
您遇到了问题,因为您在顶点着色器中使用固定功能位置属性,并且绑定到位置0的通用属性。这是无效的。
虽然您未明确使用固定功能gl_Vertex
属性,但此处隐含了用法:
gl_Position = ftransform();
这一行大部分与此相当,还有一些额外的精确保证:
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
但是你也在使用这个职位的通用属性:
in vec3 position;
...
vec3 pos = position;
如果为此通用属性指定位置0,则结果是无效的着色器程序。我在OpenGL 3.3兼容性配置文件规范的第94页上找到了以下内容,参见" 2.14.3顶点属性":
如果程序对象中使用的顶点着色器包含分配给通用属性零和传统顶点位置(gl_Vertex)的属性变量的赋值(在预处理期间未删除),则LinkProgram也将失败。
为了避免这个问题,理想的方法当然是不再使用固定的功能属性,而是采用OpenGL核心配置文件。如果这超出了您可以解决的工作范围,则至少需要避免将位置0分配给任何通用顶点属性。你可以:
glBindAttribLocation()
设置通用属性的位置时,所有属性均为0。glGetAttribLocation()
获取自动分配的位置。