奇怪的着色器腐败

时间:2011-09-26 17:02:26

标签: c++ glsl shader

我刚刚与着色器合作,我正在观察一些非常奇怪的行为。我加载了这个顶点着色器:

#version 150

uniform float r;
uniform float g;
uniform float b;
varying float retVal;
attribute float dummyAttrib;

void main(){
    retVal = dummyAttrib+r+g+b; //deleting dummyAttrib = corruption
    gl_Position = gl_ModelViewProjectionMatrix*vec4(100,100,0,1);
}

首先,我使用此着色器使用glDrawArrays(GL_POINTS,0,1000)进行渲染,没有任何特殊之处,只需使用着色器程序。如果运行此着色器并将点大小设置为可见的值,则应在屏幕中间看到白色方块(我正在使用glOrtho2d(0,200,0,200))。 DummyAttrib只是一些属性 - 如果没有,我的着色器将无法运行。此外,我需要实际使用该属性,所以通常我会做float c = dummyAttrib之类的事情。这也是我想问的问题,为什么会这样。

然而,这样会好的,但是当您将带有注释(retval=...)的行更改为retVal = r+g+b;并添加该提及的行以使用attrib(float c = dummyAttrib)时,会发生奇怪的事情。首先,你不会再看到那个方块了,所以我不得不设置变换反馈以观察正在发生的事情。

我在字段的每个元素中将dummyAttrib设置为5,并且r = g = b = 1。使用当前代码,转换反馈的结果为8 - 正是您所期望的。然而,如上所述更改它会产生奇怪的值,如250.128,每当我以某种方式修改代码(只是重新排序调用)时,此值会更改。一旦我将dummyAttrib返回到retVal的计算中,一切都被神奇地修复了。

这就是我认为存在某种着色器腐败的原因。我正在使用相同的着色器加载界面,就像我之前在项目中所做的那样,它们完美无缺,但是它们以正常方式使用属性,而不仅仅是实际运行着色器的虚拟。

这两个问题可以有联系。总结一下 - 如果该属性不用于设置片段着色器或变换反馈中使用的变化,则着色器将不会在没有任何属性的情况下运行并且着色器已损坏。

PS:当我写这篇文章时,我想到看起来每个未用于传入下一阶段的变量都是选择退出。这也可以选择退出属性,然后此着色器将没有属性,并且无法正常工作。这可能是司机的错吗?我有Radeon 3870HD,目前催化剂版本为2010.1105.19.41785。

1 个答案:

答案 0 :(得分:1)

如果您的人工使用(float c = dummyAttrib),属性将被优化。问题是你的网格准备逻辑在这种情况下做了什么。如果它从GL查询使用的属性,它什么也得不到。如果没有传递顶点属性,则不会绘制基元(我的Radeon 2400HD在任何Catalyst上的行为)。

因此,基本上,如果GL报告属性完全没有,你应该传递一个人为的非使用属性(如某些未初始化的缓冲区上每个顶点1个字节)。