Sign in to follow this  
cozzie

Frustum culling theory

Recommended Posts

Hi. After I've added frustum culling to my OpenGL 3d engine, I thought I understood how it worked. But it's not 100% clear too me now. This is what the code does (I think) - extract PROJECTION and MODELVIEW matrix (from OpenGL) - multiply MODELVIEW and PROJECTION matrix to create clip-matrix - define X,Y,Z and distance for the 6 frustum sides's vectors (with the clipping matrix) - normalize the 6 frustum sides's vectors Now in my renderscene I do this check for all 6 planes: if((objectX*plane_vector_X + objectY*plane_vectorY + objectZ*plane_vectorZ + plane_vectorLength) < -object_radius) If these checks for all planes return -1 then the object is in the frustum. This is what I don't understand: - Is a plane the "quad" with presents one of the sides of the frustum? - the plane-vector's X,Y,Z and length are being "normalized" before they can be used for frustum-checking. Does this mean the vector is being changed into a normal? - I also don't understand the check if an object is in the frustum: (objposX*plane_normalX + objposY*plane_normalY + objposZ*plane_normalZ + plane_normal_length < -objRadius) Can someone explain to me what exactly happens, thanks in advance.

Share this post


Link to post
Share on other sites
The dot product for two vectors v1 and v2 is defined as:

v1.x * v2.x + v1.y * v2.y + v1.z * v2.z

If you look at the first part of your equation, you will see that it is the dot product of the object's position vector and the plane vector.

Now to planes for a second. A plane can be uniquely defined by a vector and a scalar. Although the vector needn't be unit length, it's more convenient when it is, so we will assume it is unit length and call it the plane normal. This is the 'plane_vector' in your code.

A normal by itself can be associated with an infinite number of planes 'stacked' up along the normal but oriented in the normal's direction. To uniquely identify the plane we also choose a distance from the origin along that normal. This is 'plane_vectorLength' in your code.

Ok, post is getting long so I'll cut to the chase. Given a vector v, a plane normal n, and a plane distance d, then the distance from the vector to the plane is:

v.Dot(n) - d

That's what your equation is doing - finding the distance from the object center to the plane and comparing it to the radius. If the distance is negative the object's center is behind the plane. If the distance is < -radius, the entire object is behind the plane. As soon as you find your object is completely behind one of the frustum planes, you know there is no intersection and you can return false.

Share this post


Link to post
Share on other sites
Thanks for the explanation, which sounds really clear saying it the way you did. I find it very usefull to stop programming at specific moments, just to get back to everything I've done by now, 3d math will allways be kinda difficult.

There's only one thing I don't quite get,
why do I/we normalize the direction vector of the plane (including the length), which gives it a length of 1, does it?

Logically I would say the the length of the vector will change with the normalization to 1, instead of the distance from the plane to the origin of the frustum.

Is this explainable?



Share this post


Link to post
Share on other sites
First, look at just stright multiplication if you have:

x * 1 you'll always get x back.

With vectors, if you "multiply" or dot any vector of length x by a unit vector, which has length of 1, you get a different vector which has length of x.

Try thinking of a unit vector as a direction. We use the vector for many different things but in the true sense of the word a vector is used to represent a direction -- or it points from something to something else.

Hope this make sense and helps ya out.

Share this post


Link to post
Share on other sites
Okay, sound almost clear too me.

If the vector below, was for example a normal plane of my frustum:

x = -4
y = 3
z = 18
length = 76

This vector with distance (plane) is extracted from the matrices, the next thing I'm doing is normalize it.
(first calculate the magnitude of x, y and z, and then divide x,y,z and length with the magnitude).

This way the length of the vector (distance from normal vector of the plane to origin) is also divided by the magnitude.

What I don't get is that the length/distance changes, but the plane's direction and the origin of my world doesn't, why does checking for an object in my frustum work then?

Even though I'm not doing any normalization on the vertex which holds my world position of the object.

Maybe someone can explain this.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this