intersect: AABB Ray Intersection Algorithm
Slab Method for Efficient Ray-Box Testing
The AABB intersection function implements the slab method for computing ray-box intersection distances. This algorithm determines entry and exit points where a ray intersects the rectangular volume defined by the bounding box.
Given an AABB with bounds , ray origin , and ray direction , the algorithm computes:
The slab intersections are ordered and combined:
Intersection Interpretation
The returned vec2 contains representing:
- : Distance to entry point (if positive)
- : Distance to exit point
- Valid intersection: and
Applications
Ray-AABB intersection enables multiple rendering techniques:
- Ray Tracing: Primary ray-scene intersection testing
- Shadow Rays: Occlusion testing for lighting calculations
- Frustum Culling: Camera view volume intersection testing
- Spatial Traversal: Octree and grid acceleration structure navigation
Live Editor
const fragment = () => Scope(() => { const t = iTime.mul(0.4) const p = uv.mul(6).sub(3) const box = AABB({ minBounds: vec3(t.sin().mul(1.2).sub(0.5), t.mul(1.1).cos().mul(0.9).sub(0.2), -1), maxBounds: vec3(t.mul(0.8).sin().mul(1.3).add(0.4), t.mul(0.9).cos().mul(1).add(0.6), 1) }) const rayOrigin = vec3(p, -3) const rayDir = vec3(iTime.mul(0.3).sin().mul(0.1), iTime.mul(0.4).cos().mul(0.1), 1).normalize() const intersection = aabbIntersect(box, rayOrigin, rayDir) const tNear = intersection.x const tFar = intersection.y const validHit = tNear.lessThanEqual(tFar).and(tFar.greaterThan(0)) const hitPoint = rayOrigin.add(rayDir.mul(tNear.max(0))) const distToHit = length(p.sub(hitPoint.xy)) const hitGlow = float(0).select(smoothstep(0.1, 0.05, distToHit), validHit) const rayPath = dot(vec2(p.sub(rayOrigin.xy)), vec2(rayDir.xy).normalize().yx.mul(vec2(1, -1))).abs() const rayVis = rayPath.smoothstep(0.02, 0.01).mul(0.3) const boxEdge = p.x.sub(box.minBounds.x).abs() .min(p.x.sub(box.maxBounds.x).abs()) .min(p.y.sub(box.minBounds.y).abs() .min(p.y.sub(box.maxBounds.y).abs())) const wireframe = boxEdge.smoothstep(0.02, 0.04).oneMinus().mul(0.4) const color = vec3(0.1, 0.2, 0.4).add(hitGlow.mul(vec3(0.9, 0.6, 0.2))).add(rayVis).add(wireframe) return vec4(color, 1) })