Search code examples
c++bounding-boxfrustum

Problems with Bounding Box Frustum Culling


I am having trouble getting correct frustum culling to work. I got a great suggestion from someone about AABB point testing and it works great but I have gotten to the point where a max and a min point testing do not always work because often they won't be in the frustum but a plane from one of the sides will be. So I need to move onto full bounding box detection. I already have the code which checks the bounding box against the planes of the frustum, just need to set up the bounding box.

Does anyone have a code example or an idea about how to do this. My two points I have with which to create my bounding box are a minimum x y and z and a maximum x y and z.

Thank you! :)


Solution

  • You need to have the planes of the frustrum looking inside (their normals must point to the center). Then the rendering discard can be done by checking if the object is completelly outside of one of any of the six planes of the frustrum. You can do that with a sphere or with a AABB, or any other container where you can calculate the distance (and the side) to the plane.

    From my own plane code (so if any plane return -1 discard the rendering), I added some comments so it is easier to understand:

        int Side(const Sphere &e) const {
            float d=Distance(e.center);
            if(d-e.radius>Epsilon) return 1; // inside
            if(d+e.radius<-Epsilon) return -1; // outside
            return 0; // crossing the plane
        }
    
        int Side(const Vector3f &v) const { 
            float d=Distance(v);
            if(d>Epsilon) return 1;
            if(d<-Epsilon) return -1;
            return 0;
        }
    
    
        int Side(const Box3f &c) const {
            Vector3f a,b;
            if(Normal.x>=0.0)  { a.x=c.min.x; b.x=c.max.x; }
                else { b.x=c.min.x; a.x=c.max.x; }
            if(Normal.y>=0.0)  { a.y=c.min.y; b.y=c.max.y; }
                else { b.y=c.min.y; a.y=c.max.y; }
            if(Normal.z>=0.0)  { a.z=c.min.z; b.z=c.max.z; }
                else { b.z=c.min.z; a.z=c.max.z; }
    
            int l1 = Side(a), l2= Side(b);
    
            if(l1==l2) return l1; // both in the same side
            return 0; // we have the object crossing the plane
        }