Advertisement

Lighting

Started by December 22, 2004 11:37 AM
9 comments, last by GameDev.net 19 years, 8 months ago
Hello all, i've run into some problems setting up my lighting. I'm trying to set up 1 infinite light source that will illuminate my entire world (it's a map-like world, based on tiles). But I can't get it to work... Everything I find online refers to setting the light_position to 1,1,0 but I guess I need to do more, just can't find out what. I just want some sort of sunlightsource Any help would be appreciated ( I've been gone a loooooong time I know :$ )
could you post some code?

Anyway, if you want a global illumination, you should set up your ambient light. Put this code in your init function:

GLfloat Ambient_Color[] = {0.5F,0.5F,0.5F,1.0F}; GLfloat Light_Position[] = {0.0F,0.0F,0.0F,0.0F}; // centered on originglLightfv(GL_LIGHT0,GL_AMBIENT,Ambient_Color); glLightfv(GL_LIGHT0,GL_POSITION,Light_Position); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); 


then, if you want to put some point lights, try to set up a diffuse light source (GL_DIFFUSE)

merry xmas ^__^
Advertisement
okie...

When you set a light, it's JUST like using glVertex to plot a vertex. The positions/direction you specify will be tranformed by the modelview matrix, etc.

So.. to understand what makes an infinite light, you need to understand projection in openGL (and d3d, etc)

- bear with me, I do have a point here...

When the vertex is passed in, say, {3,2,4}, it will actually be passed in as {3,2,4,1}. If you use glVertex4f, you can specify what the last value is.
After the vertex has been transformed, openGL will divide {x,y,z} by that last number (w). So, if the projection matrix is identiy, the number won't change. it will come out as 1. so there will be no division, and therefore no projection. But with a projection matrix, the w coord will end up roughly representing how far the vertex is from the camera. So, if it's far away, and, say, w ends up as 10, then xyz is divided by 10. So the object is around 10 times smaller on screen. Ie, things get smaller as they get further away.

This is where the trick comes in.
If you were to do: glVertex4f(3,2,4,0);, then no matter how much w is scaled, it will always be 0. So openGL will divide {3,2,4} by 0...
Now, you may think "hang on, divide by zero is bad." - well, yes, it is.. but it's part of the openGL/d3d compliance spec that when that happens, the values become 'infinite'.. but not infinite in a floating point sense, more {3*infinity, 2*infinity, 4*infinity} sense. So the vertex gets plotted at infinity, but in the direction {3,2,4}.

So.. how does this effect lighting?

well, thats the thing. you either want a point source, local light, or an infinite directional light...

So by the same logic as above, all thats required to do that is:

float[] light_pos = {3,2,4,1}; // local point light

... or ...

float[] light_pos = {3,2,4,0}; // infinite light


Just make sure you actually set the light position at the right time (remember, as I said, it's treated just like a vertex, so set it just after you setup your camera)

ok? [smile]

check out the code example in my sig too.
Hi guys. Thanks for the replies. Unfortunately, Riptorn, I didn't see any difference in my results. Below is my rendering function:

void RenderGl(void){	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);	glLoadIdentity();	gluLookAt(Camera.Position.x, Camera.Position.y, Camera.Position.z, 				Camera.Lookat.x, Camera.Lookat.y, Camera.Lookat.z, 				Camera.Rotation.x, Camera.Rotation.y, Camera.Rotation.z		);	GLfloat LightPosition[]= { 1.0f, 1.0f, 0.0f, 0.0f };	glLightfv(GL_LIGHT0, GL_POSITION, LightPosition);	RenderMap();}


B3rs3rk, I'm not looking for a global ambient lighting though I do have it a little ( 0.3f ) but I need "normal" lighting aswell for shades etc.

The "map" I render remains dark (only the ambient lighting shows) with w set to zero.

What did I do wrong?
Did you setup diffuse and specular components for your light ?
SaM3d!, a cross-platform API for 3d based on SDL and OpenGL.The trouble is that things never get better, they just stay the same, only more so. -- (Terry Pratchett, Eric)
Yep

I based my settings roughly on this information:
http://sjbaker.org/steve/omniv/opengl_lighting.html

I initialise openGL with the following code:
bool InitOpengl(void){	glShadeModel(GL_SMOOTH);	glClearColor(0.0f, 0.0f, 0.25f, 0.0f);	glClearDepth(1.0f);	glEnable(GL_DEPTH_TEST);	glDepthFunc(GL_LEQUAL);	glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);	glEnable(GL_LIGHTING);	glEnable(GL_LIGHT0);	GLfloat LightAmbient[] = { 0.3f, 0.3f, 0.3f, 1.0f };	GLfloat LightDiffuse[] = { 1.0f, 1.0f, 1.0f, 1.0f };	GLfloat LightSpecular[]= { 1.0f, 1.0f, 1.0f, 1.0f };	GLfloat LightPosition[]= { 1.0f, 1.0f, 0.0f, 0.0f };	glLightfv(GL_LIGHT0, GL_AMBIENT,  LightAmbient);		glLightfv(GL_LIGHT0, GL_DIFFUSE,  LightDiffuse);		glLightfv(GL_LIGHT0, GL_SPECULAR, LightSpecular);		glLightfv(GL_LIGHT0, GL_POSITION, LightPosition);	GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 };	GLfloat mat_shininess[] = { 50.0 };	glEnable(GL_COLOR_MATERIAL);    glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);    glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);	glEnable(GL_TEXTURE_2D);	LoadGLTexturesRecursive("data/textures/");	return true;}


You gurus can probably write it a lot cleaner but I'm not that experienced yet..
Advertisement
I don't know if it'll make a difference, but perhaps you should enable GL_LIGHTING and GL_LIGHT0 after declaring all the Light arrays
if you want shades and normals you should add smooth normals. Basically, you must set up a normal for every face of the models you render, for example:

glBegin(GL_TRIANGLE_STRIP);glNormal3f(0,1,0); // this is a normal vector pointing "up" on the y coordglVertex3f(-5.0f, -4, 0.0f);glVertex3f(2.0f, -4, 0.0f);glVertex3f(-5.0f, 4, 0.0f);glVertex3f(2.0f, 4, 0.0f);glEnd();


with a single quad (like in this case) you'll see nothing, but try to render a complex model and see the results :)

take a look at this tutorial:
http://www.firestorm.go.ro/Tutorial3.htm
is this what are you looking for?

anyway, could you post a screenshot?
OMG that's right. I forgot all about the normals... STUPID! That's what happens if you stop coding opengl for a year or so...


You can override the default global scene lighting in yopur init() function , which is set to .2f automatically , with :

GLfloat global_ambient[] = { 0.4f, 0.4f, 0.4f, 1.0f };
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, global_ambient);



Don't set it higher than .4f or .5f or it will tend to flood the entire scene and nullify your individual lights which you may have set up on other objects ... the soft color tone differences obtained thru individual lights will be gone.


Likewise, when you illuminate objects, leave out the ambient[] properties, since that also tends to wash out, with too much light, your 3d objects.

For individual lights placed about the scene, you can consider doing something like the following, in your init() function :


GLfloat lightSpecular[4] = { 0.01f, 0.01f, 0.01f, 0.3f } ; // Light 0 specular properties
GLfloat lightDiffuse[4] = { 0.5f, 0.5f, 0.5f, 0.5f } ; // Light 0 diffuse properties
glLightfv(GL_LIGHT0, GL_DIFFUSE, lightDiffuse);
glLightfv(GL_LIGHT0, GL_SPECULAR, lightSpecular);



Enable/disable lighting in your renderScene() function as needed.


This topic is closed to new replies.

Advertisement