backface culling

I’m trying to do some backface culling, but I doesn’t seem to work properly (maybe becouse I don’t understand it much).

rendering loop:

VecNormal(&pFace->Normal,
Verts[pFace->Start].Pos,
Verts[pFace->Start+2].Pos,
Verts[pFace->Start+1].Pos);

if(!IsBackface(ActiveCam->Pos, Verts[pFace->Start].Pos, pFace->Normal))
{
// Render Face
}

Some math functions:

void VecNormal(t_Vec3f *v, t_Vec3f Vert1, t_Vec3f Vert2, t_Vec3f Vert3)
{

t_Vec3f Vector1, Vector2;

Vector1 = VecSubtract(Vert3, Vert1);
Vector2 = VecSubtract(Vert3, Vert2);

*v = VecCrossProduct(Vector1, Vector2);

VecNormalize(&(*v));
}

// Needed for backface-culling
bool IsBackface(t_Vec3f CameraPos, t_Vec3f VertexOnPlane, t_Vec3f Normal)
{

t_Vec3f CameraToPlane;

CameraToPlane.x = VertexOnPlane.x - CameraPos.x;
CameraToPlane.y = VertexOnPlane.y - CameraPos.y;
CameraToPlane.z = VertexOnPlane.z - CameraPos.z;

return (VecDotProduct(CameraToPlane, Normal) >= 0);
}

It seems that the polygons are culled as the camera would be at the start point even if move around.

why do you want to do this instead of relying on opengl to do it for you?
i think i read somewhere, that it is more efficient to let it be done by opengl (except your are using some space partitioning algorithm, which do it for no cost anyway)

I think this is a differend kind of backface culling. As far as I know, openGl’s backface culling affects only so that only the other side of a polygon is drawn, but what I’m trying to do, is to skip the polygons that are facing out from the camera. Still, I might be wrong about that.

…but what I’m trying to do, is to skip the polygons that are facing out from the camera

And that’s exactly what OpenGL’s back face culling is about; to remove triangles not facing the viewpoint. If they don’t face the viewpoint, they are thrown away. Of course, it’s more general that that, since you can cull front faces aswell.

Are you saying that just enabling GL_CULL_FACE, OpenGl skips the backfacing polygons. Like, if I have a linear model with 2000 polygons, only á 1000 of them are drawn at some point.

Then what are the bf culling tutorials all about out there. Are they just to demonstrate how you could do bf culling your self?

If your model has 2000 faces, and only 1000 of them face the viewpoint, then the other 1000 will not be drawn, OpenGL will throw them away.

But note this, you must still pass the faces to OpenGL before it can be thrown away. This means, in the above example, that you PASS 2000 faces to OpenGL, but only 1000 will be DRAWN.

I stronly discourage you to do your own backface culling, unless you do it for learning. If you have a graphics card with HWT&L, the backface culling is more or less for free. And even if you don’t have HWT&L, letting the driver do it for you is still good.

[This message has been edited by Bob (edited 04-26-2002).]

hi

i’m not sure whether it’s always fastest way of backface culling to let it do OpenGL…

in my level renderer i do it by myself and although haven’t tested the performance of it comparing to what OpenGL would do it doesn’t seem to slow me down at all - to make it faster than just computing dot product for every polygon i want to draw, i put into array normals of all faces in level, but only once, so that all normals in that array are different…this lets me
not to repeat the same dot product computation for faces with same normal vector

note that there’re usually not many faces with different normals and usually most common faces are orthogonal ones

but that’s about optimizing,… backface culling is nothing more than point_on_plane_side_test which is necessary in many situations like lighting, collisions and more…

hope that helps

I read somewhere that OpenGL backface culling is optimised (I assume in both HW & SW) to do it faster than typical backface culling algorithms. Additional, in the case of HW, you lessen the load on the CPU and the additional load (if any) isn’t significant on the GPU. So it sounds like its faster to let OpenGL do it and facilitates better load distribution.

blender - your code looks good. If moving the camera or the model doesn’t change what gets culled, then probably the values passed into the function is wrong. Are your vertices in world space or model space?

As far as roll-your-own vs OpenGl back-face culling, here’s why it is better to let OpenGL do it – if you do your own back-face culling then you can’t use strips, fans, display lists, or compiled vertex arrays. You could use regular vertex arrays but you have to build them every frame.

If you can’t use strips, fans, etc. then it is faster to do your own because you will be sending less geometry to the video card. However, on some platforms it takes the CPU longer to cull the triangle than it takes the video hardware to draw it!