Understanding gl_WorldToObjectEXT in GLSL
In GLSL ray tracing pipelines using the
GL_EXT_ray_tracing extension,
gl_WorldToObjectEXT is a built-in matrix uniform that
transforms spatial data from world coordinate space into the local
object coordinate space of the current geometry instance. This article
breaks down the mathematical definition of this 4x3 matrix, its role in
intersection and hit shaders, and how to use it to transform ray
origins, directions, and arbitrary points for geometric
calculations.
Definition and Structure
The variable gl_WorldToObjectEXT is defined as a
mat4x3 in GLSL. In standard mathematical notation, it
represents an affine transformation matrix consisting of 3 rows and 4
columns, which drops the conventional fourth row
[0, 0, 0, 1]. In GLSL column-major notation, a
mat4x3 consists of four column vectors of three components
each.
This matrix is the exact inverse of the current instance's
transformation matrix (gl_ObjectToWorldEXT). When instances
are placed into a Top-Level Acceleration Structure (TLAS) referencing a
Bottom-Level Acceleration Structure (BLAS), each instance is assigned a
4x3 affine transformation. During traversal, the ray tracing hardware or
driver inverts this instance transform to yield
gl_WorldToObjectEXT.
Function in Intersection Shaders
Ray generation and scene-level traversal occur in world space. Consequently, rays entering an intersection shader are defined by world-space origins and directions:
gl_WorldRayOriginEXT: The ray origin in world coordinates.gl_WorldRayDirectionEXT: The ray direction vector in world coordinates.
Intersection shaders are responsible for determining whether a ray intersects custom procedural geometry (such as an analytical sphere, capsule, or bounding volume). Evaluating intersections in world space requires deforming the geometric formulas according to instance rotation, scaling, and translation.
Instead of complicating the intersection logic, the standard practice is to transform the incoming world-space ray into the object's local coordinate space, where the geometry is defined in its canonical, undeformed form.
Applying the Matrix
Because gl_WorldToObjectEXT is a 4x3 affine transform,
it applies both linear operations (rotation and scale) and
translations.
To transform a world-space point or ray origin:
vec3 objectRayOrigin = gl_WorldToObjectEXT * vec4(gl_WorldRayOriginEXT, 1.0);Using 1.0 as the \(w\)-component enables the translation
component of the matrix.
To transform a direction vector (such as the ray direction):
vec3 objectRayDirection = gl_WorldToObjectEXT * vec4(gl_WorldRayDirectionEXT, 0.0);Using 0.0 as the \(w\)-component ignores the translation
component, preserving only rotation and scaling. Note that non-uniform
scaling will alter the length of the transformed direction vector,
meaning objectRayDirection may need to be normalized if
your intersection test assumes a unit-length ray direction.
Alternatively, the GLSL ray tracing extension provides
gl_ObjectRayOriginEXT and
gl_ObjectRayDirectionEXT, which are precomputed values
derived directly from multiplying the world-space ray parameters by
gl_WorldToObjectEXT.
Transforming Surface Normals
gl_WorldToObjectEXT is also useful outside intersection
shaders, such as in closest-hit shaders, when mapping vectors in
reverse. Because the transpose of the inverse matrix transforms normal
vectors across affine spaces, the transpose of
gl_WorldToObjectEXT acts directly as the forward
transformation matrix for converting object-space normal vectors into
world-space normal vectors:
vec3 worldNormal = normalize(transpose(mat3(gl_WorldToObjectEXT)) * objectNormal);Using gl_WorldToObjectEXT ensures custom intersection
algorithms remain decoupled from world-space placement, maintaining
performance and numerical stability across arbitrary instance
transformations.