How Does gl_LocalInvocationID Work in GLSL?

In GLSL compute shaders, gl_LocalInvocationID is a built-in input variable that uniquely identifies the position of an executing thread relative to its immediate local workgroup. Because compute workloads are divided hierarchically into workgroups and individual invocations, each invocation requires a distinct coordinate within its group to compute data offsets, index into shared memory, and coordinate execution with neighbor threads.

The Structure of Local Invocations

Compute shaders organize threads into three-dimensional grids called local workgroups. When writing a compute shader, the layout qualifier defines the local dimensions:

layout(local_size_x = 16, local_size_y = 16, local_size_z = 1) in;

Inside this defined grid, gl_LocalInvocationID is declared as a three-component unsigned integer vector (uvec3). Its components correspond to the spatial coordinates of the current thread:

Even if a compute shader operates on 1D or 2D data, the variable remains a uvec3, with unused dimensions defaulting to an index of 0 and a size of 1.

Local Coordinates vs. Global Indexing

Understanding how gl_LocalInvocationID locates a thread requires looking at the compute shader execution hierarchy. A dispatch call distributes work across multiple workgroups, creating three levels of identification:

The relationship between local and global positioning is calculated by the hardware using the following formula:

\[\text{gl\_GlobalInvocationID} = \text{gl\_WorkGroupID} \times \text{gl\_WorkGroupSize} + \text{gl\_LocalInvocationID}\]

While gl_GlobalInvocationID determines which absolute data element in a storage buffer or texture to process, gl_LocalInvocationID isolates actions that are scoped strictly to the local group.

1D Flattening with gl_LocalInvocationIndex

For operations requiring a flat one-dimensional array index rather than 3D coordinates—such as indexing into linear shared memory arrays—GLSL provides gl_LocalInvocationIndex. This is the flattened scalar equivalent of gl_LocalInvocationID, derived as follows:

\[\text{index} = \text{ID.z} \cdot (\text{Size.x} \cdot \text{Size.y}) + \text{ID.y} \cdot \text{Size.x} + \text{ID.x}\]

Primary Use Cases in Shader Programming

gl_LocalInvocationID is essential for tasks that involve intra-workgroup cooperation: