I’m having a bit of confusion about how lighting works in OpenGL.
In order to calculate the light at a vertex, OpenGL needs to find the distance between the vertex and the light, which is a simple enough operation. However, in all the diagrams of the graphics pipeline I have found, the lighting is performed afer projection and normally clipping.
Surely the act of projecting the primatives (and presumably the lights) will modify the distances (and possibly the directions?) giving an inaccurate result.
How does OpenGL resolve this? Prehaps the distances are calculated before projection and stored? Or maybe the primatives and lights are un-projected before finding distances? Anyone got any ideas?
The colour of a vertex with respect to all the enabled lights in the scene is calculated before ‘projection’.
Don’t know what diagrams you’ve seen, but they are wrong. Check out vertex programs to see how it’s actually done.
OK, so then lighting is calculated before clipping takes place? Is this not inefficent, as it will be calculated for primatives which will be culled completly?
The GL specification just states the order in which the operations must seem to take place. This means if an implementation wants to cull before lighting it can, so long as the results do not differ. In general, I believe most implementations light before clip though. Remember, that clipping will frequently generate more vertices, so as long as the app isn’t sending a lot that should be trivially rejected, this order is just fine.
Lighting after clipping is just plain wrong according to the spec.
For one thing, you need a normal for the clipped vertex and there’s no defined scheme for normal interpolation. Yes, you can make one up, but the interpolated normal probably isn’t normalized. You could re-normalize (assuming that’s what the user wants) and get a lighting result. But then you’d get specular highlights that appear and disappear for no reason other than clipping.
Vertex lighting before clipping still is hit or miss with specular highlights, but at least they are invariant w.r.t. clipping.