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):
- X-slabs: Two planes perpendicular to the X-axis
- Y-slabs: Two planes perpendicular to the Y-axis
- 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 and
Mathematically, for a ray and box bounds :
The ray intersects if and .
Applications in Raymarching
Ray-box intersection is crucial for raymarching optimization:
- Early termination: If a ray doesn't hit the scene bounds, skip raymarching entirely
- Bounding volume hierarchies: Use boxes to cull entire regions
- 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:
- Check if ray hits triangle's bounding box
- If yes, perform more expensive triangle intersection test
References
- Graphics Gems I (1990) - "An Efficient and Robust Ray-Box Intersection Algorithm"
- Ray-Box Intersection on Scratchapixel
Related Articles
- Graphics Gems GLSL - Ray-Sphere Intersection - Another fundamental intersection test
- Graphics Gems GLSL Series Index - Return to series index