Advertisement

Weird vertex-normal calculation bug.

Started by October 23, 2004 07:31 AM
1 comment, last by lc_overlord 20 years, 1 month ago
Sorry if this has been posted here alot before, I can't seem to find the problem in my code. Anyways.. on to the problem.. As you can see above the smooth lighting gets calculated incorrectly. The lines in the image point to the direction of the vertex-normals, face normals are calculated correctly. To explain how I calculate the vertex-normal based on which face-normals, I made this map that goes with the sourcecode: Here's the code with documentation:


// Here's the struct I use for storing every "quad" (actually 2
// triangles,.. 4 vertixes, sinc two are always obsolete this way).
struct POLYGON{
	GLfloat Pos[4][3];	// Vertex position 
	CVector3 Light[4];	// smooth Normal for each vertex
	CVector3 nLight[2];	// face Normal for each triangle
	GLfloat Text[4][2];	// Texture coordinats for each vertex
};

POLYGON NewMap[1024][1024];

void RAWTERRAIN::CalculateSmoothLighting()
{
	int Xrender, Zrender;

	// Calculate Smooth Lighting
	// X side
	Xrender = 0;
	while (Xrender < LvlMem.MapSize)
	{

		// Z side
		Zrender = 0;
		while (Zrender < LvlMem.MapSize)
		{
			int setPos[18];
			
			// Set Array positions, left setPos = x, right setPos = z. 
			setPos[0] = Xrender - 1; setPos[9]  = Zrender - 1;	// A - Left   Top
			setPos[1] = Xrender    ; setPos[10] = Zrender - 1;	// B - Center Top
			setPos[2] = Xrender + 1; setPos[11] = Zrender - 1;	// C - Right  Top
			setPos[3] = Xrender - 1; setPos[12] = Zrender;		// D - Left   Middle
			setPos[4] = Xrender    ; setPos[13] = Zrender;		// E - Center Middle
			setPos[5] = Xrender + 1; setPos[14] = Zrender;		// F - Right  Middle
			setPos[6] = Xrender - 1; setPos[15] = Zrender + 1;	// G - Left   Bottom
			setPos[7] = Xrender    ; setPos[16] = Zrender + 1;	// H - Center Bottom
			setPos[ 8]= Xrender + 1; setPos[17] = Zrender + 1;	// I - Right  Bottom

			// Check to see if we go out of our array.
			for (int counter = 0; counter < 16; counter++)
			{
				// Smaller than zero, go to the end of the array.
				if (setPos[counter] < 0) setPos[counter] += LvlMem.MapSize;
				// Bigger than the array, go to the start of it.
				else if (setPos[counter] >= LvlMem.MapSize) setPos[counter] -= LvlMem.MapSize;
			}


			// Corner 1
            		NewMap[Xrender][Zrender].Light[0] = (
					NewMap[ setPos[0] ][ setPos[9] ].nLight[1] +	// A o
					NewMap[ setPos[1] ][ setPos[10]].nLight[0] +	// B
					NewMap[ setPos[1] ][ setPos[10]].nLight[1] +	// B o
					NewMap[ setPos[3] ][ setPos[12]].nLight[0] +	// D
					NewMap[ setPos[3] ][ setPos[12]].nLight[1] +	// D o
					NewMap[ setPos[4] ][ setPos[13]].nLight[0])/6;	// E
			// Corner 2
			NewMap[Xrender][Zrender].Light[1] = (
					NewMap[ setPos[1] ][ setPos[10]].nLight[1] +	// B o
					NewMap[ setPos[2] ][ setPos[11]].nLight[0] +	// C
					NewMap[ setPos[2] ][ setPos[11]].nLight[1] +	// C o
					NewMap[ setPos[4] ][ setPos[13]].nLight[1] +	// E o
					NewMap[ setPos[4] ][ setPos[13]].nLight[0] +	// E
					NewMap[ setPos[5] ][ setPos[14]].nLight[0])/6;	// F
			 // Corner 3
			 NewMap[Xrender][Zrender].Light[2] = (
					NewMap[ setPos[3] ][ setPos[12]].nLight[1] +	// D o
					NewMap[ setPos[4] ][ setPos[13]].nLight[1] +	// E o
					NewMap[ setPos[4] ][ setPos[13]].nLight[0] +	// E
					NewMap[ setPos[6] ][ setPos[15]].nLight[0] +	// G
					NewMap[ setPos[6] ][ setPos[15]].nLight[1] +	// G o
					NewMap[ setPos[7] ][ setPos[16]].nLight[0])/6;	// H

			// Corner 4
			NewMap[Xrender][Zrender].Light[3] = (
					NewMap[ setPos[4] ][ setPos[13]].nLight[1] +	// E o
					NewMap[ setPos[5] ][ setPos[14]].nLight[0] +	// F
					NewMap[ setPos[5] ][ setPos[14]].nLight[1] +	// F o
					NewMap[ setPos[7] ][ setPos[16]].nLight[0] +	// H
					NewMap[ setPos[7] ][ setPos[16]].nLight[1] +	// H o
					NewMap[ setPos[ 8]][ setPos[17]].nLight[0])/6;	// I
					
			 // All corners calculated
			Zrender++;
		}
		Xrender++;
	}
	// Done
	dbg.report(' ' , 0 , 0 , "RawTerrain: Smooth lighting calculated.");
}


I have no idea whats wrong with it, for each vertex I calculate 6 face-normal's ( there are only 6 connecting faces per vertex ). I would really appreciate it if someone finds the mistake I made, thanks in advance for your time!!
I sugest you read this thread as it show another much better (faster and more corect) way of calculation normals for terrains.
You should never let your fears become the boundaries of your dreams.
Advertisement
Here's a tip.

Don't divide the normals with 6 after adding them together, instead normalise them, it will yeald a better result.
You could allso share the normal with the vertics that share the same coords to insure that you get the same normal.

and then theres allways the option of using a normal map.

This topic is closed to new replies.

Advertisement