Daniel Gray

Thoughts, Notes, Ideas, Projects

Contact

Graphics Gems GLSL - Ray-Box Intersection

The Ray-Box Intersection algorithm from Graphics Gems I provides an efficient method for determining if and where a ray intersects an Axis-Aligned Bounding Box (AABB). This "slab method" is fundamental to ray tracing, raymarching, and spatial acceleration structures.

Interactive Demo

Move your mouse to rotate the camera and explore the 3D raymarched scene. The scene uses ray-box intersection to efficiently cull rays that don't hit the scene bounds:

The Slab Method

The slab method works by treating the box as three pairs of parallel planes (slabs):

  1. X-slabs: Two planes perpendicular to the X-axis
  2. Y-slabs: Two planes perpendicular to the Y-axis
  3. Z-slabs: Two planes perpendicular to the Z-axis

For each slab, we compute where the ray enters and exits. The ray intersects the box if and only if:

  • The maximum entry time is less than the minimum exit time
  • The exit time is positive (ray is in front of the box)

The Algorithm

float rayBoxIntersect(vec3 ro, vec3 rd, vec3 boxMin, vec3 boxMax) {
    // Compute intersection with each pair of parallel planes
    vec3 invD = 1.0 / rd;
    vec3 t0 = (boxMin - ro) * invD;
    vec3 t1 = (boxMax - ro) * invD;
    
    // Find near and far intersection points
    vec3 tNear = min(t0, t1);
    vec3 tFar = max(t0, t1);
    
    // Find the farthest near point and nearest far point
    float near = max(max(tNear.x, tNear.y), tNear.z);
    float far = min(min(tFar.x, tFar.y), tFar.z);
    
    // Check if intersection is valid
    if (near > far || far < 0.0) {
        return -1.0; // No intersection
    }
    
    return near > 0.0 ? near : far;
}

Why It Works

  • tNear: The farthest point where the ray enters all three slabs (must enter all to enter box)
  • tFar: The nearest point where the ray exits any slab (exits box when leaving any slab)
  • Intersection exists if near<far\text{near} < \text{far} and far>0\text{far} > 0

Mathematically, for a ray r(t)=ro+trd\mathbf{r}(t) = \mathbf{r}_o + t \cdot \mathbf{r}_d and box bounds [bmin,bmax][b_{\min}, b_{\max}]:

tnear=max(bminrord),tfar=min(bmaxrord)t_{\text{near}} = \max\left(\frac{b_{\min} - \mathbf{r}_o}{\mathbf{r}_d}\right), \quad t_{\text{far}} = \min\left(\frac{b_{\max} - \mathbf{r}_o}{\mathbf{r}_d}\right)

The ray intersects if tnear<tfart_{\text{near}} < t_{\text{far}} and tfar>0t_{\text{far}} > 0.

Applications in Raymarching

Ray-box intersection is crucial for raymarching optimization:

  1. Early termination: If a ray doesn't hit the scene bounds, skip raymarching entirely
  2. Bounding volume hierarchies: Use boxes to cull entire regions
  3. Spatial acceleration: Quickly determine which objects a ray might hit

Example Usage

// Check if ray hits scene bounds before raymarching
float boxT = rayBoxIntersect(ro, rd, sceneMin, sceneMax);
if (boxT < 0.0) {
    return background; // Ray misses scene
}

// Start raymarching from box intersection
float t = max(0.0, boxT - 0.1);
// ... continue with raymarching

Performance Benefits

  • O(1) complexity: Constant time regardless of scene complexity
  • Early culling: Rejects rays that miss the scene immediately
  • GPU-friendly: Branch-friendly code that runs efficiently on parallel hardware

Extensions

Oriented Bounding Boxes (OBB)

Transform the ray into the OBB's local space, then use the AABB algorithm:

// Transform ray to OBB space
vec3 localRo = (ro - obbCenter) * obbRotation;
vec3 localRd = rd * obbRotation;
// Use AABB intersection in local space

Ray-Triangle Intersection

Ray-box intersection is often the first step in ray-triangle tests:

  1. Check if ray hits triangle's bounding box
  2. If yes, perform more expensive triangle intersection test

References

Related Articles

Related Content

Graphics Gems GLSL Series

Graphics Gems GLSL Series The Graphics Gems series (1990-1995) contains timeless algorithms and techniques that remain fundamental to computer graphics today. This series adapts these classic algorith...