如果我的vec4为NULL,我正在尝试检查着色器(GLSL)内部。我需要这个有几个原因,主要是为了让特定的显卡兼容,因为它们中的一些在gl_FragColor中传递了前一种颜色,而有些则没有(提供需要覆盖的空vec4)。 好吧,在一台相当新的Mac上,有人遇到了这个错误:
java.lang.RuntimeException: Error creating shader: ERROR: 0:107: '==' does not operate on 'vec4' and 'int'
ERROR: 0:208: '!=' does not operate on 'mat3' and 'int'
这是片段着色器中的代码:
void main()
{
if(gl_FragColor == 0) gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0); //Line 107
vec4 newColor = vec4(0.0, 0.0, 0.0, 0.0);
[...]
if(inverseViewMatrix != 0) //Line 208
{
[do stuff with it; though I can replace this NULL check with a boolean]
}
[...]
gl_FragColor.rgb = mix(gl_FragColor.rgb, newColor.rgb, newColor.a);
gl_FragColor.a += newColor.a;
}
正如您所看到的,我在开始时对gl_FragColor进行了0 / NULL检查,因为有些图形卡会在那里传递有价值的信息,但有些则没有。现在,在那个特殊的mac上,它没有用。我做了一些研究,但找不到有关如何在GLSL中进行正确的NULL检查的任何信息。是否有一个,或者我真的需要在这里制作单独的着色器吗?
答案 0 :(得分:9)
所有用于阅读的变量,即输入变量总是提供合理的值。作为输出变量,gl_FragColor
不是这些变量之一!
在此代码中
void main()
{
if(gl_FragColor == 0) gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0); //Line 107
vec4 newColor = vec4(0.0, 0.0, 0.0, 0.0);
您要做的第一件事就是从gl_FragColor
开始阅读。 GLSL规范明确指出,当输入片段着色器阶段( 1 )时,输出varialbe 的值为gl_FragColor
是未定义的:< / p>
在以下三种情况中的任何一种情况下,输出变量的值都将是 undefined :
- 执行开始时。
- 在每个同步点,除非
- 在上一次同步后,该值已明确定义 点,并且不是由任何调用写的,或
- 该值仅由一个着色器调用写入 上一个同步点,或
- 该值是由多个着色器调用写的 先前的同步点,以及上次执行的写入 所有这些调用都写了相同的值。
- 通过着色器调用读取时,如果
醇>
- 在前一次同步时未定义该值 点,并且从未被相同的着色器调用写入,或
- 输出变量由任何其他着色器写入 上一个和下一个同步点之间的调用, 即使该分配发生在阅读后的代码中。
只有在第一次写入输出变量的元素之后才定义其值。所以你在那里做的所有事情毫无意义。它“不起作用”是完全允许的,并且在你的结束时出错。
您正在调用未定义的行为,从技术上讲,允许您的计算机变得有意义,在街上追逐您并删除所有数据作为对此的替代反应。
在GLSL中, vec4 是一个常规数据类型,就像int一样。它不是指向可能是空指针的数组的某种指针。最好它有一些默认值,不会被 glUniform 的调用覆盖。
答案 1 :(得分:1)
总是定义GLSL着色器中的变量(否则,您将收到链接器错误)。如果您不为这些值提供数据(通过不将相应的统一或绑定属性加载到或属性变量中的),那么这些变量中的值将是未定义的(即垃圾),但现在。
答案 2 :(得分:0)
即使您不能拥有 null 值,也可以测试 undefined 变量。这是我用来调试着色器的技巧:
...
/* First we test for lower range */
if(suspect_variable.x < 0.5) {
outColour = vec4(0,1,0,0); /* Green if in lower range*/
} else if(suspect_variable.x >= 0.5) { /*Then for the higher range */
outColour = vec4(1,0,0,0); /* Red if in higher range */
} else {
/* Now we have tested for all real values.
If we end up here we know that the value must be undefined */
outColour = vec4(0,0,1,0); /* Blue if it's undefined */
}
您可能会问,什么可以使变量未定义?超出范围访问数组会导致它未定义;
const int numberOfLights = 2;
uniform vec3 lightColour[numberOfLights];
...
for(int i = 0; i < 100; i++) {
/* When i bigger than 1 the suspect_variable would be undefined */
suspect_variable = suspect_variable * lightColour[i];
}
当您无法访问真正的调试工具时,这是一个简单易用的技巧。