Archive: Backface Culling


2nd November 2004 23:05 UTC

Backface Culling
This is a technical backface culling question so noobs can hit the ol' back button now.

While helping wotl with his 'house' preset (http://forums.winamp.com/showthread....hreadid=197874) I used backface culling, but I was reminded that my method is a little flawed.

Essentially I take the normal to the face I want to cull, for example

x1=0;
y1=0;
z1=1;

Then I pass that through my rotation matrices given the current angles of rotation to retrieve a final 'z' value, so that I have the rotated normal. Now currently I simply compare this to an arbitrary number, say 0.2, to test if the normal faces "away" from the camera enough to cull the face. But 0.2 is just a magic number I have stuck in through trial and error... to be correct should I be comparing the camera vector against the rotated normal? If so how do I do this?

The vector of the camera is 0,0,-1 (well, -x depending on my camera)? So do i need to compare the angle between this and the rotated normal to see if it is above 90 degrees?


3rd November 2004 01:10 UTC

Well, I'm not sure how you'd go about doing this, but assume you're looking top-down at the face. For sake of simplicity, let's just say it's vertical. Now, with the post-rotated normal vector, you should be able to calculate the angle it's pointing in.

Assume this is a top-down view of something post-camera.


^ y
| /
|*/
|/
<----+---->
| x
|
|
v

The slashes represent a face, and the * indicates the direction it's pointing. So the x,y values of the vector should be something like <-.7072, .7072>(or <-1,1>, unnormalised). You can then reverse-calculate this angle as being 3*Pi/4 radians. Basically, from this top-down perspecitve, the face is pointing away if the angle represented by the normal is between 0 and 180 degrees or 0-Pi radians. At least this is how I figured it when working in QBasic.

3rd November 2004 19:24 UTC

But thats a 2D example so it doesnt account for perspective...I'm not sure I really understand your explanation. Are you saying you take the angle of the rotated normal (of the face) and check if it is between 0 and 180 degrees? That makes sense, but we surely need to specify the angle of the normal *with relation* to the camera (as a vector?). Thats the part I dont know how to do.

Here's an example...

AVS Frame Code

xn1=0; //normal x
yn1=0; //normal y
zn1=-1; //normal z

//put thru rotation matrices

xn2=xn1*cz-yn1*sz;
yn2=yn1*cz+xn1*sz;
zn2=zn1;

xn3=zn2*sy+xn2*cy;
yn3=yn2;
zn3=zn2*cy-xn2*sy;

xn4=xn3;
yn4=yn3*cx-zn3*sx;
zn4=yn3*sx+zn3*cx;

cull=below(zn4,0.25); //This is a hack, what should go here?


4th November 2004 08:52 UTC

Say you have the normal vector of the face you want to cull, you don't need to account for camera rotation. Just the object's own rotation in space.

After that, take vector from the camera to any point on that face (by subtracting the camera coords from a vertex's coords. You have a difference value for each axis, that makes up your vector because the direction is implicit). And compare the two vectors to see if they point the same way. (Compare them with a dot product for example, which gives you the length of a projection of one vector onto the other. If that resulting length is positive, then they point in the same direction. If its negative, then the face points towards you.

the rotation of the camera doesnt matter at all. For example, backface culling a shape that is behind the camera would use exactly the same method (but useless).

Imagine that the camera is the center of a spherical space. your vectors to the faces you want to cull are like spokes in that sphere. So the direction of the camera doesnt matter. All that matters is the direction to the shape you are culling, and the direction of the normal from each face.

i hope that made sense.. or at least was slightly relevant :/

[edit]Arg. i get you now. I thought you were rotation that normal vector with your camera. But you were just rotating the shape in space (right?). Oh well, the rest of what i said still stands.


4th November 2004 17:03 UTC

Okay yea I see your point, the rotation of the camera doesnt matter at all.

So if I get you... I need to take a vector from the camera to the face (A) (centre of the face would be logical I guess) and compare this to the rotated normal (B). Then I can say if A dot B is less than zero the face is visible... got it.

Thanks for teh help, I'll try it out (when I'm not so busy coding huffman algorithms in matlab)


6th November 2004 18:53 UTC

just do culling before rotation

N(nx,ny,nz); <- normal vector
E(ox-px, oy-py, oz-pz) <- eye-point vector
if E.N < 0 cull (you can cut 3 subtractions using px-ox, etc. and cull if greater than zero)
now px=px-ox, py=py-oy, pz=pz-oz and rotate the (px,py,pz)

i suck at explaining, but this is how i do bf culling, and it works for me. (i think its culling in object space, not camera space).


17th November 2004 08:53 UTC

I always tend to work with the vector from a vertex to the camera so that if it's positive then you draw it. And then it works well with doing reflections and specular highlights etc.