我可以在WebGL中用作GLSL中的数组索引吗?

时间:2015-06-02 00:00:08

标签: arrays indexing glsl webgl

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

1 个答案:

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