GLSL片段着色器是否被认为是动态统一的表达式?

时间:2018-02-12 23:09:43

标签: opengl glsl

this OpenGL forum post中有人说:

  

在GLSL 4.x中,采样器数组只能用动态统一表达式进行索引(在顶点着色器中表达式可能只涉及统一变量,在片段着色器中它可能只涉及统一变量和平坦限定输入)

我试图在GLSL规范中寻找这个,但无法找到它。如果代码不起作用,我会花点时间更改代码,这有点紧张。我最担心的是,如果我这样做,它似乎在我的计算机上工作,但我在不知道的情况下调用未定义的行为(某些时候可能会在某个地方结束)。

我想做的一个例子(我没有运行它,它是一个例子,应该被认为是伪代码):

// Fragment shader

in vec3 uv;
flat in uint index;  // Assume in the range of 0 to 3 inclusive

uniform sampler3D textureSampler[4];

void main() {
    someColor = texture(textureSampler[index], uv);
    // ...
}

这是定义的行为,因为它具有 flat 限定符吗?还是不?

1 个答案:

答案 0 :(得分:4)

这是一个非常复杂的问题,实际上已经改变了规范语言(感谢Vulkan实际澄清了很多这些问题,语言措辞被复制回OpenGL)。实际上,在OpenGL错误数据库中有关于此主题的一些未解决的问题。

但简而言之,没有:flat - 限定变量不是动态统一的。或者更具体地说,它们通常不是动态统一的。

关于动态统一表达式要记住的事情是关于表达式的对于"调用组中的不同调用是否不同" (如下所述)。如果所有调用的值都相同,则它是动态统一的。

"调用组"在GLSL 4.60中定义为:

  

调用组是集合处理特定计算工作组或图形操作的完整调用集,其中"图形操作的范围"是依赖于实现的,但至少与单个三角形或补丁一样大,并且至多与单个渲染一样大   命令,由客户端API定义。

不幸的是,这个"客户端API"语言是从SPIR-V规范中逐字复制的。在这种情况下,客户端API是OpenGL,但OpenGL规范实际上并没有定义调用组的大小。

current OpenGL issue tracking this omission告诉我们,ARB的意图是OpenGL定义或多或少与Vulkan定义相匹配。 Vulkan的定义是:

  

对于图形着色器,调用组是给定着色器阶段的着色器调用集的依赖于实现的子集,由单个绘图命令生成。

因此,调用组比单个基元大。因此,如果恰好将相同的值传递给绘图命令中的每个基元,则flat - 限定变量将只是动态统一。

因此,您不能认为flat限定变量是动态一致的,因为它是flat限定的。您可以假设uniformconst符合条件的全局变量,或来自类似数据。但除非您已经完成了确保渲染命令中的每个调用都获得相同flat值的内容,否则您无法在需要动态统一表达式的位置使用它。