我可以在 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]
),这循环展开也修复了。
是否只允许常量,或者我可以使用 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]
),这循环展开也修复了。