It seemed a little strange to me so I made a little app to test how much time it took. It appears that the time the intersects method takes varies by where the axis aligned bounding boxes are positioned. This makes sense because more checks are needed in some cases to verify that an intersection is not occurring.
I imagine you are running this code on the Xbox 360 since you have a large performance impact. Using Reflector it is easy to see that the method was not coded with speed in mind. The function is riddled with floating point operations and function calls. The compact .Net framework does not inline any function calls and combined with the horrible floating point performance I can see why so much time is used up by the intersects function.
I did some research and came across this article: http://zach.in.tu-clausthal.de/teaching/cg_literatur/lighthouse3d_view_frustum_culling/index.html
There are various faster methods for frustum culling you could implement to speed things up. Here is a reasonably accurate intersects implementation which is about 7 to 10 times faster.
(note: it does give a few false positives, see the "Geometric Approach - Testing Boxes" section of the article above)
public static class FrustumHelper
{
public static Vector3 GetNegativeVertex(this BoundingBox aabb,
ref Vector3 normal)
{
Vector3 p = aabb.Max;
if (normal.X >= 0)
p.X = aabb.Min.X;
if (normal.Y >= 0)
p.Y = aabb.Min.Y;
if (normal.Z >= 0)
p.Z = aabb.Min.Z;
return p;
}
public static void FastIntersects(this BoundingFrustum boundingfrustum,
ref BoundingBox aabb,
out bool intersects)
{
intersects = false;
Plane plane; Vector3 normal, p;
plane = boundingfrustum.Bottom;
normal = plane.Normal;
normal.X = -normal.X;
normal.Y = -normal.Y;
normal.Z = -normal.Z;
p = aabb.GetPositiveVertex(ref normal);
if (-plane.D + normal.X * p.X + normal.Y * p.Y + normal.Z * p.Z < 0)
return;
plane = boundingfrustum.Far;
normal = plane.Normal;
normal.X = -normal.X;
normal.Y = -normal.Y;
normal.Z = -normal.Z;
p = aabb.GetPositiveVertex(ref normal);
if (-plane.D + normal.X * p.X + normal.Y * p.Y + normal.Z * p.Z < 0)
return;
plane = boundingfrustum.Left;
normal = plane.Normal;
normal.X = -normal.X;
normal.Y = -normal.Y;
normal.Z = -normal.Z;
p = aabb.GetPositiveVertex(ref normal);
if (-plane.D + normal.X * p.X + normal.Y * p.Y + normal.Z * p.Z < 0)
return;
plane = boundingfrustum.Near;
normal = plane.Normal;
normal.X = -normal.X;
normal.Y = -normal.Y;
normal.Z = -normal.Z;
p = aabb.GetPositiveVertex(ref normal);
if (-plane.D + normal.X * p.X + normal.Y * p.Y + normal.Z * p.Z < 0)
return;
plane = boundingfrustum.Right;
normal = plane.Normal;
normal.X = -normal.X;
normal.Y = -normal.Y;
normal.Z = -normal.Z;
p = aabb.GetPositiveVertex(ref normal);
if (-plane.D + normal.X * p.X + normal.Y * p.Y + normal.Z * p.Z < 0)
return;
plane = boundingfrustum.Top;
normal = plane.Normal;
normal.X = -normal.X;
normal.Y = -normal.Y;
normal.Z = -normal.Z;
p = aabb.GetPositiveVertex(ref normal);
if (-plane.D + normal.X * p.X + normal.Y * p.Y + normal.Z * p.Z < 0)
return;
intersects = true;
}
}