BVH uses aabb for a sphere in Ray Tracing: The Next Week While studying Peter Shirley's Ray Tracing:The Next Week, I came across an issue that I cannot quite figure out:
Stepping through the random_scene() case of the code, found out that once a leaf of the BVH tree is reached, the aabb of the object is checked for a hit; even when the object is a sphere.
The check for a hit against the bounding_box of a sphere (aabb) is necessary but not sufficient; there are parts of the bounding_box which is not a part of a sphere.
Shouldn't it invoke the specific hit() function of the object when the leaf is reached?
Yet the code works somehow.
It does indeed do exactly what you described. Have a close look at how the bvh is constructed, it is a passed a list of concrete shapes that implement hittable, e.g. xy_rect, sphere, etc. The base cases for the recursive bvh construction create leaf nodes that directly reference the concrete shapes that make up the scene.
bvh_node::bvh_node(
    const std::vector&lt;shared_ptr&lt;hittable&gt;&gt;&amp; src_objects,
    size_t start, size_t end, double time0, double time1
) {
    auto objects = src_objects; // Create a modifiable array of the source scene objects
    ...
    size_t object_span = end - start;

    // **create leaf nodes, concrete shapes referenced here**
    if (object_span == 1) {
        left = right = objects[start]; 
    } else if (object_span == 2) {
        if (comparator(objects[start], objects[start+1])) {
            left = objects[start];
            right = objects[start+1];
        } else {
            left = objects[start+1];
            right = objects[start];
        }
    } else {
       // create internal bvh_node
       ...
}

When bvh_node::hit is called and the ray/aabb test passes, the left and right child nodes have their hit functions called recursively. Eventually when this recursion bottoms out the concrete shapes referenced by the leaf nodes will have their hit functions called as you would expect.
bool bvh_node::hit(const ray&amp; r, double t_min, double t_max, hit_record&amp; rec) const {
    if (!box.hit(r, t_min, t_max))
        return false;

    bool hit_left = left-&gt;hit(r, t_min, t_max, rec);
    bool hit_right = right-&gt;hit(r, t_min, hit_left ? rec.t : t_max, rec);

    return hit_left || hit_right;
}