Precaculating face and vertex normals?

Started by
16 comments, last by ByteMe95 23 years, 8 months ago
I''m trying to speed up my 3d demo. I could make it MUUUCH faster by NOT calculating the vertex normals every frame (I know i shouldn''t do it but i wanted my demo to work already and put it aside for now) Anyway, when I load in the asc file I calculate all face normals and vertex normals. Now I figured when i transform my vertices, if I apply the same transformation matrix to my face normals and vertex normals they should be calculated correctly and then I would be able to use them But for some reason that doesnt work. The lighting looks like it''s rotating with the faces (so on a sphere, it would start with the light shining right on it, but as it rotates the light rotates with it like it''s part of the object). I think that''s what was happening when i tried that, I dont really remember. Just wanted to know if that''s the way "it''s done" and if it''s posssible to precomupte everything and then just rotate the normals with everything else Thanks ByteMe95::~ByteMe95()
ByteMe95::~ByteMe95()My S(h)ite
Advertisement
hmm, it should work just fine, calculating the normals all the time can get expensive.

if it looks like the light is being rotated with the object then the problem sounds like when you rotate the object, you aren''t rotating the normals also. that definatly sounds like the problem, you should just be able to apply the exact same transformation to the precalculated normal as its owner then just recalc the lighting each rotation.

i''d have a look at your code that rotates the normal or the code that calculates the lighting each frame if i were you.

-werdup-
-werdup-
quote: Original post by ByteMe95
Anyway, when I load in the asc file I calculate all face normals and vertex normals. Now I figured when i transform my vertices, if I apply the same transformation matrix to my face normals and vertex normals they should be calculated correctly and then I would be able to use them.


Almost... If your transformation is only rotation, it should work. But if it includes translation and scaling, you'll have problems.

To handle translation, simply don't apply it. Remember that your normals are relative offsets, not absolute positions (like your vertices). Being relative, you don't translate them.

Rotate the normals same as you rotate your vertices.

As for scaling, I don't exactly remember. You'll need to look this one up... it's not exactly straightforward if you have non-uniform scaling. Although most people avoid that in their transforms anyhow...

To summarize: you have a matrix M = |Rt| , a vertex v and a normal n . You would do:

          v' = Rv + t  n' = Rn        



---- --- -- -
Blue programmer needs food badly. Blue programmer is about to die!

Edited by - mossmoss on July 24, 2000 12:47:42 PM
I dony have my code on me at the moment, but the transformation goes prettymuch something like this:

    Object3D::ApplyTransformations(){   3DV Temp;   for(int i=0; i<NumVertices; i++)   {      Temp = Vertices<i>;      VEC_MultMatrix(&Temp, TransformMX, &Vertices[i]);           Temp = VNormals[i]; //Vertex normals      VEC_MultMatrix(&Temp, TransformMX, &VNormals[i]);   }   for(i=0; i<NumFaces; i++)   {      Temp = fIndex[i].Normal;  //Face normal      VEC_MultMatrix(&Temp, TransformMX, &fIndex[i].Normal);   }}     


Where Vec.. is defined
void VEC_MultMatrix(3DV *Source, Matrix mx, 3DV *Dest);

I dont think there''s a problem with that function cause it rotates the object just fine.

Any ideas?





ByteMe95::~ByteMe95()
ByteMe95::~ByteMe95()My S(h)ite
well unless i'm mistaken his demo was just something rotating so i knew that's not his problem
i am assuming you're not? what's your code for generating 'TransformMX'?

Edited by - shmaLbus on July 24, 2000 8:27:25 PM
-werdup-
I only call Test.Rotate(1, 2, 3) at initialization, and this is what it calls:

    void Object3D::Rotate(float ax, float ay, float az){	Matrix	xmat, ymat, zmat, mat1, mat2;	IdentityMatrix(mat1);	IdentityMatrix(mat2);	xmat[0][0]=1;        xmat[0][1]=0;        xmat[0][2]=0;        xmat[0][3]=0;	xmat[1][0]=0;        xmat[1][1]=cos(ax);  xmat[1][2]=sin(ax);  xmat[1][3]=0;	xmat[2][0]=0;        xmat[2][1]=-sin(ax); xmat[2][2]=cos(ax);  xmat[2][3]=0;	xmat[3][0]=0;        xmat[3][1]=0;        xmat[3][2]=0;        xmat[3][3]=1;	ymat[0][0]=cos(ay);  ymat[0][1]=0;        ymat[0][2]=-sin(ay); ymat[0][3]=0;	ymat[1][0]=0;        ymat[1][1]=1;        ymat[1][2]=0;        ymat[1][3]=0;	ymat[2][0]=sin(ay);  ymat[2][1]=0;        ymat[2][2]=cos(ay);  ymat[2][3]=0;	ymat[3][0]=0;        ymat[3][1]=0;        ymat[3][2]=0;        ymat[3][3]=1;	zmat[0][0]=cos(az);  zmat[0][1]=sin(az);  zmat[0][2]=0;        zmat[0][3]=0;	zmat[1][0]=-sin(az); zmat[1][1]=cos(az);  zmat[1][2]=0;        zmat[1][3]=0;	zmat[2][0]=0;        zmat[2][1]=0;        zmat[2][2]=1;        zmat[2][3]=0;	zmat[3][0]=0;        zmat[3][1]=0;        zmat[3][2]=0;        zmat[3][3]=1;       	MatrixMult(TransformMX,ymat,mat1);	MatrixMult(mat1,xmat,mat2);	MatrixMult(mat2,zmat,TransformMX);}    


with MatrixMult(mat1, mat2, destination_matrix)

and that''s it
I dont get it, I''ve tried many times. If i take out calculating the vertexnormals my fps goes from 40 to 60
Gotta get it out!!!



ByteMe95::~ByteMe95()
ByteMe95::~ByteMe95()My S(h)ite
quote:

As for scaling, I don't exactly remember. You'll need to look this one up... it's not exactly straightforward if you have non-uniform scaling. Although most people avoid that in their transforms anyhow...




the normals are for the lightning, right?
i though u'd have to give normals with the length of 1?
so, you'd just don't scale your normal either, oder?
I'm still pretty new, but i think i read something like that...

cya,

Phil

Edited by - phueppl1 on July 24, 2000 12:42:41 AM
Visit Rarebyte! and no!, there are NO kangaroos in Austria (I got this question a few times over in the states ;) )
The only transformation I''m doing as of right now is rotation, so scaling and translation have nothing to do with this problem.

I have no idea what the problem is, anyone got a clue?
When I rotate it the lighting doesnt go completely crazy with crazy colors, it still looks like a shaded torus, but the light moves around funny, it doesnt stay in one place like it''s shining at the torus and torus is rotating, like the demo.

In that code snippet of rotating the vertices and vertex normals I also tried to put in VNormals = Normalize(VNormals);<br>That didnt help either<br><br>This thing is driving me nuts, i just want to get it right and be done with it!!<br><br>- ROb </i> <br><br><br><br>ByteMe95::~ByteMe95()
ByteMe95::~ByteMe95()My S(h)ite
Have you tried drawing in the normals every frame to see if they''re rotating correctly?

In fact, this doesn''t sound like a problem with your normals at all, but with your lighting. This is exactly what would happen if you were to prelight your object. Are you sure that the lighting is being recalculated every frame?

One other thing - Have you considered doing your lighting in object space instead of world space? Instead of transforming all of your object normals by the object''s world matrix, you can just transform your lights by the inverse of this matrix. Depending upon the number of lights in your scene, this will probably be much faster.

This topic is closed to new replies.

Advertisement