Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Are there ONLY constants allowed or can I use for loop indices or any other dynamic values ?

like image 243
pixartist Avatar asked Jun 02 '15 00:06

pixartist


People also ask

How can I access an opaque array in GLSL?

Under GLSL 4.00 and above, array indices leading to an opaque value can be accessed by non-compile-time constants, but these index values must be dynamically uniform. The value of those indices must be the same value, in the same execution order, regardless of any non-uniform parameter values, for all shader invocations in the invocation group.

What are the requirements for array indices in GLSL?

When an array indexing expression, including struct field member accesses, results in an opaque types, the standard has special requirements on those array indices. Under GLSL version 3.30, Sampler arrays (the only opaque type 3.30 provides) can be declared, but they can only be accessed by compile-time integral Constant Expressions.

What are built-in variables in OpenGL?

Built-in Variable (GLSL) The OpenGL Shading Language defines a number of special variables for the various shader stages. These built-in variables (or built-in variables) have special properties. They are usually for communicating with certain fixed-functionality.

Is dynamic indexing in GL still useful?

With regard to desktop GL where you do have dynamic indexing this is still quite useful. Especially in the case of dynamically indexed arrays, unrolling loops and using constants allows values to be placed in registers and you can greatly improve speed.


1 Answers

In WebGL/GLES2: Yes, only constants are allowed. However if your code can be unrolled (either by yourself or by the compiler) then it counts as a constant and you have a workaround. For example,

The problem:

uniform int i;
...
int a[4];
a[2] = 42; // ✓ a constant index, no worries
a[i] = 42; // ✗ dynamic indexing is not allowed

The workaround:

if (i == 0) a[0] = 42;
if (i == 1) a[1] = 42;
if (i == 2) a[2] = 42;
if (i == 3) a[3] = 42;

Ok, that's pretty painful. Lets get the compiler to do that:

for (int k = 0; k < 4; ++k)
    if (i == k)
        a[k] = 42; // ✓ k is a constant because the loop is bounded by one

Sometimes nesting branches can make things faster (not always and not necessarily in this case, it's just an example):

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;

With regard to desktop GL where you do have dynamic indexing this is still quite useful. Especially in the case of dynamically indexed arrays, unrolling loops and using constants allows values to be placed in registers and you can greatly improve speed. As another side note, if the int[4] array is indexed dynamically it's placed into local memory and each element is padded to 16 bytes (i.e. ivec4[4]), which loop unrolling also fixes.

like image 185
jozxyqk Avatar answered Sep 23 '22 01:09

jozxyqk