# Face normals: recalculate each time or rotate?

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

## Recommended Posts

Currently I take the triangle, rotate it, then calculate the face normal from the resulting points. Would it be more sensible calculate the face normals for every triangle as I load the model, then rotate the normal..? I ask only because I've noticed that Milkshape exports these normals - so people must use them for something, and the only reason I can think is as a faster way to calculate the normals when culling triangles and lighting a model (I'm only using flat shaded texture-mapped triangles at the moment).

##### Share on other sites
You can just multiply the rotation matrix with the normals to get the rotated normal. I believe recalculating normals everytime is alot more expensive.

##### Share on other sites
..."just multiply the rotation matrix"...

The what? I have three functions:

point3D rotatePointAboutAxisX(point3D p, double a) { }
point3D rotatePointAboutAxisY(point3D p, double a) { }
point3D rotatePointAboutAxisZ(point3D p, double a) { }

... that make use of sine and cosine to spin the points about the origin. What's a rotation matrix?

##### Share on other sites
there is loads of articles on gdnet on matrix math, if you are serious about 3D programming i suggest you read them and understand them. they are very helpful in many situations.

##### Share on other sites
Well a rotation matrix contains the required information to transform any point. Well Math is not my strong point but what you are using is Euler Angles and im sure you can easily find out how to convert your angles into a rotation matrix.

By calculating your rotation matrix once, you can use it to calculate your new normals.

Also are you using OpenGL/DX? If you are, you need not recalculate the normals for lighting. This is because when you apply the rotation using these api's, the modelview matrix takes into account the rotation when it transforms/lights your triangles.

##### Share on other sites
First of all, what API are you using? Is this OpenGL, Direct3D, or some 3D code you're writing yourself?

Elaborate a bit more so we can help.

##### Share on other sites
Quote:
 Original post by GamerSgYou can just multiply the rotation matrix with the normals to get the rotated normal. I believe recalculating normals everytime is alot more expensive.

Hug?

MxV (9 muls) is faster than U^V (3 muls) ? I'm pretty sure it is not the case :)

Quote:
 Original post by benryves..."just multiply the rotation matrix"...The what?

It seems you need more informations about linear algebra and matrices (+ another reference). Matrices offer you a way to represent linear transformations such as rotations, scaling, translations. There is a small introduction to rotation matrices in the DX SDK help. Diana Gruber write this little piece of informations (it will need some math background). Seumas McNally gave this to gamedev.net.

Regards,

##### Share on other sites
Quote:
 Original post by ProzakFirst of all, what API are you using? Is this OpenGL, Direct3D, or some 3D code you're writing yourself?Elaborate a bit more so we can help.

Sorry! I'm doing everything myself in software (filling/texturing triangles, rotating points, transforming to screen coordinates, loading models, lighting &c) in C++ and SDL.

A model from DOOM3 exported from Milkshape3D by a script (~4000 triangles, ~25fps [ouch])

The angles I rotate by are the bog standard 0-to-2pi variety (radians). I'll hunt some stuff on matrix maths (not heard of it before, which explains my confusion a little). Unfortunately, I've done everything without a reference so far, so my code is probably a little unconventional. I'm just messing around with it a bit, as I like this sort of thing. [wink]

##### Share on other sites
Quote:
 Original post by Emmanuel DelogetMxV (9 muls) is faster than U^V (3 muls) ? I'm pretty sure it is not the case :)

If you're talking about the cross product when using ^ (which is what you use to recalculate normals) then that generally requires six multiplies and three subtractions, not three muls. It also requires normalisation, though you need that with the matrix multiply as well if you allow non uniform scaling.

To the OP, you really should learn more linear algebra, it is a very elegenat way to represent changes of coordinate systems and transformations when it comes to 3d graphics. For example, you can do both the projection, the viewport transform, the camera transform and the object to world transform all at once by performing a single Matrix*vector multiply.

##### Share on other sites
Quote:
 Original post by GameCatTo the OP, you really should learn more linear algebra, it is a very elegenat way to represent changes of coordinate systems and transformations when it comes to 3d graphics.

Problem.
I cannot "learn" maths. I have a real mental block when it comes to it. I can add, subtract, multiply and divide and push the required buttons on a calculator - but don't ask me to do anything more advanced!

##### Share on other sites
Quote:
 Original post by benryvesI cannot "learn" maths. I have a real mental block when it comes to it. I can add, subtract, multiply and divide and push the required buttons on a calculator - but don't ask me to do anything more advanced!

Well, you're going to need to learn sometime if you want to get anywhere far in 3D graphics, I'm not saying you have to learn from a book but you'll need to acquire the knowledge somehow. If that somehow means asking lots of questions on the GDNet forums then so be it, there will be plenty of people here who can help.

To answer your original question, yes, you can just rotate the normal. This is typically the way most APIs do things as well - the worst case is that the normal will be un-normalised if you've scaled it (when you look up matrix maths you'll understand how this might be possible) but obviously it's solvable by renormalising the vector.

-Mezz

##### Share on other sites
I understand the maths in things such as how to normalise a vector, but it took me about a week and a half of pestering someone over IRC to work out how you performed a cross product! I'm just exceptionally stupid when it comes to maths, unfortunately.

##### Share on other sites
Quote:
Original post by GameCat
Quote:
 Original post by Emmanuel DelogetMxV (9 muls) is faster than U^V (3 muls) ? I'm pretty sure it is not the case :)

If you're talking about the cross product when using ^ (which is what you use to recalculate normals) then that generally requires six multiplies and three subtractions, not three muls. It also requires normalisation, though you need that with the matrix multiply as well if you allow non uniform scaling.

