关于OpenGL不变限定符的困惑

时间:2013-09-25 00:01:03

标签: opengl

所以我正在阅读橙皮书(第3版),我在第9章中看到了关于不变限定符的段落。它说:

  

不变限定符指示编译器并链接到忽略与输出计算无直接关系的表达式和函数。

这段经文是在两段相似的代码片段之后发布的:

uniform mat4 MVPmatrix;
// ...

in vec4 MCVertex;
// ...

a(); // does not modify gl_Position, MVP or MCVertex

// ...
// Transform vertex to clip space
gl_Position = MVP * MCVertex;

uniform mat4 MVPmatrix;
// ...

invariant gl_Position;
in vec4 MCVertex;
// ...

a(); // does not modify gl_Position, MVP or MCVertex

// ...
// Transform vertex to clip space
gl_Position = MVP * MCVertex;

然后这本书继续陈述:

  

第一种情况可能会也可能不会以完全相同的方式计算转换后的位置,无论哪种不相关的函数或表达式链接到着色器。如果使用多遍算法多次渲染相同的几何体,这可能会导致渲染问题。

让我感到困惑。如果a()决不会影响计算变换位置所涉及的变量,那么计算将如何变化? (添加invariant对此有何帮助?)。并且参考第一个引用,他们究竟是什么意思“忽略不相关的功能”?他们只是没有被处决吗?

2 个答案:

答案 0 :(得分:10)

invariant的目的是确保您正在进行的计算始终会产生相同的结果,无论着色器优化器将对着色器执行什么操作(特别是跨多个着色器编译)。

我发现橙皮书的措词很差(并且误导,正如你所指出的那样)。 GLSL规范(语言1.2)第4.6节更清晰:

  

在本节中,差异是指获得的可能性   来自不同程序中相同表达式的不同值。对于   例如,说两个顶点着色器,在不同的程序中,每组   gl_Position在两个着色器和输入中具有相同的表达式   两个着色器运行时,该表达式中的值都相同。它是   可能,由于两个着色器的独立编译,即   分配给gl_Position的值在两者中不完全相同   着色器运行。在此示例中,这可能会导致对齐问题   多遍算法中的几何。一般来说,这种差异   着色器之间是允许的。当a不存在这种差异时   特定的输出变量,该变量被认为是不变的。

并继续解释invariant限定符可以保证您避免此问题。

答案 1 :(得分:3)

invariant关键字是(简而言之,与Bahbar更详细的答案形成鲜明对比),更多关于可能出现的非常细微的计算差异,如您所提到的,多个几何过程。

这是一个例子:你在屏幕上绘制一个任意的,奇怪的(使其更难)三角形。光栅化器获取标准化顶点并计算它占据的所有片段,然后在其上运行片段着色器。现在,想象一下你想在它上面绘制另一个三角形,但是3个小时后,当你的电脑被淹没时,温度下降,你在此期间吃了一顿午餐。然后重新编译着色器,然后bam ......

所有这些都可能影响光栅化器。着色器优化可能会启动并对输出进行负面更改。虽然技术上仍然正确,但结果不一定必须与第一个三角形完全相同,而“问题”将是剩下的第一个像素。

invariant确保采用可能较慢的方法。我不是驱动程序架构师,请注意,但总的来说,这可能意味着一些额外的状态重置,清理或有时状态堆栈推送/弹出。只有这样你就会处于“干净”的计算状态,只要你的硬件没问题,结果应该完全一样。