我真的很奇怪,我pin down
现在几天都不能.我正在制作一个简单的每顶点照明,它可以正常工作Nvidia
,但不会渲染任何带灯光的阴影AMD/ATI
.我追踪了与属性有关的问题 - 特别是颜色属性.
这是我的顶点着色器:
#version 140 uniform mat4 modelViewProjectionMatrix; in vec3 in_Position; // (x,y,z) in vec4 in_Color; // (r,g,b,a) in vec2 in_TextureCoord; // (u,v) out vec2 v_TextureCoord; out vec4 v_Color; uniform bool en_ColorEnabled; uniform bool en_LightingEnabled; void main() { if (en_LightingEnabled == true){ v_Color = vec4(0.0,1.0,0.0,1.0); }else{ if (en_ColorEnabled == true){ v_Color = in_Color; }else{ v_Color = vec4(0.0,0.0,1.0,1.0); } } gl_Position = modelViewProjectionMatrix * vec4( in_Position.xyz, 1.0); v_TextureCoord = in_TextureCoord; }
这是像素着色器:
#version 140 uniform sampler2D en_TexSampler; uniform bool en_TexturingEnabled; uniform bool en_ColorEnabled; uniform vec4 en_bound_color; in vec2 v_TextureCoord; in vec4 v_Color; out vec4 out_FragColor; void main() { vec4 TexColor; if (en_TexturingEnabled == true){ TexColor = texture2D( en_TexSampler, v_TextureCoord.st ) * v_Color; }else if (en_ColorEnabled == true){ TexColor = v_Color; }else{ TexColor = en_bound_color; } out_FragColor = TexColor; }
因此,这个着色器允许3种状态 - 当我使用灯光时,当我不使用灯光时,但是使用每顶点颜色,并且当我对所有顶点使用单一颜色时.我删除了所有的光计算代码,因为我将问题追溯到属性.这是着色器的输出:
正如你所看到的,一切都是蓝色的(所以它渲染了没有阴影或颜色的所有东西(en_LightingEnabled == false and en_ColorEnabled == false)
).
当我在顶点着色器中替换此代码时:
if (en_ColorEnabled == true){ v_Color = in_Color; }else{
有了这个:
if (en_ColorEnabled == true){ v_Color = vec4(1.0,0.0,0.0,1.0); }else{
我得到以下内容:
所以你可以看到它呈现的所有内容都没有着色仍然是蓝色,但现在它也渲染了所有使用en_LightingEnabled == true
绿色的灯光().应该是这样的.问题是in_Color
属性不应该干扰灯光,因为如果启用灯光,它甚至都不会运行.您还可以看到图像中的任何内容都不是红色,这意味着在此场景en_ColorEnabled
中始终是false
.所以in_Color
在这里完全没用,但它在逻辑上不应该导致错误.在Nvidia
它上面工作正常,绿色区域有或没有in_Color
.
我用的东西AMD
不支持吗?我使用的是GLSL
规格以外的东西吗?我知道比规范AMD
更严格,所以我可能做一些未定义的事情.我使代码尽可能简单,仍然有问题,所以我没有看到它.
另外,我注意到如果顶点属性被禁用(no ),它将不会在屏幕上绘制任何(甚至蓝色区域),但为什么呢?我甚至不使用这种颜色.禁用属性需要通过规范返回()吗?我试着改变那种颜色,但仍然变黑.编译器和链接器不会返回任何错误或警告.找到属性in_Color就好了.但正如我所说,这一点都不重要,因为该分支永远不会在我的代码中执行.有任何想法吗?GL
Nvidia
in_Color
glEnableVertexAttribArray
0,0,0,1
glVertexAttrib4f
glGetAttribLocation
测试Nvidia660Ti
并且工作正常,在ATI
mobility radeon HD 5000
笔记本电脑上测试并出现此错误.我唯一的想法是,我可能超出了GPU
(太多属性等等)的功能,但是当我将代码缩减到此时,我就不再相信了.我这里只使用3个属性.
此外,我的一些朋友在更新的AMD
卡上测试并遇到了同样的问题.
更新1
顶点属性的绑定方式如下:
if (useColors){ glUniform1i(uni_colorEnable,1); glEnableVertexAttribArray(att_color); glVertexAttribPointer(att_color, 4, GL_UNSIGNED_BYTE, GL_TRUE, STRIDE, OFFSET(offset)); }else{ glUniform1i(uni_colorEnable,0); }
此外,我发现如何更容易地显示怪异 - 采用此顶点着色器:
void main() { v_Color = clamp(vec4(1.,1.,1.,1.) * vec4(0.5,0.5,0.25,1.),0.0,1.0) + in_Color; gl_Position = modelViewProjectionMatrix * vec4( in_Position.xyz, 1.0); v_TextureCoord = in_TextureCoord; }
所以没有分支.我得到了这个:
如果我通过删除in_Color
这样改变代码:
void main() { v_Color = clamp(vec4(1.,1.,1.,1.) * vec4(0.5,0.5,0.25,1.),0.0,1.0); gl_Position = modelViewProjectionMatrix * vec4( in_Position.xyz, 1.0); v_TextureCoord = in_TextureCoord; }
我明白了:
最后一个是我所期望的,但前一个没有绘制任何东西,即使我做add(+
)而不是其他任何东西.因此,如果attrib
没有绑定并给出(0,0,0,0
)或(0,0,0,1
),那么它不应该做任何事情.然而它仍然失败.
此外,所有日志都是空的 - 编译,链接和验证.没有错误或警告.虽然我注意到着色器调试信息AMD/ATI
给出的信息远远低于Nvidia
给出的信息.
更新2
我发现的唯一修复是attribarray
在所有情况下都启用(因此它基本上会GPU
在没有启用颜色的情况下发送垃圾),但是当我使用制服来检查颜色时,我就是不使用它.所以它是这样的:
if (useColors){ glUniform1i(uni_colorEnable,1); }else{ glUniform1i(uni_colorEnable,0); } glEnableVertexAttribArray(att_color); glVertexAttribPointer(att_color, 4, GL_UNSIGNED_BYTE, GL_TRUE, STRIDE, OFFSET(offset));
我不知道为什么会发生这种情况或为什么我需要使用它.我不需要那个Nvidia
.所以我想这会慢一点我浪费带宽?但至少它是有效的...但如何更好地做到这一点的帮助将是有用的.