Advertisement

Manual BackFace Culling. Is this Correct Way?

Started by August 02, 2002 05:52 PM
5 comments, last by crakinshot 22 years, 6 months ago
hey its the idiot again... I was playing around with my new vector class and matrix class and been rendering some planes and lines to indicate there normals... and I activated back face culling and I had an idea of manually culling faces instead of sending the 6 function calls to opengl to render it, then only to find it not render the face cus its a backface... this is almost certainly been done but its a first for me (as is everything)... anyway my idea... now I'm just gunna look down the Z axis for now.. cus its easier for me to explain.. plus I aint figured out how to do all 3D calc yet.. hehe... if you have a vector to the center of the plane urr... let say 'Vc' and a plane defined by P and the normal of that plane as Pn... then... ahh yes... (still thinking this through) so if the Angle (A) between C(the camera) and Pn with Vc as the rotation point, is greater than 90 deg or less than -90 deg... then dont show the face... and I suppose I could use the dot product angle thingy to find the angle??? ( A = RAD2DEG (acos(Vc . Pn)) ???? ) I'm not tooo sure if it would work... but I never used it before so I dont know... hehe... now I havent tested it yet... but I though I would ask before trying... just to see if this was the correct way... [edited by - crakinshot on August 2, 2002 7:11:27 PM] [edited by - crakinshot on August 2, 2002 7:14:13 PM]
-=CrAKiN:ShOt=-I could put something witty here but I'm not that stupid...
quote:
Original post by crakinshot
hey its the idiot again...

I was playing around with my new vector class and matrix class and been rendering some planes and lines to indicate there normals... and I activated back face culling and I had an idea of manually culling faces instead of sending the 6 function calls to opengl to render it, then only to find it not render the face cus its a backface...

[...more stuff...]

ahh yes... (still thinking this through) so if the Angle (A) between C(the camera) and Pn with Vc as the rotation point, is greater than 90 deg or less than -90 deg... then dont show the face...

[...still more...]



The method that you describe method does indeed work. Of course, its a tradeoff. If the graphics card supports backface culling then it may be quite a lot faster than doing it in code.

quote:
Original post by crakinshot
now I havent tested it yet... but I though I would ask before trying... just to see if this was the correct way...



Althougy your way does work, the way the hardware does it is to to determine whether the corners of the triangle are counterclockwise or clockwise in screen space, rather than looking at the angle between the triangle normal and the vector pointing from the camera to the center of the triangle. The clockwise/counterclockwise check can be done quite a bit faster than your method----once you get the thing into screen space.

For example, if your triangle is defined by points 1, 2, and 3, in that order (so the triangle consists of line segments 1-2, 2-3, and 3-1), then the triangle is counterclockwise if one of the three following is true:

a) (point[3].y > point[1].y) && (point[3].y > point[2].y)
b) (point[2].y > point[3].y) && (point[3].y > point[1].y)

or,

c) (point[1].y > point[2].y) && (point[3].y > point[3].y)

(Those .y''s are screen space coordinates, with positive y pointing upwards.)

No need to deal with messy dot products or acos or atan calls. Just simple integer compares that can be VERY fast in hardware.

You could even do this method in code, but if you''re using hardware to do T&L then you''d actually need to duplicate the T&L and projection stages in the CPU and again in the GPU, which would be a waste of time....My bet? Let the GPU do the back face cull for you.

Graham Rhodes
Senior Scientist
Applied Research Associates, Inc.
Graham Rhodes Moderator, Math & Physics forum @ gamedev.net
Advertisement
It may be the same solution as Graham's (although with comparisons like point[3].y > point[3].y, I doubt it), but I think it can be done with the z value of the cross product of the edges:

e1 = point[1] - point[0]
e2 = point[2] - point[1]

if(e1.x * e2.y > e1.y * e2.x) front facing else back facing

It may be reversed (front<=>back), but I'm quite sure this works.

Cédric

EDIT: With DirectX, D3DXVec2CCW evaluates this, so it should be faster than 'handcrafted' code.

[edited by - cedricl on August 2, 2002 8:51:52 PM]
quote:
Original post by grhodes_at_work

You could even do this method in code, but if you''re using hardware to do T&L then you''d actually need to duplicate the T&L and projection stages in the CPU and again in the GPU, which would be a waste of time....My bet? Let the GPU do the back face cull for you.


So just send all the faces in the view range to the API then?

I thought at first it ''MAY'' of been faster to manually do it... cus you remove 1 triangle opengl has to deal with... but like you said (and I had of though of this) you have to take into account the projection...

okay thanks...

-=CrAKiN:ShOt=-I could put something witty here but I'm not that stupid...
It actually may be a tossup/draw in terms of time when you compare sending extra triangles down to the hardware vs. sending only some. For example, your dot product and angle comparison might be exactly the same expense as the hardware doing extra T&L and projection. So both ways give exactly the same performance.

But its more complicated than that. If you start culling individual triangles yourself, you will then have to figure out how to properly send the subset of triangles down to the hardware. The easiest way is to send individual triangles, but that''s also the slowest. Once you talk about sending meshes or triangle strips, then if you need to remove individual triangles the trips and meshes will be broken. Reconstructing those meshes on-the-fly to get the best hardware performance will surely be more expensive than just letting the hardware do the culling.

The cost of the hardware doing backface culling is essentially free. The only cost is to transform and project vertices, and based on my argument above, there would be no savings from culling individual triangles in software.

Graham Rhodes
Senior Scientist
Applied Research Associates, Inc.
Graham Rhodes Moderator, Math & Physics forum @ gamedev.net
quote:
Original post by cedricl
It may be the same solution as Graham''s (although with comparisons like point[3].y > point[3].y, I doubt it), but I think it can be done with the z value of the cross product of the edges:

e1 = point[1] - point[0]
e2 = point[2] - point[1]

if(e1.x * e2.y > e1.y * e2.x) front facing else back facing

It may be reversed (front<=>back), but I''m quite sure this works.

Cédric

EDIT: With DirectX, D3DXVec2CCW evaluates this, so it should be faster than ''handcrafted'' code.

[edited by - cedricl on August 2, 2002 8:51:52 PM]


Your method certainly should work. And it might very well be faster than mine since you only have one compare. (Who knows how the hardware actually does it? ).


Graham Rhodes
Senior Scientist
Applied Research Associates, Inc.
Graham Rhodes Moderator, Math & Physics forum @ gamedev.net
Advertisement
quote:
Original post by grhodes_at_work
The cost of the hardware doing backface culling is essentially free. The only cost is to transform and project vertices, and based on my argument above, there would be no savings from culling individual triangles in software.



What I mean to say by this is that any savings in the number of triangles you would send to the GPU with software backface culling would be lost since you'd be actually either: a) sending more vertices, in the case of sending one triangle at a time instead of tristrips or meshes; or b) spending so extra much time reorganizing the mesh (including possibly touching vertex and index buffers) in order to send the GPU what it likes (tristrips or meshes).

Graham Rhodes
Senior Scientist
Applied Research Associates, Inc.

[edited by - grhodes_at_work on August 5, 2002 3:54:37 PM]
Graham Rhodes Moderator, Math & Physics forum @ gamedev.net

This topic is closed to new replies.

Advertisement