在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 限定符吗?还是不?
答案 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
限定的。您可以假设uniform
或const
符合条件的全局变量,或来自类似数据。但除非您已经完成了确保渲染命令中的每个调用都获得相同flat
值的内容,否则您无法在需要动态统一表达式的位置使用它。