Automatic normal per triangle

  • Many OpenGL cards can compute hardware culling for triangle, which means that they compute cross products per triangle for “free”.

  • Many OpenGL cards can normalize normals in hardware.

Knowing this, I would expect that there is a way to shade triangles in flat_shaded mode without specifying any normal, but instead have it automatically computed on the card using the cross product…

Anyone knows if there’s a way to do this, to have automatic per-triangle flat shading?



I guess it’s possible with a pixel shader, but I’m more interested to know if it’s possible within the basic shading & lighting pipeline…

glShadeModel( GL_FLAT );


This is not what I want; I want to send no normal at all (no glNormal3f), I would want OpenGL to itself create them using the cross product of 2 triangle vectors, the exact same cross product that he uses to define if a triangle is front or back-facing (to do culling or to define if it should use the inner or outer material).


Unless I made something wrong, but I did a test and GL_FLAT with a light an no normals gives all white shading (but is correctly flat shaded if normals are specified per polygon).

no not possible, u could write a shader but then i suppose youll have to send the other 2 vertices as well.

Unless I made something wrong, but I did a test and GL_FLAT with a light an no normals gives all white shading
youre right, all white is what u should see

Well OK then… thanks.

Hey Jerome_cg, you might want to have a peek at section 3.5.1 in the spec w.r.t. front/back face determination.

How does that equation (2.6) work anyway?
And also, it’s actually possible to have polygons like tri strips and tri fans be both front and back facing at the same time if they are folded a bit.

I’m sure that graphics cards break down everything to tris which gives good results, but the spec talks in terms of primitives.

Originally posted by V-man:
How does that equation (2.6) work anyway?

It calculates the area of a polygon. If the area is negative, the vertices are winded the “wrong” way and it is considered back facing.

As an example, think of the simplest case; a triangle. To calculate the area of a triangle, you can use the cross product. The length of the cross product of two vectors is equal to the area of the parallelogram (think that’s the shape) spanend by the two vectors. The triangle is half that size, hence the factor 0.5.

Now, let’s say we have three vertices (X0, Y0), (X1, Y1) and (X2, Y2) forming a triangle (vertices are in screen space coordinates or a similar coordinate system, like normalized device coordinates). Let’s pick two edges to calculate the cross product. A zero is appended to form three dimensional vectors in order to calculate the cross product.

V = (X1, Y1, 0) - (X0, Y0, 0) cross (X2, Y2, 0) - (X0, Y0, 0)

Half the length of the resulting vector is the area of the triangle. So let’s calculate the cross product of the two vectors above.

V = (0, 0, (X1-X0)*(Y2-Y0)-(Y1-Y0)*(X2-X0))

Since the first two components of V are zero, the length of the vector will be equal to the third component.

Now we expand the third component and reorder the factors, and we get the following.

Area = Vz = (X0*Y1 - X1*Y0) + (X1*Y2 - X2*Y1) + (X2*Y0 - X0*Y2)

Now, try expanding the summation in equation (2.6) for three vertices and see what you get. Hopefully you get the exact same thing as Vz above.

So, together with the factor 0.5, that formula calculates the area of the triangle, given the screen space coordinates of the triangle. A positive area means it’s a front facing triangle, a negative are means a back facing triangle since the vertices are winded in the “wrong” way to produce a positive area.

It’s also easy to expand this to a polygon with an arbitrary amount of vertices. Concider a quad for example. The formula is applied for the two triangles building a quad, and the common edge will appear twice, but in different “directions”, canceling each other from the equation when summed together to calculate the area of the quad. This can then be applied for polygons with more vertices.

Hope that was correct. I just verified it quickly on paper before I wrote this, so I could be wrong somewhere :stuck_out_tongue:

Ahh, you beat me to it Bob … yours in prettier anyway.



i think where you may be mistaken is you are assuming triangles are culled via their normals in object space, but in actuality they are culled in screen space after projection based on how their vertices are oriented.

in other words normals are never computed by the graphics hardware indapendantly.

Thanks Bob.

If the idea is to get the sign, then multiplying by 0.5 is not necessary.

The formula is, as mentioned in the specification, for calculating the area of the polygon, and then you need the 0.5 to get correct value.

But as you say, if all you really need is the sign, then you don’t need it. That is, however, an implementation detail, but the specification is about conceptual details (enforcing correct result, not a certain way of achieving that result). :wink: