How Is gl_LocalInvocationIndex Calculated in GLSL?

In GLSL compute shaders, gl_LocalInvocationIndex is a built-in 1D integer variable that uniquely identifies an invocation within its local workgroup. It is computed by flattening the three-dimensional gl_LocalInvocationID into a single linear scalar value using row-major ordering where the X dimension is the most rapidly changing coordinate, followed by Y, and then Z. Understanding this calculation is essential for managing shared memory layouts, optimizing cache locality, and indexing flat buffers efficiently.

The Mathematical Formula

The relationship between the 3D local invocation identifier (gl_LocalInvocationID), the local workgroup dimensions (gl_WorkGroupSize), and the 1D index is defined formally by the OpenGL and Vulkan shading language specifications as:

\[gl\_LocalInvocationIndex = gl\_LocalInvocationID.z \times gl\_WorkGroupSize.x \times gl\_WorkGroupSize.y + gl\_LocalInvocationID.y \times gl\_WorkGroupSize.x + gl\_LocalInvocationID.x\]

In this equation:

Step-by-Step Example

Consider a compute shader defined with a local workgroup size of \(4 \times 4 \times 2\):

layout(local_size_x = 4, local_size_y = 4, local_size_z = 2) in;

For a thread executing at invocation coordinates gl_LocalInvocationID = uvec3(2, 3, 1):

  1. Multiply the Z coordinate by the total number of threads in an XY slice:

\[1 \times (4 \times 4) = 16\]

  1. Multiply the Y coordinate by the width of a single row along the X axis:

\[3 \times 4 = 12\]

  1. Add the X coordinate offset:

\[2\]

  1. Sum all components together:

\[16 + 12 + 2 = 30\]

The resulting gl_LocalInvocationIndex for this thread is 30, covering a valid index range from \(0\) to \(31\) (\(4 \times 4 \times 2 - 1\)).

Common Practical Applications

Computing and using gl_LocalInvocationIndex directly serves several primary purposes in compute shaders: