AABB is Behind Plane Test

Started by
4 comments, last by NullStar 5 years, 7 months ago

Hello. I'm trying to come up with a simple method to cull an AABB against frustum planes, and I have something here, but I'm wondering if the logic is flawed. I am not currently able to test it, and have been in these situations before where I think I have a solid idea and then later realize it didn't make much sense. Can anyone confirm or deny this will work? The idea is pretty simple. Find the corner of the AABB that is farthest into the direction of the plane normal and test only that single point. If the point is in front of the plane (inside the camera frustum), then the AABB cannot be culled by that frustum plane and is still considered visible. Function to test against a single plane:


bool TestPlaneAABB(const VEC3 &eye,const VEC3 &normal,const AABB &box) const
{
	// prepare most-positive vector offset
	// + this will be the (offset of the) corner of the AABB that is farthest into the direction of the plane normal
	VEC3 most_positive_offset(
		( normal.x < 0 ? box.Left : box.Right ) - eye.x,	// choose x-side that is most positive relative to plane normal.x
		( normal.y < 0 ? box.Bottom : box.Top ) - eye.y,	// choose y-side that is most positive relative to plane normal.y
		( normal.z < 0 ? box.Back : box.Front ) - eye.z );	// choose z-side that is most positive relative to plane normal.z

	// now simply return the result based on which side (of the plane) the most positive corner is on
	// + if this returns true, the most positive point is on the positive side and the box is still partially visible
	// + if it returns false, the most positive point is BEHIND the plane, meaning the entire box is behind the plane
	return Dot3( normal, most_positive_offset ) >= 0;
}

So I would just execute this function once for each frustum plane to determine if the box is hidden or visible. I tried to do some research on AABB frustum tests, but didn't find much that helped. If there is a simpler or easier way to do this, I really appreciate any insights.

Thanks!

Advertisement

What you describe is one of various standard approaches to culling an axis-aligned box against a plane. This article seems to discuss a similar method (under '16.2.4.3 Frustum/AABB Intersection').

I haven't examined your code carefully, but it looks like you have the right idea. Obviously testing it will tell you more though.

This is a fine way to write this function (assuming your implementation is correct, which I didn't really read).

You are describing what is a called a support function. Basically a support function answers the question - given a convex set (your AABB) - what is the most extreme (furthest) point in a given direction. Obviously the AABB is in front of the plane if the support point in the negative normal direction is still in front of the plane. Or vice versa the AABB is behind the plane if the support point in the positive direction of the normal is still behind the plane. 

I attached a sketch to visualize the idea:

Capture.PNG.055056dcbe8042263f84d675a0d18dfc.PNG

The plane tests you are describing are actually a subset of the separating axis test (SAT) between a frustum and an AABB. Since you are only testing a subset you might get false positives. E.g. you will draw objects which are not inside the frustum. 

Another option is to use a SAT-GJK for this problem. This is a simplified GJK test which doesn't report closest points, but only whether to object intersect or not. 

 

Thanks, I appreciate the feedback. The part I was least confident in was the concept of generating a single point to represent the AABB in respect to the plane. I wasn't sure if that made sense.

This topic is closed to new replies.

Advertisement