• 11
• 9
• 12
• 9
• 11

# smoothing normals

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

## Recommended Posts

How to smooth normals?
When I calculate the normal, they become flat.

var figure = {
vertex: [1, 1, -1, -1, 0, 0, -1, 1, -1, 1, 0, 1, 1, 0, 0, -1, 0, 1],
index: [0, 1, 2, 3, 1, 4, 0, 4, 1, 3, 5, 1]
};

function calcNormal(vertex, index) {
var vertNormal = [];
var surfNormal = [];
for (var i = 0; i < index.length; i += 3) {
var v0_v = [vertex[index[i + 0] * 3 + 0], vertex[index[i + 0] * 3 + 1], vertex[index[i + 0] * 3 + 2]];
var v1_v = [vertex[index[i + 1] * 3 + 0], vertex[index[i + 1] * 3 + 1], vertex[index[i + 1] * 3 + 2]];
var v2_v = [vertex[index[i + 2] * 3 + 0], vertex[index[i + 2] * 3 + 1], vertex[index[i + 2] * 3 + 2]];
var p = Vector3.minus(v1_v, v0_v);
var q = Vector3.minus(v2_v, v0_v);
var n = Vector3.cross(p, q);
//n = Vector3.normalize(n);
surfNormal.push(-n[0]);
surfNormal.push(-n[1]);
surfNormal.push(-n[2]);

vertNormal[index[i + 0] * 3 + 0] = -n[0]; vertNormal[index[i + 0] * 3 + 1] = -n[1]; vertNormal[index[i + 0] * 3 + 2] = -n[2];
vertNormal[index[i + 1] * 3 + 0] = -n[0]; vertNormal[index[i + 1] * 3 + 1] = -n[1]; vertNormal[index[i + 1] * 3 + 2] = -n[2];
vertNormal[index[i + 2] * 3 + 0] = -n[0]; vertNormal[index[i + 2] * 3 + 1] = -n[1]; vertNormal[index[i + 2] * 3 + 2] = -n[2];
};
//... calculation smooth normals
//...
//createBuffer(vertNormal)
}
calcNormal(figure.vertex, figure.index);

##### Share on other sites

I'm not sure, but I think you are on the right track. See if this helps:

A vertex that is shared by more than one triangle must average the normal for that vertex of each triangle. It appears you are only using info from one face to calculate the normal.....

##### Share on other sites

1.) If this is just a normal 3D model that is static, why not just have 3DsMax/Maya/Blender etc calculate this for you and then export.

2.)
surfNormal.push(-n[0]);

If your normals are pointing in the wrong direction, then you did the wrong cross product. Are you sure all your triangles are even wound probably since you hard coded them?

3.) Your algorithm looks completely wrong. You are looping through every face (which shares vertices, and computing the normal over and over again for the same vertex). It looks like then the last face to touch that vertex assigns its face normal to that vertex.

You need to create normals for all the faces in one loop. Then a second loop afterwards you need to do  vertexNormal[index[ blah ] += triangles normal. This gives you all the normals added.  Then in a 3rd loop, you need to divide the normal by how many faces the vertex is connected to (averaging the normal).

##### Share on other sites

It's a bit hard to work out what's going on with that, it might be worth trying to make the code a bit easier to follow. To calculate smoothed normals you need to do 2 passes.
First work out face normals, I see you already do that.
Second part depends how you want to weigh your normal contributions. For example if you have a tiny face joined to a huge face shouldn't the huge face contribute more than the smaller face? If you don't take that into account your normals will look off. For simplicity sake though:
Initialise all the vertex normals to 0
Go through each vertex
For every attached face add the face normal onto the vertex normal
normalize the normal

If you want larger faces to contribute more you could do:

for each vertex:
normal = Vector(0, 0, 0)
for each attached face
normal += face.normal*face.area
normal.Normalize();

That way larger faces contribute more and you won't get weird looking lighting when small faces attach to larger ones at differing angles.

You need to create normals for all the faces in one loop. Then a second loop afterwards you need to do  vertexNormal[index[ blah ] += triangles normal. This gives you all the normals added.  Then in a 3rd loop, you need to divide the normal by how many faces the vertex is connected to (averaging the normal).

Just a comment on the third pass, you don't need to know how many faces there are since normalizing will take care of that no matter the number of faces.

Edited by Nanoha