是否只允许使用常量,还是可以使用循环索引或任何其他动态值?
答案 0 :(得分:4)
在 WebGL / GLES2 :是的,只允许使用常量。但是,如果您的代码可以展开(无论是由您自己还是由编译器),那么它将被视为常量并且您有一个解决方法。例如,
问题:
uniform int i;
...
int a[4];
a[2] = 42; // ✓ a constant index, no worries
a[i] = 42; // ✗ dynamic indexing is not allowed
解决方法:
if (i == 0) a[0] = 42;
if (i == 1) a[1] = 42;
if (i == 2) a[2] = 42;
if (i == 3) a[3] = 42;
好的,那真是太痛苦了。让我们让编译器这样做:
for (int k = 0; k < 4; ++k)
if (i == k)
a[k] = 42; // ✓ k is a constant because the loop is bounded by one
有时嵌套分支可以使事情变得更快(在这种情况下并非总是如此,这只是一个例子):
if (i == 0)
a[0] = 42;
else
{
if (i == 1)
a[1] = 42;
else
{
if (i == 2)
a[2] = 42;
else
{
if (i == 3)
a[3] = 42;
}
}
}
// or equivalently...
for (int k = 0; k <= i && k < 4; ++k)
if (i == k)
a[k] = 42;
对于您拥有动态索引的桌面GL,这仍然非常有用。特别是在动态索引数组的情况下,展开循环和使用常量允许将值放在寄存器中,您可以大大提高速度。另请注意,如果int[4]
数组被动态索引,则将其放入本地内存,每个元素都是padded to 16 bytes(即ivec4[4]
),这也是循环展开的修复。