Here's code to create mesh normals using the "Mean Weighted by Angle" method, which looks better than the default Irrlicht method.
http://ryanclark.net/irrlicht/CMeshManipulator.cpp
You can compare methods by toggling #define USE_ANGLE_WEIGHTED_NORMALS
Here is the relevant bit from recalculateNormalsT_Smooth. (Similar code is also added in createMeshWithTangents.)
Code: Select all
#ifdef USE_ANGLE_WEIGHTED_NORMALS
// Calculate this triangle's weight for each of its three vertices
// start by calculating the lengths of its sides
float a = (v[idx[i+1]].Pos - v[idx[i+2]].Pos).getLength();
float b = (v[idx[i+0]].Pos - v[idx[i+2]].Pos).getLength();
float c = (v[idx[i+0]].Pos - v[idx[i+1]].Pos).getLength();
// use them to find the angle at each vertex
float weight0 = acos(( b*b + c*c - a*a) / (2 * b * c));
float weight1 = acos((-b*b + c*c + a*a) / (2 * a * c));
float weight2 = acos(( b*b - c*c + a*a) / (2 * b * a));
#else
float weight0 = 1;
float weight1 = 1;
float weight2 = 1;
#endif
core::plane3d<f32> p(v[idx[i+0]].Pos, v[idx[i+1]].Pos, v[idx[i+2]].Pos);
v[idx[i+0]].Normal += p.Normal * weight0;
v[idx[i+1]].Normal += p.Normal * weight1;
v[idx[i+2]].Normal += p.Normal * weight2;