Quick'n'Dirty way to calculate Normals

6ad5f8c742f1e8ec61000e2b0900fc76
0
davepermen 101 Jul 28, 2003 at 21:15
// just reset the normals to an initial value of 0
for every vertex v in mesh {
    v.normal = 0,0,0
}

// calculate each face normal and add it to the 3 edge-vertices
for every face f in mesh {
    vertex& a = mesh.vertex_array[f.a] // refer to the 3 vertices of this face
    vertex& b = mesh.vertex_array[f.b]
    vertex& c = mesh.vertex_array[f.c]
    vector3 normal = calc_triangle_normal(a,b,c)
    a.normal += normal
    b.normal += normal
    c.normal += normal
}

// normalize the vertices to average
for every vertex v in mesh {
    v.normal.normalize()
}

By the way, as we don’t normalize the normals on the summing part, bigger faces turn normals on their vertices more towards them.. this is accurate if you do it on paper (in 2d as best)..

there are suggestions to divide them by the squared length before summing to smoothen more towards the round parts.. while looking nice, too, and being based on some good idea actually, it is just slower.. thats why i never use anything else but that..

be warned that, if you have different vertices with same position, you get a hard edge there..

11 Replies

Please log in or register to post a reply.

4851117d61425bafb6c034e0f595d517
0
DrunkenCoder 101 Jul 30, 2003 at 05:55

This is the method I use to took me some time to figoure it out (mostly because my teacher said it wouldn’t work :blink: ).

Just make sure that calc_triangle_normal returns a unit normal (is that the correct terminology?) i.e. a normal with length 1.0

6ad5f8c742f1e8ec61000e2b0900fc76
0
davepermen 101 Jul 30, 2003 at 06:26

as i said above, that is NOT needed. and gives mathematically more correct result (good if you animate the mesh..)..

well.. i just thought about it again.. i’m not sure now anymore.. i’ll paper it out today, i have time..

4851117d61425bafb6c034e0f595d517
0
DrunkenCoder 101 Jul 30, 2003 at 06:58

@davepermen

as i said above, that is NOT needed. and gives mathematically more correct result (good if you animate the mesh..).. well.. i just thought about it again.. i’m not sure now anymore.. i’ll paper it out today, i have time..

Actually Im not quite sure that just being large should give you an added bonus at least for me I get the feel that the look is more correct when rescaling all normals to unit normals before summation.

The other method most people use is to first calculate normalized plane normals then add these and divide by the number of normals, normalizing the plane normals before summation here yields the exact same result with less book-keeping so I would call it more accurate.

But that’s just my oppinion, could be wron… it’s known to happen… :unsure:

6ad5f8c742f1e8ec61000e2b0900fc76
0
davepermen 101 Jul 30, 2003 at 08:27

as i said, i’ll go over the normalizing per face again to see how it affects visual impression..

2b97deded6213469bcd87b65cce5d014
0
Mihail121 102 Sep 07, 2004 at 10:39

You’re right dave. One shoudn’t!!! normalize triangle normals when calculating vertex ones. The results are really more correct that way.

254754b37f468a2926bffcd83bbbf1fa
0
z80 101 Sep 07, 2004 at 13:35

Does calc_triangle_normal() return a unit vector?

If it does, I fail to see how bigger faces turn normals on their vertices more towards them.

If not, then how is it implemented (probably (b-a)x(c-a) right)?

6ad5f8c742f1e8ec61000e2b0900fc76
0
davepermen 101 Sep 07, 2004 at 14:14

no normalization, nope. just b-a x c-a, yes. (or the other way around? no this way around, what ever way around :D)

2b97deded6213469bcd87b65cce5d014
0
Mihail121 102 Sep 07, 2004 at 14:34

Actually when you calculating cross product the order does matter…

6ad5f8c742f1e8ec61000e2b0900fc76
0
davepermen 101 Sep 07, 2004 at 14:48

yeah, but in the end, we can just flip all the normals if they are to the wrong side. the rest doesn’t mather, it doesn’t change anything else of the calculation. thats what i ment.

254754b37f468a2926bffcd83bbbf1fa
0
z80 101 Sep 07, 2004 at 14:49

So really the bending-towards-large-faces-feature is controlled by the two edges (randomly) selected for the normal calculation (b-a and c-a or whatever).

This could give some random results if for example a triangle face has two very long edges and one very short edge.

254754b37f468a2926bffcd83bbbf1fa
0
z80 101 Sep 08, 2004 at 14:01

@davepermen

to z80, nope, the cross product normal length is always related to the area of the triangle you calculate it on, it doesn’t mather, on wich edges you evaluate it. works always.

but yes, the ones with bigger area result in longer normals => they affect a vertex normal more => they drift towards the long faces.. making them more flat, while small faces get more round shading (wich often makes sence).

[snapback]10883[/snapback]

Yeah ok, you’re right of course! I’ve been unaware of that vector cross product property until now.