Project assassinated by normals _

Started by
3 comments, last by Mushu 18 years, 9 months ago
Okay, so I've got a heightmap yadda yadda, and I've been trying all day to get the bloody normal generations to work. I'm not doing anything fancy - just trying to calculate normals per surface (triangle primitives) and everything goes bonkers: The problem is the normals are ending up skewed for one reason or another, and I can't seem to figure out for the life of me why. The dark patches are areas that the normals are pointing away from the light (they aren't culled or anything). All the vertices are ordered clock-wise properly. All the vector math is hand-coded and checked. Here's the code in question, since there's no way you'll be able to work anything out without it:
for (int ix = 0; ix != x; ix++) {
	for (int iz = 0; iz != z; iz++) {
		{
		cVector v[3];
		v[0].set( ix   *w+xOff,func->call(ix,  iz)  +yOff, iz   *h+zOff);
		v[1].set((ix+1)*w+xOff,func->call(ix+1,iz)  +yOff, iz   *h+zOff);
		v[2].set( ix   *w+xOff,func->call(ix,  iz+1)+yOff,(iz+1)*h+zOff);

		cVector v01 = v[0] - v[1];
		cVector v02 = v[1] - v[2];

		cVector vn;
		vn.p_x = v01.p_y * v02.p_z - v01.p_z * v02.p_y;
		vn.p_y = v01.p_z * v02.p_x - v01.p_x * v02.p_z;
		vn.p_z = v01.p_x * v02.p_y - v01.p_y * v02.p_x;

		float L = sqrtf(vn.p_x*vn.p_x + vn.p_y*vn.p_y + vn.p_z*vn.p_z);
		vn.p_x /= L;
		vn.p_y /= L;
		vn.p_z /= L;

		glNormal3f(v01.p_x,v01.p_y,v01.p_z);
		glTexCoord2f(0,0); glVertex3f(v[0].p_x,v[0].p_y,v[0].p_z);
		glTexCoord2f(1,0); glVertex3f(v[1].p_x,v[1].p_y,v[1].p_z);
		glTexCoord2f(0,1); glVertex3f(v[2].p_x,v[2].p_y,v[2].p_z);
		}
				
		{
		cVector v[3];
		v[0].set((ix+1)*w+xOff,func->call(ix+1,iz)  +yOff, iz   *h+zOff);
		v[1].set((ix+1)*w+xOff,func->call(ix+1,iz+1)+yOff,(iz+1)*h+zOff);
		v[2].set( ix   *w+xOff,func->call(ix,  iz+1)+yOff,(iz+1)*h+zOff);

		cVector v01 = v[0] - v[1];
		cVector v02 = v[1] - v[2];

		cVector vn;
		vn.p_x = v01.p_y * v02.p_z - v01.p_z * v02.p_y;
		vn.p_y = v01.p_z * v02.p_x - v01.p_x * v02.p_z;
		vn.p_z = v01.p_x * v02.p_y - v01.p_y * v02.p_x;

		float L = sqrtf(vn.p_x*vn.p_x + vn.p_y*vn.p_y + vn.p_z*vn.p_z);
		vn.p_x /= L;
		vn.p_y /= L;
		vn.p_z /= L;

		glNormal3f(v01.p_x,v01.p_y,v01.p_z);
		glTexCoord2f(1,0); glVertex3f(v[0].p_x,v[0].p_y,v[0].p_z);
		glTexCoord2f(1,1); glVertex3f(v[1].p_x,v[1].p_y,v[1].p_z);
		glTexCoord2f(0,1); glVertex3f(v[2].p_x,v[2].p_y,v[2].p_z);
				
		}
	}
}
We can assume that the coordinates generated are correct, since the terrain renders correctly (superimposed sinusoidal waves). The problem lies in the normal calculations, somewhere. If there's anything else that you need to help me, just ask and I'll post it up. No point in me posting up everything, as this (it seems to me) is the only relevant code. Thanks [sad]
Advertisement
shouldnt glNormal3f() take vn and not v01?
if not try to draw the normals with glBegin(GL_LINES) or something to see if they seem to point in the right direction
It looks like only half of the triangles is facing the wrong way... try flipping half of them. (i.e. float L = -1.0f * sqrtf... in one of the two "chunks" of code).

Did that do anything?
Quote:Original post by Erik Rufelt
shouldnt glNormal3f() take vn and not v01?
if not try to draw the normals with glBegin(GL_LINES) or something to see if they seem to point in the right direction

I am a total retard! Unsuprisingly, that solved all of my problems. Thanks [grin]

For the record, it was like that because all of the vector operations were being done by cVector member functions, so the original code was v01.cross(v02), so it made sense then. Guess I forgot about it >_<
Here's a big rate++ for you guys :D
Quote:Original post by Kurioes
It looks like only half of the triangles is facing the wrong way... try flipping half of them. (i.e. float L = -1.0f * sqrtf... in one of the two "chunks" of code).

Did that do anything?

Yeah, I originally thought that too. But in reality, they were all facing the wrong way, just some of them were facing the opposite direction of the "wrong" way.

Just another lesson that the wrong wrong way is not necessarily the right way ;)

This topic is closed to new replies.

Advertisement