Lighting concept questions

Started by
2 comments, last by DalTXColtsFan 21 years, 2 months ago
Greetings all, Thanks for help in advance. 1. Correct or incorrect: A light becomes a "spotlight" after setting the 4th parameter of the GL_POSITION parameter to 1.0. The GL_SPOT_CUTOFF can also be changed, but for all practical purposes, a positional light is a spotlight. 2. Question: If I only create one light source, for example GL_LIGHT0, and I make it a spotlight (GL_POSITION''s 4th parameter is 0) and GL_SPOT_CUTOFF to something small like 10, can I still control the ambient light and diffuse light? For example, if I have a streetlight in a city, can I simulate both the sun and the streetlight... wait I think I just answered my own question. If I turn the ambient light up and down, i.e. shades of grey, I''ll be turning the intensity of the streetlight up and down as well. If I want the day/night control and the streetlight, I''d have to use one directional light source for the sun and raise/lower its intensity based on the hour, and a second for the streetlight that would remain constant. Any of this make sense? What are the "missing gaps" in my understanding? Thanks Joe
Advertisement
settings the positions 4th (w) coord to zero indicates an infinite light where the position is actually the direction of the light. set to 1 will be a point light about the position. Use GL_SPOT_DIRECTION to set the direction of the spot light from the position (ie, treat it as a point light). A GL_SPOT_CUTOFF value of 0 will set a point light (default), other values indicate a spot.

Note that spots/point lights are signficantly slower than infinite, spots slightly more so than point (in GL, apparently it's the other way around in d3d). And infinite lights with GL_LIGHT_MODEL_LOCAL_VIEWER (glLightModel) set to true are basically no faster than point lights (ie, they are much slower when set to true).

One other thing to note when working with lights that is very important (in GL, but not D3D) is that when you set a position value, that position is then multiplied by the inverse of the modelview matrix. What this means, is that if you have used glTranslate/rotate/loadmatrix/etc to, say, render a sphere somewhere on screen, then WHEN you make calls to glLightf/glLightfv is very important. If you wanted the light to be in the centre of the sphere (no idea why, but bear with me) then you can do two things:
set the position of the light to that of the sphere THEN call glTranslate/rotate/etc, (then draw the sphere)
or:
call glTranslate/loadmatrix/etc then set the position of the light to 0,0,0. (then draw the sphere)

(this also applies to direction of spot lights)

This would have the same effect either way.

(I'm assuming here the glTranslate/loadmatrix/etc calls move from 0,0,0 as it would be seen from the camera, which would be normal in most engines anyway)...

Note that if you did set the light position just after a call to glLoadIdentity, you'd need to work out where the light is realtive to the camerea's position and direction, which you most definitly don't want to be doing (this is the reason why GL will mutltiply the position for you).


Also, be careful when using glPush/pop matrix and lights...
drawing multiple objects like this (ie, set light, push, translate, draw, pop, repeat) is ok, but it's best to reset every light every time. Nvidia cards seem to handle this ok if you only change lights that have changed (ie, enabled/disabled) but some other cards have issues.


Just realise that having a light enabled is almost as expensive as drawing the trinagles again... for each light, so make SURE you only enable lights that will actually have an effect on what your drawing. (not as easy as you might think)


good luck


<-- smile :-)

Project-X

[edited by - RipTorn on November 4, 2002 1:38:26 AM]
Lots of good advices there.

Though, I'd add two things :

- GL_LIGHT_MODEL_LOCAL_VIEWER is not necessarily slower if specular color is black and if the driver/hardware knows that. Anyway, if specular is black, it's nonsense to setup light model local viewer !

- In order to setup lights correctly, the typical rendering function may look like that :

1- clear the buffer (eg glClear)
2- setup the camera (eg glLoadIdentity and gluLookAt)
3- setup light positions (call glLight with GL_POSITION for each light, and glLight with GL_SPOT_DIRECTION if needed)
4- render the models
5- flush the buffer (eg glFlush and glutPostRedisplay)

It's very important to know why camera is setup first, then lights, then models. If you understand that, you can easily extend this algorithm to more advanced algorithms like render-to-texture or reflections (or even both simultaneously )

[edited by - vincoof on February 3, 2003 6:42:46 PM]
the point I also made was that some gl drivers don''t save lighting information correctly when going through push/poping of the view matrix... nVidia drivers do this right, and so do current ati driver (I think) but I have seen it done wrong, and can have some pretty ugly effects.
Basically, it''s a good idea to set every lights position before drawing each object.. although this will incur a small performance penalty, it will save potentially aweful lighting errors (think lights that come from completly the worng direction, etc).

Thats one thing nehe really lacks is a really good lighting setup and use tutorial.

| - Project-X - my mega project.. yup, still cracking along - | - adDeath - an ad blocker I made - | - email me - |

This topic is closed to new replies.

Advertisement