GLSL 变量将对象变成黑色
GLSL variable turns object black
我目前有这个顶点着色器:
#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;
}
整个对象只是变黑(有时变绿,但你明白了 - 它不起作用)。
预期行为:
实际行为:
(地形和水没有任何着色器渲染,因此它们没有改变)
好像变量 "position" 有毒 - 如果我在任何地方使用它,即使是无用的东西,我的着色器也无法正常工作。
为什么会发生这种情况,我该如何解决?
您 运行 遇到了问题,因为您在顶点着色器中同时使用了固定函数位置属性和绑定到位置 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 顶点属性”部分找到了以下内容:
LinkProgram will also fail if the vertex shaders used in the program object contain assignments (not removed during pre-processing) to an attribute variable bound to generic attribute zero and to the conventional vertex position (gl_Vertex).
要避免这个问题,理想的方法当然是摆脱使用固定功能属性,而采用 OpenGL Core Profile。如果这超出了您可以处理的工作范围,您至少需要避免将位置 0 分配给任何通用顶点属性。您可以:
- 当您使用
glBindAttribLocation()
设置通用属性的位置时,对所有属性使用 > 0 的位置。
- 根本不要设置位置,并在 link 程序后使用
glGetAttribLocation()
获取自动分配的位置。
我目前有这个顶点着色器:
#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;
}
整个对象只是变黑(有时变绿,但你明白了 - 它不起作用)。
预期行为:
好像变量 "position" 有毒 - 如果我在任何地方使用它,即使是无用的东西,我的着色器也无法正常工作。
为什么会发生这种情况,我该如何解决?
您 运行 遇到了问题,因为您在顶点着色器中同时使用了固定函数位置属性和绑定到位置 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 顶点属性”部分找到了以下内容:
LinkProgram will also fail if the vertex shaders used in the program object contain assignments (not removed during pre-processing) to an attribute variable bound to generic attribute zero and to the conventional vertex position (gl_Vertex).
要避免这个问题,理想的方法当然是摆脱使用固定功能属性,而采用 OpenGL Core Profile。如果这超出了您可以处理的工作范围,您至少需要避免将位置 0 分配给任何通用顶点属性。您可以:
- 当您使用
glBindAttribLocation()
设置通用属性的位置时,对所有属性使用 > 0 的位置。 - 根本不要设置位置,并在 link 程序后使用
glGetAttribLocation()
获取自动分配的位置。