我可以在 WebGL 的 GLSL 中使用什么作为数组索引?

What can I use as an array index in GLSL in WebGL ?

是否只允许常量,或者我可以使用 for 循环索引或任何其他动态值吗?

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]),这循环展开也修复了。