GLSL片段着色器中的flat变量是否被视为动态均匀表达式?

4
这个OpenGL论坛帖子中提到:

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

我试图在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 修饰符,所以属于已定义行为吗?还是不属于?


@BDL 谢谢您的关注,同时3.3版本的信息对我很有用,这很好! - Water
@Water: "此外,这个页面似乎也暗示了平坦的工作方式……" 绝对不是。你在哪里看到有任何暗示这样的事情? - Nicol Bolas
@NicolBolas 我错了,已删除链接。 - Water
1个回答

4
这是一个非常复杂的问题,实际上它的规范语言已经发生了变化(多亏了Vulkan,实际上澄清了许多这些问题,语言措辞被复制回OpenGL中)。确实,在OpenGL错误数据库中有几个与此主题相关的未解决问题。
但简而言之,flat限定的变量不是动态均匀的。更具体地说,它们通常不是动态均匀的。
关于动态均匀表达式需要记住的是,它是关于表达式的值是否对“调用组”内的不同调用有所不同。如果对所有调用来说,值都是相同的,则它就是动态均匀的。
在GLSL 4.60中,“调用组”的定义为:
“调用组是完整的调用集合,共同处理特定的计算工作组或图形操作,其中“图形操作”的范围取决于实现,但至少与单个三角形或补丁一样大,并且最多与单个渲染命令一样大,由客户端API定义。”
很不幸,“客户端API”这个术语是从SPIR-V规范中逐字复制的。在这种情况下,客户端API是OpenGL,但OpenGL规范实际上并没有定义调用组的大小。当前的OpenGL问题跟踪遗漏了这一点,告诉我们ARB的意图是OpenGL定义与Vulkan定义基本相匹配。而Vulkan定义是:对于图形着色器,调用组是给定着色器阶段的着色器调用集合的实现相关子集,由单个绘图命令产生。因此,调用组比单个基元更大。因此,如果恰好将相同的值传递给绘图命令中的每个基元,则flat限定变量才能动态统一。
所以,不能假设一个flat限定的变量是动态统一的,仅仅因为它是flat限定的。对于uniformconst限定的全局变量,或类似数据,则可以做出这样的假设。但是,除非你已经采取一些措施确保在渲染命令内的每次调用都获得相同的flat值,否则无法在需要动态统一表达式的地方使用它。

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