OpenGL着色器:如何防止优化器删除属性/统一变量

7
有没有办法防止着色器编译器删除被检测为未使用的uniform/attribute? 我有时会注释掉我的着色器的某些部分进行测试,但这会在程序的其他部分中引起问题,因为突然某些名称不存在(从而导致查找错误和设置值时出错)。

我认为你不能这样做。相反,你应该在调用程序中添加逻辑,检查在尝试访问它们之前是否存在统一/属性。 - umläute
这就是导致问题的确切逻辑。程序的其余部分需要该属性才能工作,否则它将充斥着一堆if语句 - 而我正试图避免这种情况。 - edA-qa mort-ora-y
@edA-qamort-ora-y 嗯,获取不存在的统一变量的位置应该只返回-1,使用-1调用glUniform不会有任何损害,除了可能会生成一个GL错误外,谁在乎呢? - Christian Rau
2个回答

3
不是必须的,这取决于您编写代码的方式。 glUniform* 函数可以轻松地接受 -1 的统一位置。如果您正在使用 program_pack420 和 explicit_attrib_location,则可以将属性索引、片段着色器输出、UBO 绑定和纹理单元绑定全部放在着色器中。因此,您不必查询活动属性、输出、统一块或采样器。请注意,GL 4.3 中还有 ARB_explicit_uniform_location,因此您可以在着色器中指定它们,它们不会被优化掉。如果没有给出OpenGL属性索引,那么您会遇到这种情况,无论是使用 explicit_attrib_location 还是在链接前调用 glBindAttribLocation。这是糟糕的编码,您不应该以这种方式进行操作。始终告诉OpenGL您的属性位置。除非您正在编写着色器内省工具,否则不应查询它们。块引用文本结束

它将需要相当高的OpenGL版本。 - Bartek Banachewicz
1
@Bartek:不是的。program_pack420和explicit_attrib_location在OpenGL 2.1实现中可用。它们在那里运行得很好。NVIDIA为他们仍然支持的2.1级硬件公开了它们。简而言之,如果您可以为其获得相当新的驱动程序,则它们将存在。 - Nicol Bolas
1
@edA-qamort-ora-y 是的,对于uniform变量来说并不重要,因为调用glUniform(-1, ...)(由于glGetUniformLocation返回-1表示不存在)是一个无操作。 - Christian Rau
1
即使没有explicit_attrib_location,您仍然可以使用glBindAttribLocation,它始终受支持并且实际上执行相同的操作(尽管在应用程序中而不是着色器中)。对于uniform变量,无论如何都没有关系,就像Nicol已经解释过的那样。@BartekBanachewicz - Christian Rau
1
@BartekBanachewicz 如果有一个扩展(即使是核心扩展)适用于您的硬件/驱动程序,您可以使用它。仅因为这些功能仅包含在GL 3+的核心版本中,并不意味着当您在GL 2中使用它们时,您正在进入未定义的行为或黑魔法,而它们完全受支持(无论如何,您也不会在非nVidia硬件上使用桌面GL)。 - Christian Rau
显示剩余3条评论

-1
通常,我使用 glGetUniformLocation 返回的 -1 来检测错误。因此,我认为仅仅忽略 -1 并不是一个好主意。 但是,我找到了解决这个问题的一个巧妙方法。 我将所有的 uniform 变量相加,赋值给输出颜色之前的一个标识符,并在 if(condition) 语句中使用它。例如:
if(condition)
{
    outputColor = uniformSum;
}

如果你让条件始终为假,例如编写if(val < 0)val始终为正值,则可以避免编译器优化均匀变量。


这段代码应该放在主函数的末尾。 - doyoubi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接