I've mentioned this a while back, but the way to implement hierarchical culling is to fully exploit spatial coherence.  Make the function return inside/outside/overlap (`Ceisum.Intersect`).  If it returns outside, stop traversing.  It it returns inside, gather all children without visibility checks.  If it returns overlap, continue traversing with visibility checks.