How gl_RayTminEXT Sets the Near Clipping Boundary
In hardware-accelerated GLSL ray tracing, the
gl_RayTminEXT built-in variable defines the minimum
parametric distance along a ray where valid intersections can occur.
This article explains how gl_RayTminEXT establishes the
near clipping boundary during traversal, its relationship with the
traceRayEXT invocation, its role in eliminating
self-intersection artifacts, and how the ray tracing pipeline consumes
this value across shader stages.
Parametric Ray Formulation and Boundary Enforcement
Ray tracing models a ray as a parametric function:
\[\mathbf{P}(t) = \mathbf{O} + t \cdot \mathbf{D}\]
where \(\mathbf{O}\) represents the ray origin, \(\mathbf{D}\) is the normalized ray direction, and \(t\) represents the distance scalar along the ray.
The ray tracing hardware traversal engine evaluates geometry hits
only within a bounded interval defined as \([t_{\min}, t_{\max}]\). The
gl_RayTminEXT variable represents this lower bound (\(t_{\min}\)). Any geometric intersection
discovered at a distance \(t\) where
\(t < \text{gl\_RayTminEXT}\) is
automatically discarded by the traversal unit before invoking
intersection or hit shaders.
Initialization via
traceRayEXT
The value of gl_RayTminEXT originates in the ray
generation shader, callable shader, or closest-hit shader when
initiating ray traversal using the built-in traceRayEXT()
function:
void traceRayEXT(
accelerationStructureEXT topLevel,
uint rayFlags,
uint cullMask,
uint sbtRecordOffset,
uint sbtRecordStride,
uint missIndex,
vec3 origin,
float tMin,
vec3 direction,
float tMax,
int payload
);The float passed into the tMin argument is forwarded
directly to the hardware traversal pipeline. Once traversal begins, this
value is exposed as a read-only variable gl_RayTminEXT in
subsequent pipeline stages, including:
- Intersection Shaders: Used to validate custom primitive intersections.
- Any-Hit Shaders: Confirms that candidate hits fall within the valid range before executing opacity or filtering logic.
- Closest-Hit Shaders: Available for informational purposes or computing secondary rays.
Preventing Self-Intersection (Ray Acne)
The primary practical function of gl_RayTminEXT is
mitigating numerical floating-point inaccuracies when casting secondary
rays, such as shadow, reflection, or ambient occlusion rays.
When a secondary ray originates from a hit surface, floating-point
rounding errors often place the ray origin slightly beneath or directly
on the surface geometry. If tMin were set to zero, the
traversal engine would register an immediate intersection with the
starting polygon, resulting in visual artifacts known as ray acne.
By setting a small positive epsilon for tMin in
traceRayEXT(), the near clipping boundary shifts slightly
forward along the ray direction vector:
float tMin = 0.001; // Epsilon threshold to ignore immediate source surface
traceRayEXT(topLevelAS, gl_RayFlagsOpaqueEXT, 0xFF, 0, 0, 0, hitPoint, tMin, lightDir, maxDistance, 0);Because traversal explicitly ignores all hits occurring between \(t = 0\) and \(t = \text{gl\_RayTminEXT}\), the originating geometry cannot self-intersect.
Custom
Intersections and reportIntersectionEXT
In custom intersection shaders, gl_RayTminEXT acts as an
active execution guardrail. When calculating analytical intersections
against procedural primitives (such as spheres or bounding volumes),
developers compare candidate \(t\)
roots against gl_RayTminEXT and
gl_RayTmaxEXT:
if (tHit >= gl_RayTminEXT && tHit <= gl_RayTmaxEXT) {
reportIntersectionEXT(tHit, hitKind);
}If reportIntersectionEXT is called with a \(t\) value smaller than
gl_RayTminEXT, the traversal runtime rejects the
intersection report, preserving the near clipping boundary across
procedural primitives.