Jump to content
  • Advertisement
Sign in to follow this  
Isolier

Lighting

This topic is 4830 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hello, I seem to be having trouble with lighting in my current project which creates terrain from a heightmap. The problem seems to be with directional lights. When I set up a directional light, the entire world is lit as if I was only using ambient light, so I am getting a 2d looking landscape basically, because there is no shading done along the hills or anything. However, when I use a positional light, things seem to work correctly as the 3d terrain appears to be correctly lit along the hills and valleys and such. I am simply using:
float[] diffuseLight = {0.5f, 0.5f, 0.5f, 1.0f};
float[] lightPos    = {0.0f, 1.0f, 0.0f, 0.0f};
nomalizeVector(lightPos);
glLightfv(GL_LIGHT0, GL_POSITION, lightPos);
glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuseLight);


I am fairly sure my normals are calculated correctly else the positional light wouldn't work I am assuming. Does anyone know what is wrong? Am I setting up the directional light incorrectly? Thanks in advance.

Share this post


Link to post
Share on other sites
Advertisement
1. u use glLightfv to assign the values, so you have to assign a pointer. I don't know whether it is just one, in delphi you have to place an @ before the variable or constant, I don't know which language u use, maybe there's a similar way.
2. your light position describes a direction exactly to -y. this may look a little bit strange because all "walls" will get darken. Ambient light is just a value which is added to every calculation, it doesn't depend on normals. However - you won't get happy with wierd looking standard opengl lighting, so you should learn how to use GLSL, too

greets KyRo1989

Share this post


Link to post
Share on other sites
That piece of code seems alright, (except the normalizeVector(lightPos); the vector is obviously unit-length from before...)
Post some more relevant code, i.e. the rest of the lighting setup, (I don't see glEnable(GL_LIGHTING) in there, for example), and also the code that you use to calculate the normals.

Share this post


Link to post
Share on other sites
Hey,

The lighting appears to work somewhat correctly now, the problem was I wasn't storing the calculated vertex normals correctly(somewhat of a "Javaism" if you will). However, there may be some inacuracy in the normal calculations as the terrain appears to be somewhat bumpy. Here is a screenshot so you can see what I mean.

Also, I noticed that I am getting negative numbers in my normals x and z values, is this correct or shouldn't the normal's x, y and z values always be positive?

Well, the surface normal calculation is as such:
int surfaceNormalsIndex = 0;
for(int y = -1; y <= mapLength - 1; y++)
{

float height1, height2, height3;
for(int x = -1; x <= mapWidth - 1; x++)
{
if(x == -1 || x == mapWidth - 1 || y == -1 || y == mapLength -1)
{
surfaceNormals[surfaceNormalsIndex++] = new float[]{0.0f, 1.0f, 0.0f};
surfaceNormals[surfaceNormalsIndex++] = new float[]{0.0f, 1.0f, 0.0f};
}
else
{
height1 = heightBuffer[(y*mapWidth)+x];
height2 = heightBuffer[((y+1)*mapWidth)+x];
height3 = heightBuffer[(y*mapWidth)+x+1];

float[] vec1 = {0.0f, height2 - height1, 1.0f};
float[] vec2 = {1.0f, height3 - height1, 0.0f};

surfaceNormals[surfaceNormalsIndex++] = GameUtil.crossProduct(vec1, vec2);

height1 = height3;
height3 = heightBuffer[((y+1)*mapWidth)+x+1];

vec1[1] = height2 - height1;
vec2[1] = height3 - height1;

surfaceNormals[surfaceNormalsIndex++] = GameUtil.crossProduct(vec1, vec2);
}
}
}




I then normalize them with:

for(int i = 0; i < surfaceNormals.length; i++)
{
GameUtil.nomalizeVector(surfaceNormals);
}




And finally I calculate the vertex normals with:


int triRowOffset = ((mapWidth+1)*2)-1;
int triIndex = 1;
int vertexIndex = 0;
float[] currentNormal = new float[3];
float[][] tempVec = new float[6][3];
for(int z = 0; z < mapLength; z++)
{
for(int x = 0; x < mapWidth; x++)
{
tempVec[0] = surfaceNormals[triIndex];
tempVec[1] = surfaceNormals[triIndex + 1];
tempVec[2] = surfaceNormals[triIndex + 2];
tempVec[3] = surfaceNormals[triRowOffset + triIndex];
tempVec[4] = surfaceNormals[triRowOffset + triIndex + 1];
tempVec[5] = surfaceNormals[triRowOffset + triIndex + 2];

currentNormal[0] = (tempVec[0][0] + tempVec[1][0] + tempVec[2][0] + tempVec[3][0] + tempVec[4][0] + tempVec[5][0]) / 6.0f;
currentNormal[1] = (tempVec[0][1] + tempVec[1][1] + tempVec[2][1] + tempVec[3][1] + tempVec[4][1] + tempVec[5][1]) / 6.0f;
currentNormal[2] = (tempVec[0][2] + tempVec[1][2] + tempVec[2][2] + tempVec[3][2] + tempVec[4][2] + tempVec[5][2]) / 6.0f;

vertexNormals[vertexIndex][0] = currentNormal[0];
vertexNormals[vertexIndex][1] = currentNormal[1];
vertexNormals[vertexIndex][2] = currentNormal[2];

triIndex +=2;
vertexIndex++;
}
triIndex += 2;
}




So there you have it, sorry to bombard you with so much code. I have verified my little helper methods, crossProduct() and normalizeVector(), so I know those aren't miscalculating antyhing. You may(or may not) notice that it is Java... Thanks again.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!