Lighting

Started by
2 comments, last by Isolier 18 years, 8 months ago
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.
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
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.
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.

This topic is closed to new replies.

Advertisement