How gl_GeometryIndexEXT Distinguishes BLAS Geometries

In Vulkan ray tracing using GLSL, gl_GeometryIndexEXT is a built-in input variable that uniquely identifies distinct geometric subsets combined within a single Bottom-Level Acceleration Structure (BLAS). This article explains how the index is assigned during acceleration structure creation, which shader stages can access it, and how developers utilize it to look up geometry-specific material and vertex data efficiently without creating separate acceleration structures.

The Role of Multiple Geometries in a BLAS

When setting up ray tracing through the VK_KHR_ray_tracing_pipeline extension, a BLAS is built from an array of geometry descriptions (VkAccelerationStructureGeometryKHR). Rather than creating a separate BLAS for every mesh, developers often pack multiple geometries—such as different parts of a complex object or distinct meshes that share the same transform—into a single BLAS.

Inside the shader pipeline, gl_GeometryIndexEXT serves as the zero-based index representing the specific geometry description that an active ray has intersected.

How Indexing Works

The value of gl_GeometryIndexEXT corresponds directly to the order of the geometries submitted to the acceleration structure build command:

  1. Array Submission Order: During the BLAS build, geometries are provided via the pGeometries or ppGeometries array in VkAccelerationStructureBuildGeometryInfoKHR.
  2. Implicit Index Assignment: The driver assigns a sequential, zero-based integer to each entry. The geometry defined at array element 0 receives an index of 0, array element 1 receives 1, and so on up to \(N-1\) geometries.
  3. Hardware Traversal Tracking: When a ray traverses the acceleration structure and tests primitives, the intersection hardware tracks both the primitive index within the geometry and the index of the geometry itself. Upon hitting a primitive, that geometry's array index is passed to the execution environment as gl_GeometryIndexEXT.

Shader Availability

To use gl_GeometryIndexEXT, the shader must enable the ray tracing extension:

#extension GL_EXT_ray_tracing : require

The variable is available as a read-only int in the following ray tracing stages:

  • Any-Hit Shader (.rahit): Evaluates intersections, often used for alpha-testing transparency.
  • Closest-Hit Shader (.rchit): Executes after the closest intersection is determined to calculate surface shading.
  • Intersection Shader (.rint): Executes during procedural geometry testing.

Structural Distinction in the Hierarchy

To uniquely locate any primitive in a scene, the ray tracing pipeline provides three hierarchical levels of identifiers:

  • gl_InstanceCustomIndexEXT (or gl_InstanceID): Identifies the instance within the Top-Level Acceleration Structure (TLAS).
  • gl_GeometryIndexEXT: Identifies the specific mesh or geometry description within the referenced BLAS.
  • gl_PrimitiveID: Identifies the specific triangle or procedural primitive within that geometry.

Practical Application: Material and Buffer Fetching

The primary use case for gl_GeometryIndexEXT is fetching per-geometry resources, such as distinct materials, textures, or vertex/index buffer addresses.

Instead of routing every geometry through separate shader binding table (SBT) hit groups, developers typically use a single hit group per material domain and index into descriptor arrays dynamically:

struct GeometryData {
    uint64_t vertexBufferAddress;
    uint64_t indexBufferAddress;
    int materialIndex;
};

layout(binding = 0, set = 0) readonly buffer GeometryBuffer {
    GeometryData geometries[];
} sceneGeometries;

void main() {
    // Retrieve metadata for the specific geometry hit
    GeometryData currentGeo = sceneGeometries.geometries[gl_GeometryIndexEXT];

    // Access the geometry-specific material
    int matID = currentGeo.materialIndex;
    
    // Process lighting and shading...
}

By leveraging gl_GeometryIndexEXT, rendering engines can merge multiple static meshes into unified BLAS instances, minimizing driver overhead and significantly reducing total acceleration structure memory consumption.