You are right, my bad (/me feel ashamed). Do you forget my stupidity if I give you teh caek?

Quote:
 Original post by benryvesI'm just exceptionally stupid when it comes to maths, unfortunately.

O_o

You should stop believing that math are hard. Just right now. And to beleive there is only two things in math:
A) definitions (as in: what is a dot product)
B) logic (as in: why the hell 1+1=2?)
Nothing else. If you are able to program then you should understand the logic. The only thing you have to do is to consider definitions as definitions.

When it comes to higher level math, the separation becomes clearer. You don't have to think about why matrices look like this. They do. You don't have to prove that the product of the inverse matrix and the matrix itself is the identity matrix, because you define the inverse matrix like this.

Math is not complex (well, some numbers are, but that's only a pun, and I know I don't have any sense of humour).

HTH,

##### Share on other sites
Quote:
 Original post by Emmanuel DelogetYou should stop believing that math are hard.

I will stop doing that when I lever my marks up a bit. I got a C in Pure 3 and a C in Statistics 2 (unfortunately these didn't bring my overall grade down, I still got an A [sad]).

In terms of breaking it down, I wish my lecturers and/or supervisors would do that. I'm doing a hell of a lot of extra work in maths and getting absolutely nowhere.

The worst for me is anything that involves calculus. Especially when they throw in logarithms or trig functions.

##### Share on other sites
Yes, maths is hard. I don't make any bones about this, and neither would most people - that's why they don't teach linear algebra to 5 year olds! It took me ages when I first started to get to grips with vectors, matrices and all the other shit that comes with 3D programming. I spent quite a bit of money and time reading books or papers on the internet, only to find that they didn't really explain things in a way which helped me understand them (I also have a problem learning new things from books... it's ok when I have some background in the field as I do now, but when I started it was impossible).

I also did fairly poorly in the advanced modules at A level maths too, although I got an A overall. You don't need to be a god of the pure maths side of things for 3D programming, it's actually more oriented on physics, mechanics and spatial transformation stuff. Don't expect to be integrating the inverse logarithm of the hyperbolic cosine of x much in this field.

That said, if you have a big issue learning from books or whatever, I don't know where I can direct you to learn this stuff, all I can say is that after many books, papers and internet sites I only found one which explained it in a way I understood, and it was infact Brian Hook who recommended it.

Computer Graphics: Mathematical First Steps ISBN: 0135995728

I hate sounding corny, but maybe it'll help you the way it helped me :)

-Mezz

##### Share on other sites
Yeah, it is hard. I'm like you Benryves. I have real trouble with math. Just about passed it at school with a grade C, BUT, discovered at college that learning math (or any subject for that matter) is about the quality of the teacher. I had a math teacher at college (Mr Newton was his name believe it or not) that had the ability to make the subject realtively easy to understand. Many years later I now face the same issue again. I want to improve my 3D programming, but the math just numbs my brain. Got to find the right teacher again! Learning this stuff from books and online docs just doesnt work for me either - and that approach is the longer, more drawn out one also. Saying that though, I might still pick up the book Mezz mentioned though :-) Keep at it man. There's plenty of us out here in the same boat, and places like gamedev.net are excellent for receiving help and support when trying to get your head around something!

##### Share on other sites
Mezz, that book sounds interesting. Can you tell us the Index for it, what it covers? (couldnt find that info on Amazon)

Benryves: A matrix is just a "pack of information" that has information on how to rotate and translate a vector on all 3 axis.

Once you multiply you vector by a matrix, the vector is rotated and translated by the information stored on the matrix...

Another property of matrices is that you can multiply them together.

Imagine you have a set of vectors in 3D space, and you need to rotate/translate them a certain way (A), and then rotate/translate them in a diferent way (B).

You probably have matrices A and B. Instead of doing two separate operations on the vertices, all you do is:
N = A*B

...and you create the N matrix. The N matrix will store in itself the rotation/translation information of A AND B, and, therefore, when you pass your vertices through the N matrix, the result will be the same as if they had just passed by A & B.

##### Share on other sites
Note that you actually need to multiply the normals by the inverse transpose of the matrix used to transform the model vertexes though in practice if all your matrix does is rotations and translations taking the inverse transpose of it is a no-op so you can use the matrix directly.

##### Share on other sites
hey, can i see your

point3D rotatePointAboutAxisX(point3D p, double a) { }point3D rotatePointAboutAxisY(point3D p, double a) { }point3D rotatePointAboutAxisZ(point3D p, double a) { }

functions?

for my camera id actually prefer to do that than construct a yaw pitch and roll matrix and then extract the forward and right vectors... because frankly, thats a lot of multiplies, and wasted trig functions

edit: eh, maybe not such a good idea, because i need to rotate around the camera's axis, not the x,y,z (well the first rotation would be, but after that)

thanks
-Dan

[Edited by - Ademan555 on January 8, 2005 4:53:24 AM]

##### Share on other sites
Quote:
Quote:Original post by Emmanuel Deloget
Quote:
 MxV (9 muls) is faster than U^V (3 muls) ? I'm pretty sure it is not the case :)

If you're talking about the cross product when using ^ (which is what you use to recalculate normals) then that generally requires six multiplies and three subtractions, not three muls. It also requires normalisation, though you need that with the matrix multiply as well if you allow non uniform scaling.

apart from the fact that it requires 6 muls (and not 3 like a dot product), this would only work for face normals, if you want vertex normals, you need much more work than that, like adding together the face normals of all the faces touching that vertex, with a final renormalization required per vertex (6 muls and one div)
matrices are definitely better, and the only place where re-computing the normals might have a slight advantage would be special cases anyway...