Fastest Box View Frustum Culling

Discuss about anything related to the Irrlicht Engine, or read announcements about any significant features or usage changes.
Post Reply
devsh
Competition winner
Posts: 2057
Joined: Tue Dec 09, 2008 6:00 pm
Location: UK
Contact:

Fastest Box View Frustum Culling

Post by devsh »

Doesn't care about the matrices, can be used for culling for shadowpass drawing and any weird projection matrix that would usually gently caress up a frustum

Code: Select all

 
        core::aabbox3d<f32> tbox = node->getBoundingBox();
        if (tbox.MinEdge==tbox.MaxEdge)
            return true;
 
        //transform the frustum to the node's current absolute transformation
        core::matrix4 worldviewproj = cam->getProjectionMatrix()*(cam->getViewMatrix()*node->getAbsoluteTransformation());
 
        core::vector3df column0_Min = reinterpret_cast<core::vector3df*>(worldviewproj.pointer())[0];
        core::vector3df column1_Min = reinterpret_cast<core::vector3df*>(worldviewproj.pointer()+4)[0];
        core::vector3df column2_Min = reinterpret_cast<core::vector3df*>(worldviewproj.pointer()+8)[0];
        core::vector3df column3_Min = reinterpret_cast<core::vector3df*>(worldviewproj.pointer()+12)[0];
        core::vector3df column0_Max = column0_Min;
        core::vector3df column1_Max = column1_Min;
        core::vector3df column2_Max = column2_Min;
        core::vector3df column3_Max = column3_Min;
 
        column0_Min += worldviewproj.pointer()[3];
        column1_Min += worldviewproj.pointer()[7];
        column2_Min += worldviewproj.pointer()[11];
        column3_Min += worldviewproj.pointer()[15];
 
        float tmp = column0_Min.X*(column0_Min.X<0.f ? tbox.MinEdge.X:tbox.MaxEdge.X)+column1_Min.X*(column1_Min.X<0.f ? tbox.MinEdge.Y:tbox.MaxEdge.Y)+column2_Min.X*(column2_Min.X<0.f ? tbox.MinEdge.Z:tbox.MaxEdge.Z);
        if (tmp<=-column3_Min.X)
            return true;
        tmp = column0_Min.Y*(column0_Min.Y<0.f ? tbox.MinEdge.X:tbox.MaxEdge.X)+column1_Min.Y*(column1_Min.Y<0.f ? tbox.MinEdge.Y:tbox.MaxEdge.Y)+column2_Min.Y*(column2_Min.Y<0.f ? tbox.MinEdge.Z:tbox.MaxEdge.Z);
        if (tmp<=-column3_Min.Y)
            return true;
        tmp = worldviewproj.pointer()[3]*(worldviewproj.pointer()[3]<0.f ? tbox.MinEdge.X:tbox.MaxEdge.X)+worldviewproj.pointer()[7]*(worldviewproj.pointer()[7]<0.f ? tbox.MinEdge.Y:tbox.MaxEdge.Y)+worldviewproj.pointer()[11]*(worldviewproj.pointer()[11]<0.f ? tbox.MinEdge.Z:tbox.MaxEdge.Z);
        if (tmp<=-worldviewproj.pointer()[15])
            return true;
 
        column0_Max -= worldviewproj.pointer()[3];
        column1_Max -= worldviewproj.pointer()[7];
        column2_Max -= worldviewproj.pointer()[11];
        column3_Max = core::vector3df(worldviewproj.pointer()[15])-column3_Max;
        tmp = column0_Max.X*(column0_Max.X>=0.f ? tbox.MinEdge.X:tbox.MaxEdge.X)+column1_Max.X*(column1_Max.X>=0.f ? tbox.MinEdge.Y:tbox.MaxEdge.Y)+column2_Max.X*(column2_Max.X>=0.f ? tbox.MinEdge.Z:tbox.MaxEdge.Z);
        if (tmp>=column3_Max.X)
            return true;
        tmp = column0_Max.Y*(column0_Max.Y>=0.f ? tbox.MinEdge.X:tbox.MaxEdge.X)+column1_Max.Y*(column1_Max.Y>=0.f ? tbox.MinEdge.Y:tbox.MaxEdge.Y)+column2_Max.Y*(column2_Max.Y>=0.f ? tbox.MinEdge.Z:tbox.MaxEdge.Z);
        if (tmp>=column3_Max.Y)
            return true;
 
        tmp = column0_Max.Z*(column0_Max.Z>=0.f ? tbox.MinEdge.X:tbox.MaxEdge.X)+column1_Max.Z*(column1_Max.Z>=0.f ? tbox.MinEdge.Y:tbox.MaxEdge.Y)+column2_Max.Z*(column2_Max.Z>=0.f ? tbox.MinEdge.Z:tbox.MaxEdge.Z);
        if (tmp>=column3_Max.Z)
            return true;
The ViewProj part of the matrix can be cached in the driver so there is only matrix*matrix multiplication in the function... still faster than transforming 6 planes!
hendu
Posts: 2600
Joined: Sat Dec 18, 2010 12:53 pm

Re: Fastest Box View Frustum Culling

Post by hendu »

This is pretty nice. Interlacing the initialization such that the vars aren't created until they are needed might bring a small speedup.

I wonder how it compares to the sphere-cone method in performance.
Post Reply