BVH

/ˌbiː viː ˈeɪtʃ/

n. "Tree-structured spatial index organizing primitives within nested bounding volumes accelerating ray-primitive intersection unlike flat triangle lists."

BVH, short for Bounding Volume Hierarchy, recursively partitions scene geometry into tight-fitting AABB containers—RTX GPUs traverse top-down skipping entire subtrees when ray misses parent bounds, reducing 10M-triangle scenes to <100 ray-triangle tests per pixel. SAH cost function optimizes splits minimizing expected traversal cost C=Ci+Ca*(1-p)+Cb*p where p measures primitive probability; contrasts k-d trees by object-centered partitioning immune to empty-space waste.

Key characteristics of BVH include: AABB/OBB Containers axis-aligned or oriented boxes per node; SAH Optimization Surface Area Heuristic guides median/split selection; Top-Down Traversal ray skips non-intersecting subtrees; Refit Updates dynamic scenes rebuild leaf bounds only; LBVH Linear construction via Morton codes for GPU parallelism.

Conceptual example of BVH usage:

// BVH node structure for ray tracer
struct BVHNode {
    AABB bounds;              // Node bounding volume
    int left, right;          // Child indices (-1=leaf)
    int prim_start, prim_count; // Leaf primitive range
    float sah_cost;           // Cached SAH metric
};

void build_bvh(std::vector<Triangle>& tris, BVHNode* nodes, int node_idx) {
    BVHNode& node = nodes[node_idx];
    
    if (tris.size() <= 4) {  // Leaf threshold
        node.prim_start = prim_offset;
        node.prim_count = tris.size();
        node.bounds = compute_leaf_bounds(tris);
        return;
    }
    
    // SAH split: try median along longest axis
    int split = sah_partition(tris, node.bounds);
    
    std::vector<Triangle> left_tris(tris.begin(), tris.begin()+split);
    std::vector<Triangle> right_tris(tris.begin()+split, tris.end());
    
    node.left = ++node_counter;
    node.right = ++node_counter;
    
    build_bvh(left_tris, nodes, node.left);
    build_bvh(right_tris, nodes, node.right);
    
    // Union bounds
    node.bounds = union_aabb(nodes[node.left].bounds, nodes[node.right].bounds);
}

bool ray_intersect(const Ray& ray, const BVHNode* nodes, Hit& hit) {
    Stack<int> stack;
    stack.push(0);  // Root
    
    while (!stack.empty()) {
        int idx = stack.pop();
        const BVHNode& node = nodes[idx];
        
        if (!ray.intersects_aabb(node.bounds)) continue;
        
        if (node.prim_count) {
            // Test leaf primitives
            test_triangles(ray, tris.data() + node.prim_start, hit);
        } else {
            stack.push(node.right);
            stack.push(node.left);
        }
    }
}

Conceptually, BVH transforms O(n²) brute-force intersection into O(log n) via spatial exclusion—RTX cores fetch 16-wide nodes testing ray-AABB before triangle SIMD while refit handles skinned meshes swapping vertex buffers without full rebuilds. Top-level acceleration structures TLAS reference BLAS per object enabling instancing; contrasts VHDL streaming operators by preprocessing geometry for cache-coherent ray traversal in Bluetooth AR glasses rendering FHSS-tracked beacons amid dynamic occlusion.