# Terrain Lighting Problems

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

## Recommended Posts

Hello, In my current project I am generating terrain from a greyscale heightmap but I am currently running into some problems while trying to implement lighting. Now, without having to dump all of my code to you I was hoping to post a screenshot and get some feedback on what might be going wrong. I know this may be a bit naive, so if the screenshot doesn't immediately ring some bells for anyone I will post the relevent code I have for calculating the face normals, normalizing them, then from the normalized face normals calculating the vertex normals, and from there rendering each vertex with the predetermined vertex normal. As you can see I am getting a somewhat striped effect, on top of the fact that it doesn't really seem like the terrian is correctly lit anyhow. Anyway, thank you for your help in advance, and as I said I will post the relevent code later if need be but I am hoping someone may have experienced my problem and will be able to give me some insight simply from viewing the screenshot.

##### Share on other sites
well yes, post your code so that we know how you are calculating your normals.

if you want to verify them, just draw them as lines from the vertex where the are to the vertex plus its normal.

##### Share on other sites
Hey,

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] = currentNormal;				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 on other sites
In your first code snippet, where you calculate the surface normals, I understand your first surface normal like that:
  2  |  |  |  1------3

which means height1 from point 1, height2 from point 2 and height3 from point 3.
This matches your vec1 which is [0.f, height2 - height1, 1.f] and your vec2 which is [1.f, height3 - height1, 0.f].
Then you exchange height1 and height3 and read in a new value for height3, which yields this picture in my mind:
  2------3         |         |         |         1

and the vectors you make out of this:
vec1 = [0.f, height2 - height1, 1.f]
vec2 = [1.f, height3 - height1, 0.f]
which I think is wrong.
In my oppinion it should be something like this:
vec1 = [0.f, height1 - height3, -1.f]
vec2 = [-1.f, height2 - height3, 0.f]

Don´t know if that fixes your artifacts, but could be, so I´d try it out.
Perhaps I completely misunderstood your data array structure, then just ignore my post. ;)

Good luck!

##### Share on other sites
It appears you need to smooth out your height values aswell...transitions look very rough. Smooth them out after loading them from the height map.

##### Share on other sites
To be true, without looking at your code, are you sure that the problem is with your normals?

The stripped effect does not occur on the slopes and it doesn't seem to have any other anomally so I'd guess that there's something in your height map or in the way it is loaded to your structure (that you then use)...

Or if it's a normal problm then another thing that troubles me is that if this happens every other row (one row has light and the other has darkness) then are your sure that all your normals are facing upwards? (trust me it's the easiest mistake to make)

I think that one these 2 issues might be causing your problem.

1. 1
Rutin
40
2. 2
3. 3
4. 4
5. 5

• 18
• 20
• 13
• 14
• 9
• ### Forum Statistics

• Total Topics
633365
• Total Posts
3011520
• ### Who's Online (See full list)

There are no registered users currently online

×