two-sided lighting in vertex programs

In the OpenGL red book, this statement is made about two-sided lighting:

OpenGL reverses the surface normals for back-facing polygons; typically, this means that the surface normals of visible back- and front-facing polygons face the viewer, rather than pointing away. As a result, all polygons are illumnated correctly.

I tried to enable this normal-flipping in arb_vertex_program by doing the obvious:

glLightModeli( GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE );
glEnable(GL_VERTEX_PROGRAM_TWO_SIDE_ARB);

but it seems to only affect colors, not normals. How can I get that normal reversal based on facedness to happen in ARB_vertex_program? If it cannot be done automatically, is it even possible to detect triangle winding in a VP?

[This message has been edited by Zeno (edited 12-26-2003).]

[This message has been edited by Zeno (edited 12-26-2003).]

I think it is done like this:

  • calculate front lighting

  • calculate lighting with negative of the normal (using the back material properties)

  • Write the result of the front lighting to result.color.front

  • Write the result of the back lighting to result.color.back

(Note you can access front and back material properties - ie. state.lightprod[n].front/back.xxxx)

You cannot access if the vertex is on a forward or backward winding polygon as (with an index array) it could be used in both a forward and backward winding polygon.

I have not actually done this myself, so someone with more experience may be able to help more.

Thanks. That sounds like it’s probably right. I’ll give it a try soon.

Now, a follow-up question: There isn’t any way to do two-sided per-pixel lighting, is there? There is only one output color from the fragment program…

I am less familar with fragment programs (and at the brief look at the spec I could not see a winding order parameter)

But what you could do is this:
In the vertex program write 1,1,1,1 in result color.front and write 0,0,0,0 in result.color.back.

Then in the fragment program if you get 1 or 0 as the incomming color, do front or back lighting.

(Note that in GLSL there is a variable in the fragment shader called gl_FrontFacing which may be what you want)