How to simulate sunlight on terrain?

HELP! I’ve used OpenGL to create a textured terrain/landscape viewer. Some of the triangular polygons are “sloped” - i.e., not all of the 3 vertices have the same Y coordinate - as opposed to “flat” terrain polygons whose vertices all have the same Y elevation. I would like to create spome visual cues to help distinguish between “flat” vs “sloped” polygons by simulating the effect of sunlight in the real world, where an object’s brightness is determined by the angle of the light rays - and thus the amount - of sunlight it receives. From the reading I’ve done, it seems that OpenGL’s DIFFUSE lighting may (??) be the answer, since supposedly it is directional and the light rays are considered parallel, i.e., received by all the polygons as if from a distant source. I’ve set up OpenGL lighting in my app but so far the results have been very disappointing: there’s been no discernable difference in the final rendering. Are there some special steps necessary to integrate lighting effects with textured polygons? Any help (links, code snippets, tutorials…) on this topic would be greatly appreciated. Thanks.

Hi,

You also have to specify normals for you vertice. If you already have, and your lighting setup is correct too, then perhaps you have a wrong texture enviroment. Try setting it to GL_MODULATE, using glTexEnvi.

To make all light rays parallel, you have to set the w-coordinate of the light position to 0.

-Ilkka

I just calculate the lighting manually, simulating a directional light (which OpenGL doesn’t appear to natively support). Take the dot3 product of the normal and the light direction and apply the result to the vertex colour.

Yes it does support directional lights. Like I said, just set the light’s w-coordinate to zero. That’s the fourth coordinate you pass to glLightfv. That’ll make the light infinitely far, which is the same as directional.

-Ilkka

Ah. . . I had not known that. . . (and had not seen your post before I made my reply).

Ilkka:

Thanks for the reply. Changing glTexEnvi from GL_DECAL to GL_MODULATE totally messed up the polygon textures even before I enabled LIGHTING. I’ve decided not to waste any more time pursuing this, OpenGL’s lighting model with its countless functions, arguments and parameters is beyond comprehension to me

Originally posted by JustHanging:

Try setting it to GL_MODULATE, using glTexEnvi.
-Ilkka

Thanks for the reply. Changing glTexEnvi from GL_DECAL to GL_MODULATE totally messed up the polygon textures even before I enabled LIGHTING.

GL_MODULATE tells OpenGL to take the interpolated per-vertex color and multiply it by the texture color. If you didn’t pass one, then yes, your textures are going to be broken.

Now, lighting happens, using the standard GL lighting model, via per-vertex colors. The light has a color, and the surface (material) has a color. OpenGL multiplies these two colors together (based on the surface normal and direction/position of the light) and this becomes the per-vertex color.

You can set OpenGL up to take the surface material color from the glColor3* function, rather than as a glMaterial* parameter. This involves the glColorMaterial function and glEnable-ing GL_COLOR_MATERIAL. It’s really quite simple.

I’ve decided not to waste any more time pursuing this, OpenGL’s lighting model with its countless functions, arguments and parameters is beyond comprehension to me

Are you planning on giving up 3D graphics? Because you’re not going to find a simpler lighting model. 3D graphics is not trivial; it’s going to require some effort.

Admittedly, some pieces of the API (mainly where the material color comes from) could be better, but it’s about where it should be to do what needs to be done. It’s not even that complicated of a lighting model; you simply need to understand what the pieces mean.

OpenGl lighting is not that bad, just start small. Setup one light and see what happens. To start the only really important functions are:

glEnable( GL_LIGHTING );
glEnable( GL_LIGHT0 ) ;
glLightfv( GL_LIGHT0, GL_POSITION, Pos);
glLightfv( GL_LIGHT0, GL_AMBIENT, Ambient);
glLightfv( GL_LIGHT0, GL_DIFFUSE, Diffuse );

Here is a good tutorial explaining the basics of OpenGl Lighting: http://nehe.gamedev.net/data/lessons/lesson.asp?lesson=07

are you setting you triangle normals correctly?

use glNormal3f( nx, ny, nz );

the normal of a triangle can be defined as :
N = (Pb - Pa ) ^ (Pc - Pa )

^ is cross product.
don’t forget to normalize the result.
cb

OpenGL lighting is easy. Stick at it, you’re just at the bottom of thelearning curve and it looks difficult, it is not.

The advice to use GL_MODULATE is correct. The only thing left is to get lighting working.

For lighting to work correctly you need to do the following:

  1. Calculate and send surface normals for each vertex or polygon.

  2. Position and turn on a single light source.

  3. Set up material parameters.

  4. Set up a lighting model

Most of the above parameters begin with default values. The trickiest part is calculating the surface normals, it requires a vertex cross product for each triangle using the triangle edges.

Persevere and we’ll help you over the learning curve.

Look at the bottom of this page “Finding Normals from Polygonal Data”
http://fly.cc.fer.hr/~unreal/theredbook/appendixf.html

This may also help:
http://www.sjbaker.org/steve/omniv/opengl_lighting.html

See, it’s VERY simple.