Built-in Variable (GLSL): Difference between revisions
TES inputs/outputs defined. |
geometry shader inputs/outputs |
||
Line 29: | Line 29: | ||
== Geometry shader inputs == | == Geometry shader inputs == | ||
{{snippet|:Geometry Shader/Defined Inputs}} | |||
/ | {{snippet|:Geometry Shader/Defined Inputs Layered}} | ||
} | |||
== Geometry shader outputs == | == Geometry shader outputs == | ||
{{snippet|:Geometry Shader/Defined Outputs}} | |||
/ | {{snippet|:Geometry Shader/Defined Outputs Layered}} | ||
} | |||
== Fragment shader inputs == | == Fragment shader inputs == |
Revision as of 06:32, 26 July 2013
The OpenGL Shading Language defines a number of special variables for the various shader stages. These predefined variables (or built-in variables) have special properties. They are usually for communicating with certain fixed-functionality. By convention, all predefined variables start with "gl_"; no user-defined variables may start with this.
Vertex shader inputs
Vertex Shaders have the following built-in input variables.
in int gl_VertexID;
in int gl_InstanceID;
in int gl_DrawID; // Requires GLSL 4.60 or ARB_shader_draw_parameters
in int gl_BaseVertex; // Requires GLSL 4.60 or ARB_shader_draw_parameters
in int gl_BaseInstance; // Requires GLSL 4.60 or ARB_shader_draw_parameters
- gl_VertexID
- the index of the vertex currently being processed. When using non-indexed rendering, it is the effective index of the current vertex (the number of vertices processed + the first value). For indexed rendering, it is the index used to fetch this vertex from the buffer.
- gl_InstanceID
- the index of the current instance when doing some form of instanced rendering. The instance count always starts at 0, even when using base instance calls. When not using instanced rendering, this value will be 0.
- gl_DrawID
- the index of the drawing command within multi-draw rendering commands (including indirect multi-draw commands). The first draw command has an ID of 0, increasing by one as the renderer passes through drawing commands.
- This value will always be a Dynamically Uniform Expression.
- gl_BaseVertex
- the value of the baseVertex parameter of the rendering command. If the rendering command did not include that parameter, the value of this input will be 0.
- gl_BaseInstance
- the value of the baseInstance parameter of the instanced rendering command. If the rendering command did not include this parameter, the value of this input will be 0.
Vertex shader outputs
Vertex Shaders have the following predefined outputs.
out gl_PerVertex
{
vec4 gl_Position;
float gl_PointSize;
float gl_ClipDistance[];
};
gl_PerVertex defines an interface block for outputs. The block is defined without an instance name, so that prefixing the names is not required.
These variables only take on the meanings below if this shader is the last active Vertex Processing stage, and if rasterization is still active (ie: GL_RASTERIZER_DISCARD is not enabled). The text below explains how the Vertex Post-Processing system uses the variables. These variables may not be redeclared with interpolation qualifiers.
- gl_Position
- the clip-space output position of the current vertex.
- gl_PointSize
- the pixel width/height of the point being rasterized. It only has a meaning when rendering point primitives. It will be clamped to the GL_POINT_SIZE_RANGE.
- gl_ClipDistance
- allows the shader to set the distance from the vertex to each user-defined clipping half-space. A non-negative distance means that the vertex is inside/behind the clip plane, and a negative distance means it is outside/in front of the clip plane. Each element in the array is one clip plane. In order to use this variable, the user must manually redeclare it with an explicit size. With GLSL 4.10 or ARB_separate_shader_objects, the whole gl_PerVertex block needs to be redeclared. Otherwise just the gl_ClipDistance built-in needs to be redeclared.
Tessellation control shader inputs
Tessellation Control Shaders provide the following built-in input variables:
in int gl_PatchVerticesIn;
in int gl_PrimitiveID;
in int gl_InvocationID;
- gl_PatchVerticesIn
- the number of vertices in the input patch.
- gl_PrimitiveID
- the index of the current patch within this rendering command.
- gl_InvocationID
- the index of the TCS invocation within this patch. A TCS invocation writes to per-vertex output variables by using this to index them.
The TCS also takes the built-in variables output by the vertex shader:
in gl_PerVertex
{
vec4 gl_Position;
float gl_PointSize;
float gl_ClipDistance[];
} gl_in[gl_MaxPatchVertices];
Note that just because gl_in is defined to have gl_MaxPatchVertices entries does not mean that you can access beyond gl_PatchVerticesIn and get reasonable values. These variables have only the meaning the vertex shader that passed them gave them.
Tessellation control shader outputs
Tessellation Control Shaders have the following built-in patch output variables:
patch out float gl_TessLevelOuter[4];
patch out float gl_TessLevelInner[2];
These define the outer and inner tessellation levels used by the tessellation primitive generator. They define how much tessellation to apply to the patch. Their exact meaning depends on the type of patch (and other settings) defined in the Tessellation Evaluation Shader.
As with any other patch variable, multiple TCS invocations for the same patch can write to the same tessellation level variable, so long as they are all computing and writing the exact same value.
TCS's also provide the following optional per-vertex output variables:
out gl_PerVertex
{
vec4 gl_Position;
float gl_PointSize;
float gl_ClipDistance[];
} gl_out[];
The use of any of these in a TCS is completely optional. Indeed, their semantics will generally be of no practical value to the TCS. They have the same general meaning as for vertex shaders, but since a TCS must always be followed by an evaluation shader, the TCS never has to write to any of them.
Tessellation evaluation shader inputs
Tessellation Evaluation Shaders have the following built-in inputs.
in vec3 gl_TessCoord;
in int gl_PatchVerticesIn;
in int gl_PrimitiveID;
- gl_TessCoord
- the location within the tessellated abstract patch for this particular vertex. Every input parameter other than this one will be identical for all TES invocations within a patch.
- Which components of this vec3 that have valid values depends on the abstract patch type. For isolines and quads, only the XY components have valid values. For triangles, all three components have valid values. All valid values are normalized floats (on the range [0, 1]).
- gl_PatchVerticesIn
- the vertex count for the patch being processed. This is either the output vertex count specified by the TCS, or the patch vertex size specified by glPatchParameter if no TCS is active. Attempts to index per-vertex inputs by a value greater than or equal to gl_PatchVerticesIn results in undefined behavior.
- gl_PrimitiveID
- the index of the current patch in the series of patches being processed for this draw call. Primitive restart, if used, has no effect on the primitive ID.
The TES also has access to the tessellation levels provided for the patch by the TCS or by OpenGL:
patch in float gl_TessLevelOuter[4];
patch in float gl_TessLevelInner[2];
Only the outer and inner levels actually used by the abstract patch are valid. For example, if this TES uses isolines, only gl_TessLevelOuter[0] and gl_TessLevelOuter[1] will have valid values.
The TES also takes the built-in per-vertex variables output by the TCS:
in gl_PerVertex
{
vec4 gl_Position;
float gl_PointSize;
float gl_ClipDistance[];
} gl_in[gl_MaxPatchVertices];
Note that just because gl_in is defined to have gl_MaxPatchVertices entries does not mean that you can access beyond gl_PatchVerticesIn and get reasonable values.
Tessellation evaluation shader outputs
Tessellation Evaluation Shaders have the following built-in outputs.
out gl_PerVertex {
vec4 gl_Position;
float gl_PointSize;
float gl_ClipDistance[];
};
gl_PerVertex defines an interface block for outputs. The block is defined without an instance name, so that prefixing the names is not required.
These variables only take on the meanings below if this shader is the last active Vertex Processing stage, and if rasterization is still active (ie: GL_RASTERIZER_DISCARD is not enabled). The text below explains how the Vertex Post-Processing system uses the variables. These variables may not be redeclared with interpolation qualifiers.
- gl_Position
- the clip-space output position of the current vertex.
- gl_PointSize
- the pixel width/height of the point being rasterized. It only has a meaning when rendering point primitives, which in a TES requires using the point_mode input layout qualifier.
- gl_ClipDistance
- allows the shader to set the distance from the vertex to each User-Defined Clip Plane. A positive distance means that the vertex is inside/behind the clip plane, and a negative distance means it is outside/in front of the clip plane. Each element in the array is one clip plane. In order to use this variable, the user must manually redeclare it with an explicit size.
Geometry shader inputs
Geometry Shaders provide the following built-in input variables:
in gl_PerVertex
{
vec4 gl_Position;
float gl_PointSize;
float gl_ClipDistance[];
} gl_in[];
These variables have only the meaning the prior shader stage(s) that passed them gave them.
There are some GS input values that are based on primitives, not vertices. These are not aggregated into arrays. These are:
in int gl_PrimitiveIDIn;
in int gl_InvocationID; // Requires GLSL 4.0 or ARB_gpu_shader5
- gl_PrimitiveIDIn
- the current input primitive's ID, based on the number of primitives processed by the GS since the current drawing command started.
- gl_InvocationID
- the current instance, as defined when instancing geometry shaders.
|
||||||||||||
OpenGL Rendering Pipeline
|
A Geometry Shader (GS) is a Shader program written in GLSL that governs the processing of Primitives. Geometry shaders reside between the Vertex Shaders (or the optional Tessellation stage) and the fixed-function Vertex Post-Processing stage.
A geometry shader is optional and does not have to be used.
Geometry shader invocations take a single Primitive as input and may output zero or more primitives. There are implementation-defined limits on how many primitives can be generated from a single GS invocation. GS's are written to accept a specific input primitive type and to output a specific primitive type.
While the GS can be used to amplify geometry, thus implementing a crude form of tessellation, this is generally not a good use of a GS. The main reasons to use a GS are:
- Layered rendering: taking one primitive and rendering it to multiple images without having to change bound rendertargets and so forth.
- Transform Feedback: This is often employed for doing computational tasks on the GPU (obviously pre-Compute Shader).
In OpenGL 4.0, GS's gained two new features. One was the ability to write to multiple output streams. This is used exclusively with transform feedback, such that different feedback buffer sets can get different transform feedback data.
The other feature was GS instancing, which allows multiple invocations to operate over the same input primitive. This makes layered rendering easier to implement and possibly faster performing, as each layer's primitive(s) can be computed by a separate GS instance.
Primitive in/out specification
Each geometry shader is designed to accept a specific Primitive type as input and to output a specific primitive type. The accepted input primitive type is defined in the shader:
layout(input_primitive) in;
The input_primitive type must match the primitive type for the vertex stream provided to the GS. If Tessellation is enabled, then the primitive type is specified by the Tessellation Evaluation Shader's output qualifiers. If Tessellation is not enabled, then the primitive type is provided by the drawing command that renders with this shader program. The valid values for input_primitive, along with the valid OpenGL primitive types or tessellation forms, are:
GS input | OpenGL primitives | TES parameter | vertex count |
---|---|---|---|
points | GL_POINTS | point_mode | 1 |
lines | GL_LINES, GL_LINE_STRIP, GL_LINE_LOOP | isolines | 2 |
lines_adjacency | GL_LINES_ADJACENCY, GL_LINE_STRIP_ADJACENCY | N/A | 4 |
triangles | GL_TRIANGLES, GL_TRIANGLE_STRIP, GL_TRIANGLE_FAN | triangles, quads | 3 |
triangles_adjacency | GL_TRIANGLES_ADJACENCY, GL_TRIANGLE_STRIP_ADJACENCY | N/A | 6 |
The vertex count is the number of vertices that the GS receives per-input primitive.
The output primitive type is defined as follows:
layout(output_primitive, max_vertices = vert_count) out;
The output_primitive must be one of the following:
- points
- line_strip
- triangle_strip
These work exactly the same way their counterpart OpenGL rendering modes do. To output individual triangles or lines, simply use EndPrimitive (see below) after emitting each set of 3 or 2 vertices.
There must be a max_vertices declaration for the output. The number must be a compile-time constant, and it defines the maximum number of vertices that will be written by a single invocation of the GS. It may be no larger than the implementation-defined limit of MAX_GEOMETRY_OUTPUT_VERTICES. The minimum value for this limit is 256. See the limitations below.
Instancing
Core in version | 4.6 | |
---|---|---|
Core since version | 4.0 | |
Core ARB extension | ARB_gpu_shader5 |
The GS can also be instanced (this is separate from instanced rendering, as this is localized to the GS). This causes the GS to execute multiple times for the same input primitive. Each invocation of the GS for a particular input primitive will get a different gl_InvocationID value. This is useful for layered rendering and outputs to multiple streams (see below).
To use instancing, there must be an input layout qualifier:
layout(invocations = num_instances) in;
The value of num_instances must not be larger than MAX_GEOMETRY_SHADER_INVOCATIONS (this will be at least 32). The built-in value gl_InvocationID specifies the particular instance of this shader; it will be on the half-open range [0, num_instances).
The output primitives from instances are ordered by the gl_InvocationID. So if the user renders two primitives, and has num_instances set to 3, then the GS will be effectively called in this order: (prim0, inst0), (prim0, inst1), (prim0, inst2), (prim1, inst0), ... The output primitives from the GS's will be ordered based on that input sequence. So if (prim0, inst0) outputs two triangles, they will both be rendered before rendering any triangles from (prim0, inst1).
Inputs
Geometry shaders take a primitive as input; each primitive is composed of some number of vertices, as defined by the input primitive type in the shader.
The outputs of the vertex shader (or Tessellation Stage, as appropriate) are thus fed to the GS as arrays of variables. These can be organized as individual variables or as part of an interface block. Each individual variable will be an array of the length of the primitive's vertex count; for interface blocks, the block itself will be arrayed with this length. The order of vertices in the input arrays corresponds to the order of the vertices specified by prior shader stages.
Geometry shader inputs may have interpolation qualifiers on them. If they do, then the prior stage's outputs must use the same qualifier. Template loop detected: Template:Snippet
Outputs
Geometry shaders can output as many vertices as they wish (up to the maximum specified by the max_vertices layout specification). To provide this, output values in geometry shaders are not arrays. Instead, a function-based interface is used.
GS code writes all of the output values for a vertex, then calls EmitVertex(). This tells the system to write those output values to where ever it is that output vertices get written. After calling this function, all output variables contain undefined values. So you will need to write to them all again before emitting the next vertex (if there is a next vertex).
The GS defines what kind of primitive these vertex outputs represent. The GS can also end a primitive and start a new one, by calling the EndPrimitive() function. This does not emit a vertex.
In order to write two independent triangles from a GS, you must write three separate vertices with EmitVertex() for the first three vertices, then call EndPrimitive() to end the strip and start a new one. Then you write three more vertices with EmitVertex().
Output variables are defined as normal for GLSL. They can be grouped into interface blocks or be single values, as appropriate. Output variables can be defined with interpolation qualifiers. The Fragment Shader equivalent interface variables should define the same variables with the same qualifiers. Template loop detected: Template:Snippet
Layered rendering
Layered rendering is the process of having the GS send specific primitives to different layers of a layered framebuffer. This can be useful for doing cube-based shadow mapping, or even for rendering cube environment maps without having to render the entire scene multiple times. Template loop detected: Template:Snippet
Layered rendering can be more efficient with GS instancing, as different GS invocations can process instances in parallel. However, while ARB_viewport_array is often implemented in 3.3 hardware, no 3.3 hardware provides ARB_gpu_shader5 support.
If the geometry shader never writes to gl_ViewportIndex, then everything will behave as if 0 were written to it.
Which vertex
gl_Layer and gl_ViewportIndex are per-vertex parameters, but they specify a property that applies to the entire primitive. Therefore, a question arises: which vertex in a particular primitive defines that primitive's layer and viewport index?
The answer is that it is implementation-dependent. However, OpenGL does have two queries to determine which one the current implementation uses: GL_LAYER_PROVOKING_VERTEX and GL_VIEWPORT_INDEX_PROVOKING_VERTEX.
The value returned from glGetIntegerv will be one of the following enumerators:
- GL_PROVOKING_VERTEX: The vertex used will track the current provoking vertex convention.
- GL_LAST_VERTEX_CONVENTION: The vertex used will be the one defined by the last-vertex provoking vertex convention.
- GL_FIRST_VERTEX_CONVENTION: The vertex used will be the one defined by the first-vertex provoking vertex convention.
- GL_UNDEFINED_VERTEX: The implementation isn't saying.
For maximum portability, you will have to provide the same layer and viewport index to each primitive. So if you wanted to output a triangle strip, where different triangles had different indices, too bad. You have to split it into different primitives.
Output streams
Core in version | 4.6 | |
---|---|---|
Core since version | 4.0 | |
Core ARB extension | ARB_transform_feedback3 |
When using Transform Feedback to compute values, it is often useful to be able to send different sets of vertices to different buffers at different rates. For example, GS's can send vertex data to one stream, while building per-instance data in another stream. The vertex data and per-instance data will be of different lengths, written at different speeds.
Multiple stream output requires that the output primitive type be points. You can still take whatever input you prefer.
To provide this, output variables can be given a stream index with a layout qualifier:
layout(stream = stream_index) out vec4 some_output;
The stream_index ranges from 0 to GL_MAX_VERTEX_STREAMS - 1.
A default value for the stream can be set with:
layout(stream = 2) out;
All following out variables will use stream 2 unless they specify a stream. The default can be changed later. The initial default is 0.
To write a vertex to a particular stream, the function EmitStreamVertex is used. This function takes a stream index; only those output variables are written. Similarly, EndStreamPrimitive ends a particular stream's primitive. However, since multiple stream output requires using points primitives, the latter function is not very useful.
Only primitives emitted to stream 0 will actually be pass along to Vertex Post-Processing and rendered; the rest of the streams will only matter if transform feedback is being used. Calling EmitVertex or EndPrimitive is equivalent to calling their stream counterparts with stream 0.
Output limitations
There are two competing limitations on the output of a geometry shader:
- The maximum number of vertices that a single invocation of a GS can output.
- The total maximum number of output components that a single invocation of a GS can output.
The first limit, defined by GL_MAX_GEOMETRY_OUTPUT_VERTICES, is the maximum number that can be provided to the max_vertices output layout qualifier. No single geometry shader invocation can exceed this number.
The other limit, defined by GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS is, in layman's terms, the total amount of stuff that a single GS invocation can write. It is the total number of output values (a component, in GLSL terms, is a component of a vector. So a float is one component; a vec3 is 3 components) that a single GS invocation can write to. This is different from GL_MAX_GEOMETRY_OUTPUT_COMPONENTS (the maximum allowed number of components in out variables). The total output component is the total number of components + vertices that can be written.
For example, if the total output component count is 1024 (the smallest maximum value from GL 4.3), and the output stream writes to 12 components, the total number of vertices that can be written is $ floor({\tfrac {1024}{12}})=85 $. This is the absolute hard limit to the number of vertices that can be written. Even if GL_MAX_GEOMETRY_OUTPUT_VERTICES is larger than 85, because this vertex shader writes 12 components per vertex, the true maximum that this geometry shader can write is 85 vertices. If the geometry shader instead wrote only 8 components per vertex, then it could write 128 (subject to the output vertices limit, of course).
Note that even built-in outputs like gl_Layer count towards GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS. For example, a geometry shader with a total output component count of 1024 which outputs vec4 gl_Position and int gl_Layer supports a maximum of $ floor({\tfrac {1024}{4+1}})=204 $ vertices.
See also
Geometry shader outputs
Geometry Shaders have the following built-in outputs.
out gl_PerVertex
{
vec4 gl_Position;
float gl_PointSize;
float gl_ClipDistance[];
};
gl_PerVertex defines an interface block for outputs. The block is defined without an instance name, so that prefixing the names is not required.
The GS is the final Vertex Processing stage. Therefore, unless rasterization is being turned off, you must write to some of these values. These outputs are always associated with stream 0. So if you're emitting vertices to a different stream, you don't have to write to them.
- gl_Position
- the clip-space output position of the current vertex. This value must be written if you are emitting a vertex to stream 0, unless rasterization is off.
- gl_PointSize
- the pixel width/height of the point being rasterized. It is only necessary to write to this when outputting point primitives.
- gl_ClipDistance
- allows the shader to set the distance from the vertex to each User-Defined Clip Plane. A positive distance means that the vertex is inside/behind the clip plane, and a negative distance means it is outside/in front of the clip plane. In order to use this variable, the user must manually redeclare it (and therefore the interface block) with an explicit size.
Certain predefined outputs have special meaning and semantics.
out int gl_PrimitiveID;
The primitive ID will be passed to the fragment shader. The primitive ID for a particular line/triangle will be taken from the provoking vertex of that line/triangle, so make sure that you are writing the correct value for the right provoking vertex.
The meaning for this value is whatever you want it to be. However, if you want to match the standard OpenGL meaning (ie: what the Fragment Shader would get if no GS were used), you must do this for each vertex before emitting it:
gl_PrimitiveID = gl_PrimitiveIDIn;
This naturally assumes that the number of primitives output by the GS equals the number of primitives received by the GS.
Layered rendering in the GS works via two special output variables:
out int gl_Layer;
out int gl_ViewportIndex; // Requires GL 4.1 or ARB_viewport_array.
The gl_Layer output defines which layer in the layered image the primitive goes to. Each vertex in the primitive must get the same layer index. Note that when rendering to cubemap arrays, the gl_Layer value represents layer-faces (the faces within a layer), not the layers of cubemaps.
gl_ViewportIndex, which requires GL 4.1 or ARB_viewport_array, specifies which viewport index to use with this primitive.
Fragment shader inputs
in vec4 gl_FragCoord;
in bool gl_FrontFacing;
in float gl_ClipDistance[];
in vec2 gl_PointCoord;
in int gl_PrimitiveID;
gl_FragCoord contains the window-space position of the current sample that this fragment represents. The Z component is the value that will be written to the depth buffer if the user does not override this (see below). The W component is special; it is 1/Wclip. That is, it is 1 divided by the W component of gl_Position output from the vertex or geometry shader.
gl_FrontFacing is true if the primitive is seen from the front, and false if it is the back.
gl_ClipDistance contains the values output from the vertex shader, linearly interpolated across the primitive. As before, it must be sized explicitly.
gl_PointCoord is the location within the area of a point that specifies this fragment's location. This is a normalized value, on the range [0, 1]. The (0,0) origin depends on the point coordinate origin set by OpenGL; the default is the lower-left corner.
gl_PrimitiveID is the value output by the geometry shader, or by OpenGL if no geometry shader was used. It represents the index of the primitive that is being rasterized.
GLSL 4.00 adds the following inputs:
in int gl_SampleID;
in vec2 gl_SamplePosition;
in int gl_SampleMaskIn[];
gl_SampleID is the ID for the current sample being rasterized within the area of the pixel.
gl_SamplePosition is the location of the current sample within the pixel area being rendered. These values are on the range [0, 1].
gl_SampleMaskIn represents the sample coverage mask for the currently rasterized fragment. The user must redeclare the size of the sample mask to the implementation-dependent maximum number of samples, divided by 32, rounded up (to get the number of 32-bit integers).
GLSL 4.30 adds the following inputs:
in int gl_Layer;
in int gl_ViewportIndex;
gl_Layer and gl_ViewportIndex both have the values passed from the geometry shader. If no geometry shader is used, they both have the value 0.
Fragment shader uniforms
The fragment shader defines some uniform built-in values for the sake of convenience:
struct gl_DepthRangeParameters
{
float near;
float far;
float diff;
};
uniform gl_DepthRangeParameters gl_DepthRange;
This struct provides access to the glDepthRange near and far values. The diff value is the far value minus the near value.
Fragment shader outputs
out float gl_FragDepth;
The gl_FragDepth value is the value that will be written to the depth buffer. It will also be used for the depth test. The fragment shader does not have to write to this variable; it will automatically be filled with with gl_FragCoord.z. However, if the fragment shader writes to this variable anywhere, then it must ensure that the value is always written to, no matter what path is taken through the shader (unless discard is used in the other paths).
GLSL 4.00 adds the following output:
out int gl_SampleMask[];
gl_SampleMask is a bitmask that represents the samples, when using multisample rendering, that will be written to. The user must redeclare the size of the sample mask to the implementation-dependent maximum number of samples, divided by 32, rounded up (to get the number of 32-bit integers).
The mask bits will be logically AND'd with the coverage mask computed normally.
Compute shader inputs
// Compute shaders require GL 4.3 or ARB_compute_shader
in uvec3 gl_NumWorkGroups;
in uvec3 gl_WorkGroupID;
in uvec3 gl_LocalInvocationID;
in uvec3 gl_GlobalInvocationID;
in uint gl_LocalInvocationIndex;
The gl_NumWorkGroups variable contains the number of workgroups in each dimension passed to glDispatchCompute or glDispatchComputeIndirect.
The gl_WorkGroupID is the work group that the current invocation is executing in. The values are between 0 and gl_NumWorkGroups - 1, for each of the three axes.
The gl_LocalInvocationID contains the invocation within a work group that is being executed. It is between 0 and gl_WorkGroupSize - 1 (see below), for each of the three axes.
The gl_GlobalInvocationID variable uniquely identifies this invocation across all other local and global work groups dispatched by the compute dispatch call. It is defined as:
gl_GlobalInvocationID = gl_WorkGroupID * gl_WorkGroupSize + gl_LocalInvocationID;
The gl_LocalInvocationIndex contains a 1-dimensional representation of gl_LocalInvocationID. It is defined as:
gl_LocalInvocationIndex =
gl_LocalInvocationID.z * gl_WorkGroupSize.x * gl_WorkGroupSize.y +
gl_LocalInvocationID.y * gl_WorkGroupSize.x +
gl_LocalInvocationID.x;
Compute shader other variables
const uvec3 gl_WorkGroupSize; // GLSL ≥ 4.30
The gl_WorkGroupSize variable is a constant that contains the local work-group size of the shader, in 3 dimensions. It is defined by the layout qualifiers local_size_x/y/z. This is a compile-time constant.