Understanding gl_WorldRayOriginEXT in GLSL

This article provides a concise technical overview of the gl_WorldRayOriginEXT built-in variable in GLSL ray tracing shaders. It explores how this variable defines the starting position of a ray in world space, how it is initialized via the ray tracing pipeline, and how it differs from its object-space counterpart during intersection and hit evaluation.

Definition and Purpose

In hardware-accelerated ray tracing pipelines using the GL_EXT_ray_tracing extension, gl_WorldRayOriginEXT is a built-in input variable of type vec3. It contains the world-space coordinates from which the currently executing ray was launched.

Unlike rasterization shaders where vertex positions are transformed manually via model-view-projection matrices, ray tracing operates directly with geometric rays defined by an origin and a direction vector. gl_WorldRayOriginEXT exposes the starting point of that ray vector to downstream ray-tracing shader stages.

How It Is Specified

The value of gl_WorldRayOriginEXT is not assigned directly to the variable inside the shader where it is read. Instead, it is initialized when a ray is cast using the traceRayEXT() intrinsic function, typically called from a Ray Generation or Closest Hit shader:

traceRayEXT(
    topLevelAS,           // Acceleration structure
    rayFlags,             // Ray flags
    cullMask,             // Cull mask
    sbtRecordOffset,      // SBT offset
    sbtRecordStride,      // SBT stride
    missIndex,            // Miss index
    rayOrigin,            // World-space ray origin (vec3)
    tMin,                 // Minimum ray distance
    rayDirection,         // World-space ray direction (vec3)
    tMax,                 // Maximum ray distance
    payloadLocation       // Payload location
);

The rayOrigin parameter passed into traceRayEXT() directly defines the value that becomes accessible as gl_WorldRayOriginEXT in subsequent pipeline stages handling that ray.

Availability Across Shader Stages

gl_WorldRayOriginEXT is accessible in the following shader stages:

  • Intersection Shaders: To calculate custom primitive intersections in world coordinates.
  • Any-Hit Shaders: To evaluate surface properties or reject hits (such as alpha-tested geometry) using world-space positioning.
  • Closest-Hit Shaders: To compute lighting, reflections, or secondary rays originating from the surface intersection relative to the incoming ray.
  • Miss Shaders: To sample environment maps or skyboxes that depend on the incoming ray's trajectory and point of emission.

It is not available in the Ray Generation shader, as the origin is defined explicitly by the developer within that stage.

World Space vs. Object Space

When evaluating hits against instances within a Top-Level Acceleration Structure (TLAS), Vulkan handles instance transformations automatically:

  • gl_WorldRayOriginEXT remains invariant across different coordinate frames; it reflects the exact world-space position passed to traceRayEXT().
  • gl_ObjectRayOriginEXT contains the ray origin transformed into the local coordinate system of the current geometric instance using the inverse of the instance's transform matrix.

While gl_ObjectRayOriginEXT simplifies procedural geometry calculations within custom bounding boxes, gl_WorldRayOriginEXT is typically used for world-space lighting, computing world-space hit points via gl_WorldRayOriginEXT + gl_WorldRayDirectionEXT * gl_HitTEXT, and generating secondary bounce rays.