Jump to content
  • Advertisement
Sign in to follow this  
Yhonatan

Problem with Normals[solved]

This topic is 3774 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

Hey all, I'm currently working on a 3D tank game and I have a serious problem with the normals. I'm trying to achieve smooth shading (I think that's the way this is called) by summing up all the normals of the faces of some vertex and then avaraging them. Firstly, It didnt work well on the ground, there arent many changes (when changing the position of a light source) but when the light source is below a certrain point(Y axis), that place (the place above it) is blacked out. so It looks like it got some affect on the ground, and i'm not sure what should I do. here are two screen shots the red cross is the place of the light source, and by looking at the tank you can see that this is wrong: http://img89.imageshack.us/img89/4773/normals2nz1.jpg http://img359.imageshack.us/img359/8967/normals1kn9.jpg before explaining what exacly I'm doing this is how i calculate each normal:


void VectorOffset (point *pIn, point *pOffset, point *pOut)
{
   pOut->x = pIn->x - pOffset->x;
   pOut->y = pIn->y - pOffset->y;
   pOut->z = pIn->z - pOffset->z;
}

// Compute the cross product a X b into pOut
void VectorGetNormal (point *a, point *b, point *pOut)
{
   pOut->x = a->y * b->z - a->z * b->y;
   pOut->y = a->z * b->x - a->x * b->z;
   pOut->z = a->x * b->y - a->y * b->x;
}



// Compute p1,p2,p3 face normal into pOut
bool ComputeFaceNormal (point *p1, point *p2, point *p3, point *pOut)
{
   // Uses p2 as a new origin for p1,p3
   point a;
   VectorOffset(p3, p2, &a);
   point b;
   VectorOffset(p1, p2, &b);
   // Compute the cross product a X b to get the face normal
   point pn;
   VectorGetNormal(&a, &b, &pn);

   pOut->x = pn.x;
   pOut->y = pn.y;
   pOut->z = pn.z;
return true;
}







What I'm doing is this: first I calculate all the normals for a certain vertex and I save it with a certain class i've made. After all faces are loaded, i'm chaning all the normals so they'll suit up. (NFV is an object of that class) Numosh is the place of that Vertex's normal (assuming there are 3 vertices, if i want the normal for the vertex in the place 1 Numosh=1)

for (vector <Mesh>::iterator JHJ=Meshes.begin();JHJ!=Meshes.end();JHJ++)
{
	NumTria=0;
	for (vector <Triangle>::iterator Tria = (*JHJ).Triangles.begin();Tria!=(*JHJ).Triangles.end();Tria++)
	{
		for (int i=0;i<3;i++)
		{
			int Numosh = int((*Tria).Normal.x);
	
			point OldVector;
			OldVector.x = float(NFV[Numosh].SumOfAllNormals.x/float(NFV[Numosh].numOfNormals));
			OldVector.y = float(NFV[Numosh].SumOfAllNormals.y/float(NFV[Numosh].numOfNormals));
			OldVector.z = float(NFV[Numosh].SumOfAllNormals.z/float(NFV[Numosh].numOfNormals));
			point NewN, NewN2;
			
		    NewN.x=OldVector.x;
			NewN.y=OldVector.y;
			NewN.z=OldVector.z;
			Meshes[NumMush].Triangles[NumTria].Normal.x=NewN.x;
			Meshes[NumMush].Triangles[NumTria].Normal.y=NewN.y;
			Meshes[NumMush].Triangles[NumTria].Normal.z=NewN.z;
		
		}
		NumTria++;
	}
	NumMush++;
}






Any idea why is this happening this way? Thanks in advance [Edited by - Yhonatan on July 22, 2008 5:00:28 PM]

Share this post


Link to post
Share on other sites
Advertisement
Your normal vectors don't appear to ever be normalized. That could be the problem since OpenGL assumes your normal vectors are normalized.

I also don't see any logic that's accounting for winding (i.e. are your points clockwise or counter-clockwise), though that could be happening naturally assuming a consistent mesh format. Otherwise, you need to guarantee that the normal you generate is pointing "outwards" on the model. Remember that each poly has 2 normals, one facing inside, the other outside.

-me

Share this post


Link to post
Share on other sites
Quote:
Original post by Palidine
Your normal vectors don't appear to ever be normalized. That could be the problem since OpenGL assumes your normal vectors are normalized.

I also don't see any logic that's guaranteeing that your accounting for winding, though that could be happening naturally. Basically you need to guarantee that the normal you generate is pointing "outwards" on the model. Remember that each poly has 2 normals, one facing inside, the other outside.

-me


Hey Palidine,
Thanks for your post.
Every time that I've tried to normalize those vectors it turned out that that they always have "light" upon them, and by changing the light position it doesnt change.
I was trying to normalize them this way:


bool VectorNormalize (point *pIn, point *pOut)
{
GLfloat len = (GLfloat)(sqrt(sqrt(pIn->x) + sqrt(pIn->y) + sqrt(pIn->z)));
if (len)
{
pOut->x = pIn->x / len;
pOut->y = pIn->y / len;
pOut->z = pIn->z / len;
return true;
}
return false;
}





How can I garuntee that the normal is pointing out of the model and not inside?


Thanks in advance

Share this post


Link to post
Share on other sites
That's the wrong math for vector normalization:
http://www.fundza.com/vectors/normalize/index.html

Cross-product is right-hand rule (http://en.wikipedia.org/wiki/Right-hand_rule). Models are typically authored in a specific winding (either clockwise or counter-clockwise). So depending on the winding, you cross either AB x BC or CB x BA to get the vector pointing in/out. A,B,C are the vertices as defined by the order in which they appear in your indices list.

You should add some debug drawing code to draw your actual normal vectors at each vertex to assure yourself that they are being calculated correctly. Once you have that running it's simple trial and error to get the normals correct.

-me

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!