Working in screen space

Is there a reason to find out if a triangle is front or back facing in screen space coordinates? It seems peculiar to me why you would want to do this, but I am wondering if there is a reason you would want to do this and why?

Thanks

before hardware t+l cards u used to do this to see if a triangle would show up on screen or not, if not then u wouldnt send it (resulting in a performance boost quake1-3 use this i assume) but nowadays its (usually) quicker to send all the triangles to the card + let the card deal with backface culling

glFrontFace(GL_CW);
This tells the comp that all clockwise-wound triangles are facing front

It’s more difficult to determine facingness in camera space because a triangle which may be back facing in camera space, could be front facing in screen/ndc space after the perspective divide. Most implementations simply find the signed area of the triangle and use that to determine which way it’s facing.

Is there a reason to find out if a triangle is front or back facing in screen space coordinates? It seems peculiar to me why you would want to do this, but I am wondering if there is a reason you would want to do this and why?

Well, for several reasons.

One, it is far easier to tell what the winding order of the triangle is in camera/screen space (it doesn’t matter which) than it is in model space. In screen space, it comes down to a cross product and a compare with the result. In model space, you have to get a normal (via cross product), dot that normal with the view vector (acquired from the modelview matrix), and do a compare of the result. That slower than just a cross product and compare operation.

Two, these days, the transformation from model to screen is programmable; it need not be a mere matrix transform (skinning comes to mind). In these cases, there may not even be model space coordinates; maybe you’re tesselating a bezier spline in a vertex program.

Three, even before the days of hardware T&L, vertex arrays made it difficult for a software driver to pick out vertex data. For a driver to do pre-T&L backface culling, it would have to walk a vertex array and test each triangle. If a trangle was backfaced, it would then have to remove it from the tri-strip and create two (or more) strips where there was only one originally. Since even TNT hardware supported tristrips natively, this meant that the driver would have to render one strip, wait till that finishes, then render the next. This causes a stall in glDrawElements(). Nobody likes stalls, especially in rendering functions, and glDrawElements does some stalling a lot of the time anyway; no need to add more to it.

plus, the less data you send to the graphics card, the less memory bandwidth you’re using - if you can quickly discard stuff before sending it to the card, do it.

Chances are, you’re going to be CPU limited in your app on a HT&L card; and if you’re not CPU limited, you’re probably fill limited.

Thus, letting the card DMA all the data and sorting it out is a net win, because typically it’s using AGP bandwidth (not VRAM, needed for fill rate) and the CPU doesn’t have to touch the data at all.

EDIT: clearly, you should cull out entire meshes when they’re not intersecting the frustum, or when your portal/zone system tells you they’re not visible, or whatever. Just don’t touch any data within each mesh, if possible.

[This message has been edited by jwatte (edited 10-28-2002).]