I have vertex position and index and I want vertex normal:
// input
vector<Vec3f> points = ... // position
vector<Vec3i> facets = ... // index (triangles)
// output
vector<Vec3f> norms; // normal
Method 1
I compute normal like this:
norms.resize(points.size()); // for each vertex there is a normal
for (Vec3i f : facets) {
int i0 = f.x();
int i1 = f.y(); // index
int i2 = f.z();
Vec3d pos0 = points.at(i0);
Vec3d pos1 = points.at(i1); // position
Vec3d pos2 = points.at(i2);
Vec3d N = triangleNormal(pos0, pos1, pos2); // face/triangle normal
norms[i0] = N;
norms[i1] = N; // Use the same normal for all 3 vertices
norms[i2] = N;
}
Then, the output mesh is rendered like this with a Phong material:
Method 1 with reversed normal
When I reverse normal direction in method 1:
norms[i0] = -N;
norms[i1] = -N;
norms[i2] = -N;
The dark and light regions are swapped:
The same happens by swapping position 0 with position 1 by:
// Vec3d N = triangleNormal(pos0, pos1, pos2);
Vec3d N = triangleNormal(pos1, pos0, pos2); // Swap pos0 with pos1
Method 2
I compute the normal by this method:
// Count how many faces/triangles a vertex is shared by
vector<int> counters;
counters.resize(points.size());
norms.resize(points.size());
for (Vec3i f : facets) {
int i0 = f.x();
int i1 = f.y(); // index
int i2 = f.z();
Vec3d pos0 = points.at(i0);
Vec3d pos1 = points.at(i1); // position
Vec3d pos2 = points.at(i2);
Vec3d N = triangleNormal(pos0, pos1, pos2);
// Must be normalized
// https://stackoverflow.com/a/21930058/3405291
N.normalize();
norms[i0] += N;
norms[i1] += N; // add normal to all vertices used in face
norms[i2] += N;
counters[i0]++;
counters[i1]++; // increment count for all vertices used in face
counters[i2]++;
}
// https://stackoverflow.com/a/21930058/3405291
for (int i = 0; i < static_cast<int>(norms.size()); ++i) {
if (counters[i] > 0)
norms[i] /= counters[i];
else
norms[i].normalize();
}
This method yields a totally dark final render by a Phong material:
I also tried methods suggested here and there which are similar to method 2. They all result in a final render which looks like that of method 2 i.e. all dark regions without any light one.
Method 2 with reversed normal
I used method 2, but at the end, I reversed the normal direction by:
for (Vec3d & n : norms) {
n = -n;
}
To my surprise, the final render is all darK:
Also in method 2, I tried swapping position 0 with position 1:
// Vec3d N = triangleNormal(pos0, pos1, pos2);
Vec3d N = triangleNormal(pos1, pos0, pos2); // swap pos0 with pos1
The final render is all dark regions without any light ones.
How?
Any idea how I can get my final render to be all light without any dark region?