backface culling

Started by
24 comments, last by blizzard999 18 years, 7 months ago
I was just wondering if anyone knows exactly how OpenGL performs backface culling. I'm guessing that it looks at the 2d projection and sees if the points are in clockwise or counterclockwise order. If they're counterclockwise, and it's in GL_CW mode, then I think it removes the face. What is the fastest way to tell if a set of points are clockwise or counterclockwise though? Thanks. mike http://www.coolgroups.com/
Mike C.http://www.coolgroups.com/zoomer/http://www.coolgroups.com/ez/
Advertisement
I don't know but my guess would be to calculate something similar to a normal for the points and determine whether the resulting vector is pointing towards or away from the viewer.

To add to your question, is there a difference between swapping between back & front culling, or leaving culling mode as it is & swapping between GL_CW & GL_CCW modes performance-wise? Apart from having to specify the vertices in a different order I mean.
"I must not fear. Fear is the mindkiller. Fear is the little death that brings total obliteration. I will face my fear. I will permit it to pass over me and through me. And when it has gone past me I will turn to see fear's path. Where the fear has gone there will be nothing. Only I will remain." ~Frank Herbert, DuneMy slice of the web
Your guess is correct. As far I know, that's exactly how OpenGL performs backface culling.
As for your second question: I believe there is no other way than to arrange your vertices in the desired order by yourself.

//ClockwiseglBegin(GL_TRIANGLES);glVertex3f(-1.0f,-1.0f,0);glVertex3f( 1.0f,-1.0f,0);glVertex3f( 1.0f, 1.0f,0);glEnd();//Counter ClockwiseglBegin(GL_TRIANGLES);glVertex3f(-1.0f,-1.0f,0);glVertex3f( 1.0f, 1.0f,0);glVertex3f( 1.0f,-1.0f,0);glEnd();


Greets

Chris
Backface culling is done in hardware, not by OpenGL. I assume the rasterizer can figure out the orientation when it's calculating deltas and stuff anyway in preparations for filling the triangle.

DrewGreen: No, there is no speed difference.
well, as far as i know, the algorithm is the same as the one used by lighting. it computest the triangle normal vector, then it computes the viewer vector and then it computes a dotproduct between them. if the angle is > 90 degrees, the triangle is invisible to the user.
If this is true, then why is it that OpenGL makes you do normals yourself for lighting but does them for you for backface culling?

Quote:Original post by meeshoo
well, as far as i know, the algorithm is the same as the one used by lighting. it computest the triangle normal vector, then it computes the viewer vector and then it computes a dotproduct between them. if the angle is > 90 degrees, the triangle is invisible to the user.


Mike C.http://www.coolgroups.com/zoomer/http://www.coolgroups.com/ez/
Quote:Original post by mike74
If this is true, then why is it that OpenGL makes you do normals yourself for lighting but does them for you for backface culling?

Quote:Original post by meeshoo
well, as far as i know, the algorithm is the same as the one used by lighting. it computest the triangle normal vector, then it computes the viewer vector and then it computes a dotproduct between them. if the angle is > 90 degrees, the triangle is invisible to the user.


For flexibility, and for the fact that a single triangle can have three different normals for surface approximation, all pointing to different directions.

The winding order of the vertices - in the context of graphics API:s - is almost exclusively used for backface culling.

Niko Suni

The algorithm is very simple

Given a polygon A. B, C, .... you can compute the normal from the first three points.

normal = ( B-A ) ^ ( C-A )


The observer looks always in the opposite z direction ( that is after the modelview transform is like it is)

Now, if the polygon is looking toward the observer the scalar product

normal * observer_direction

is negative otherwise is positive.

// since you need only the z you can 'optimize' the code
bool back_faced = CCW ? ((B-A)^(C-A)).z > 0 : ((B-A)^(C-A)).z < 0;


It's performed by OpenGL before rasterization

EDIT: I confused the sign in back_faced (as I wrote before if the sign is <0 the polygon is front_facing...)

[Edited by - blizzard999 on September 6, 2005 4:05:34 AM]
yes, this must be the algorithm.
Quote:Original post by blizzard999
The algorithm is very simple
Given a polygon A. B, C, .... you can compute the normal from the first three points.
The observer looks always in the opposite z direction ( that is after the modelview transform is like it is)
Now, if the polygon is looking toward the observer the scalar product
is negative otherwise is positive.


I'm sorey, but you are absolutely wrong )))
Imagine the situation: you have wide viewport with the horizontal range of about 120-150 degrees. Imagine the cube in front of you, which is oriented right to you by one of its faces. Only cube front side is visible to you, the others are got clipped by your algorithm, because they have 0 dot product (the back side has negative dot product, so, it is clipped anyway).
This is right situation and right solution, but until the cube begins to move to the right. It is moving, moving... Dot products remain the same... Now we must see it's left side!!! Imagine it, we MUST see it! But it is still clipped due to your algo.

The only right method to verify it, is to build a plane, including 3 triangle vertices, and to watch, whether the viewing point is lying in positive half-space according to this plane.

So, the algo is:
---------------

A, B, C - points of triangle after modelview transformation

calculate triangle plane:
N = (B - A) x (C - A)
d = A dot N

Now, the equation of plane is : N dot X - d = 0
Equation of positive half-space is : N dot X - d > 0


So, put here X = (0,0,0)
Now, we have -d > 0 to accomplish test, or, d < 0 - triangle is visible

So, if A dot ((B - A) x (C - A)) >= 0 - triangle is got culled.

This topic is closed to new replies.

Advertisement