Lighting problem

Started by
3 comments, last by isenthalpic53 15 years, 5 months ago
Hi i seem to be having a positional light problem when it is hitting the surface of my ground. I have created a texture loader and then used that to create a heightmap which looks greate when using a directional light but for some reason when i use this positional light i get a jagged edge to it between the light and dark areas(this is more clear in the screen shot below). Any ideas please? screen shot http://img291.imageshack.us/my.php?image=screemshotbv4.jpg Here's where i set up my light

//init
glEnable(GL_DEPTH_TEST);
glEnable(GL_LIGHTING);
glEnable(GL_NORMALIZE);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

GLfloat lightPosition2[] = {0,0,0,1};
GLfloat spot_direction[] = {0,0,1};

glLightf(GL_LIGHT1, GL_SPOT_CUTOFF, 35.0);
glLightfv(GL_LIGHT1, GL_SPOT_DIRECTION, spot_direction);

glLightf(GL_LIGHT1, GL_CONSTANT_ATTENUATION, 0.5);
glLightf(GL_LIGHT1, GL_LINEAR_ATTENUATION, 0.0);
glLightf(GL_LIGHT1, GL_QUADRATIC_ATTENUATION, 0.0);

glLightfv(GL_LIGHT1, GL_AMBIENT, ambientLight2);
glLightfv(GL_LIGHT1, GL_DIFFUSE, diffuseLight2);
glLightfv(GL_LIGHT1, GL_SPECULAR, specularLight2);
glLightfv(GL_LIGHT1, GL_POSITION, lightPosition2);

glEnable(GL_LIGHT1);

Heres where i create the normals for my ground, which basically collect all the vertex around the current and then takes a weighted average of them.

	
for(int z = 0; z < length; z++) 
{
   for(int x = 0; x < width; x++) 
   {
   Vec sum(0.0f, 0.0f, 0.0f);
   Vec back;

   //Collects vectors around current
   if (z > 0) //Checks to see if its on the edge
   {
      back = Vec(0.0f, hs[z - 1][x] - hs[z][x], -1.0f);
   }
   Vec front;

   if (z < length - 1) //Checks to see if its on the edge
   {
      front = Vec(0.0f, hs[z + 1][x] - hs[z][x], 1.0f);
   }
   Vec left;

   if (x > 0) //Checks to see if its on the edge
   {
      left = Vec(-1.0f, hs[z][x - 1] - hs[z][x], 0.0f);
   }
   Vec right;

   if (x < width - 1) //Checks to see if its on the edge
   {
       right = Vec(1.0f, hs[z][x + 1] - hs[z][x], 0.0f);
   }

   //Takes cross product of vectors
   if (x > 0 && z > 0) 
   {
      sum += back.cross(left);
   }

   if (x > 0 && z < length - 1) 
   {
      sum += left.cross(front);
   }

   if (x < width - 1 && z < length - 1) 
   {
      sum += front.cross(right);
   }

   if (x < width - 1 && z > 0) 
   {
      sum += right.cross(back);
   }
					
   //Places vectors into normals array
   normals[z][x] = sum;
   }
}	

Many Thanks
Advertisement
Hello,

You are probably using gouraud shading (OpenGL default?) - In each triangle, the brightness of each vertex is interpolated accross the surface. With a spotlight, there will be some triangles where one vertex is in shadow and the others are in light (or vice versa). In these cases you'll get a very steep interpolation between the dark vertices and light vertices which will give you that step effect. Google Gouraud shading, for more info.

There are various things that can be done to avoid this.
1) Subdivide your triangles. You will still have the same problem but because the triangles are smaller, you won't notice so much. This is a VERY BAD idea for a real time game as it will slow everything down by a significant amount.
2) Use lightmaps. This is a great technique and worth looking at, there are plenty of tutorials on it.
3) Use shaders and perform 'per-pixel' lighting. Again, plenty of tutorials on this.

Good luck!

Hugh
--------------------------------www.hughosborne.co.uk[email=hugh.osborne@googlemail.com]hugh.osborne@googlemail.com[/email]
It seems you aren't re-normalizing the summed vector that is to be your normal. It also seems suspicious that you must recompute the triangle normals within the vertex normal computation code (don't you already store the triangle normals for other uses?)
Thanks for your replies, I have looked at lightmaps and dont think it would be useful for what im trying to do? I have a terrain which i can drive around on in my car and attached to the car is a spotlight (headlights) and from what i can see about lightmaps they are static?

As for per-pixel shading do you know any good (easy-ish) tutorials?

and also are there no other ways round this problem?

Again many thanks.
yeah, lightmaps are for static lighting of an environment (although doesn't quake 2 basically do a dynamic lightmap for like the default blaster gun thing and such?)

I believe you can have the world lit by a static lightmap and still have your headlights apply added lighting.

You can also look into shaders and build a 'real' lighting model rather than doing GL's built in lighting and lighting hacks (light mapping is basically considered a lighting hack).

This topic is closed to new replies.

Advertisement