PDA

View Full Version : two-sided lighting in vertex programs



Zeno
12-26-2003, 11:03 AM
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).]

sqrt[-1]
12-26-2003, 06:28 PM
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.

Zeno
12-27-2003, 10:22 AM
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....

sqrt[-1]
12-27-2003, 02:57 PM
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)