Archive: real backface culling?


12th May 2004 09:38 UTC

real backface culling?
I am trying to create a method to cull the backfaces of any polygon based superscope. I started with a simple cube. as a helper I created a texerII with one sprite for each side. when the side of the cube would be culled, the texerII sprite should become invisible. so i created a texer with 6 sprites at the positions
(1;0;0), (-1;0;0), (0;1;0), (0;-1;0), (0;0;1), (0;0;-1). my idea of backface culling is the following:
for each face you calculate the normal and then, via raytracing, you check the angle between normal and the ray to the middle of the face. if the angle is larger than 90°, the face must be invisible.
for the texer my culling code looks like this:
x2, y2 and z2 are the coordinates of the point after the rotation.
so the normal if (x2;y2;z2). the rayvector is (x,y,1) where x and y are the 2d coordinates of the point after 3d->2d mapping.
the angle of the normal is atan2(sqrt(x2*x2+y2*y2),z2);
the rayangle is:
atan2(sqrt(x*x+y*y),1);
the angle between the two would now be:
angle=abs(normalangle-rayangle);
then with above(angle,$pi*.5) I do the color coding. but for some reason, it does not work.
I can't post the preset right, but I will do that later if required.


12th May 2004 12:16 UTC

Erm... im doing it little different:
-I calculate normal vector
-I calculate point-eye vector AND normalize it (normalization is only for correct shading)
-Find dot product between those 2 vectors, and check if its below 0, if so, the eye doesnt see the point and you can easily skip it.
Works perfectly for simple shapes, but as for torus and more complicated shapes it doesn't work (could fix it thanks to unconed for torus, you can see the preset in my da acc)=)

Only thing thats complicated here is finding the deamn normal :D


14th May 2004 10:55 UTC

err? afaik the dot product is the vector: c = a*b*sin(a,b)
this vector has three components: x, y and z. so what do you mean by "below 0" and how does this work at all. can you please explain to my why my method doesn't work and why I have to use the product.
btw: where can I find you culling preset?


14th May 2004 11:37 UTC

dot product is:
a*b
=ax*bx+ay*by+az*bz
=|a|*|b|*cos(angle(a,b))
dot product returns a number, not a vector.

and there is also a cosine formula:


a*b ax*bx+ay*by+az*bz
cos(angle(a,b)) = --------- = -----------------------------
|a|*|b| (ax²+ay²+az²)*(bx²+by²+bz²)

this formula is basically reformed from 3rd line of the dot product formula above and then out-multiplied.
btw your method sounds quite 2D-ish, and thus can't really work for 3D objects ;) at least not for all of them. 3D vectors do not have one angle as 2D vectors have, as they're not all in one plane. Angles are always connected to planes.

Skalarprodukt ist:
a*b
=ax*bx+ay*by+az*bz
=|a|*|b|*cos(winkel(a,b))
Beim Skalarprodukt kommt ein Skalar raus wie der Name schon sagt ;) also eine Zahl, kein Vektor.

und dann gibts da noch die Cosinusformel:

a*b ax*bx+ay*by+az*bz
cos(winkel(a,b)) = --------- = -----------------------------
|a|*|b| (ax²+ay²+az²)*(bx²+by²+bz²)

Diese Formel ist eigentlich nur die 3. Zeile der Skalarproduktsformel umgeformt und dann ausmultipliziert
btw deine Methode hört sich ziemlich 2D-isch an, kann also eigentlich garnet funzen für 3D-Objekte ;) zumindest nicht für alle. 3D-Vektoren haben nicht nur einen Winkel wie 2D-Vektoren, weil sie nicht alle in einer Ebene liegen. Winkel gibt's immer nur in Ebenen.

14th May 2004 14:05 UTC

you didn't read my formula correctly. i didn't say that each vector has one angle, but there is only one angle between the two vectors. i also tried the thing with the product, but it didn't work.


14th May 2004 17:27 UTC

y-d: First of all, you can't do an abs() on angles because e.g. 2***960; and 0 would not work.

Tomy's comment is still valid: you cannot determine the angle between two vectors using one atan2 on each and then doing a difference: you're simply determining one of the angles in spherical coordinates and taking the difference.

According to your formula, there is 0° between (1,1,1) and (-1,-1,1).


15th May 2004 09:16 UTC

Geeezz.

just stop and look at jaak's method work out what each step doing. The purpose of the whole thing is to work out when a point is facing away from the camera, right?

*you take the normal vector from the point (that tells you which direction the point is facing)

*get the vector between the camera and the point (like you would with a raytraced dm).

*now, you have two vectors, so we just need to check if they are pointing in the same direction(cull it) or the opposite direction(draw it).

One way to do it is to do a dot product with:


a.b=|a|*|b|*[(a*b)/(|a|*|b|)]


since the dot product finds the length of a projection of B onto A:
http://mathworld.wolfram.com/d2img1872.gif
then the results yeild:

if the two vectors are facing the same direction (like in the picture) then the dot product is positive, so we can safely cull that point. If they are facing away from each other, then the dot product is negative, so we want to draw it.

OK?

15th May 2004 11:45 UTC

i even wrote comments to it


17th May 2004 10:12 UTC

I tried it at home with the dot product, after I found out that I overread the "dot" and thus used the wrong formula, and it works a bit as it's supposed to. BUT, the point of the texer is culled away too early and reappears too late, so the still is some bug in there. I'll send the preset, so you can take a look at, tomorrow.


20th May 2004 18:34 UTC

Well, "tomorrow" was not quite right. Anyway, here'S my preset, maybe someone can have a look at it to help me out.
Some info 'bout the preset: the last superscope is the cube which should cover the texer's particles. The texer makes the particles and the culling, which does not work as expected.