gl_MeshVerticesEXT Attributes in GLSL Mesh Shaders

This article provides an overview of the gl_MeshVerticesEXT output array used in GLSL mesh shaders via the GL_EXT_mesh_shader extension. It covers the specific built-in per-vertex attributes available within this structure, their data types, their roles in the graphics pipeline, and how they contrast with user-defined per-vertex attributes.

Built-in Attributes of gl_MeshVerticesEXT

In GLSL mesh shaders using the GL_EXT_mesh_shader extension, per-vertex fixed-function outputs are grouped into an unsized built-in output block array named gl_MeshVerticesEXT[]. The size of this array corresponds to the maximum vertex count defined by the shader's layout(max_vertices = N) output layout qualifier.

The underlying structure for this array is the built-in interface block gl_MeshPerVertexEXT, which contains the following standard attributes:

  • vec4 gl_Position
    The homogeneous clip-space position of the vertex. This attribute is the primary output required for rasterization, defining where the vertex resides in normalized device coordinates after the perspective divide.

  • float gl_PointSize
    Controls the size (in pixels) of rasterized point primitives. This attribute is only relevant if the mesh shader outputs points (layout(points) out;).

  • float gl_ClipDistance[]
    An array of clip distances used for user-defined clipping stages. Each element specifies the distance of the vertex to a custom half-space clipping plane. A primitive is clipped if the interpolated distance is negative.

  • float gl_CullDistance[]
    An array of cull distances used for user-defined primitive culling. Similar to clip distances, primitives are discarded prior to rasterization if all vertices have negative values for a given cull plane.

Syntax and Declaration

The internal definition provided by the compiler behaves as follows:

out gl_MeshPerVertexEXT {
    vec4  gl_Position;
    float gl_PointSize;
    float gl_ClipDistance[];
    float gl_CullDistance[];
} gl_MeshVerticesEXT[];

To write to these attributes, index the gl_MeshVerticesEXT array using the local invocation index or a target vertex index:

#version 460
#extension GL_EXT_mesh_shader : require

layout(local_size_x = 32) in;
layout(triangles, max_vertices = 64, max_primitives = 126) out;

void main() {
    uint vIndex = gl_LocalInvocationIndex;

    if (vIndex < 64) {
        gl_MeshVerticesEXT[vIndex].gl_Position = vec4(0.0, 0.0, 0.0, 1.0);
        gl_MeshVerticesEXT[vIndex].gl_PointSize = 1.0;
    }
}

Custom Per-Vertex Attributes

User-defined vertex attributes—such as normals, texture coordinates, colors, or tangent vectors—are not members of gl_MeshVerticesEXT. Instead, custom per-vertex attributes are declared as separate output arrays using the standard out keyword and an explicit output location:

layout(location = 0) out vec3 v_Normal[];
layout(location = 1) out vec2 v_TexCoord[];

void main() {
    uint vIndex = gl_LocalInvocationIndex;
    
    if (vIndex < 64) {
        v_Normal[vIndex] = vec3(0.0, 1.0, 0.0);
        v_TexCoord[vIndex] = vec2(0.5, 0.5);
    }
}

gl_MeshVerticesEXT is strictly reserved for core Vulkan/OpenGL fixed-function vertex outputs, maintaining architectural parity with gl_PerVertex from traditional vertex and geometry shading stages.