1

I can calculate triangle normal N by having three vertex positions of v0, v1, v2 and using cross product:

calculation

The problem is a 3D mesh data structure needs a normal for each vertex. I mean, it needs n1, n2 and n3. I don't know what is the correct way to calculate them.

Tried

I tried to use the same N value for n1, n2 and n3, but I'm not sure if it is the correct approach:

n1 = n2 = n3 = N

Megidd
  • 7,089
  • 6
  • 65
  • 142
  • 1
    If you want to compute a "smooth" mesh for a curved object (like a sphere), you have to interpolate the vertex normals from the adjacent face normals – Rabbid76 Oct 12 '20 at 08:45
  • @Rabbid76 Do you know any sample calculation I can get inspired by? – Megidd Oct 12 '20 at 08:49
  • 1
    @user3405291 here is one of samples from another question: https://stackoverflow.com/questions/61336175/how-can-i-optimize-my-soft-normal-calculation-function – gkv311 Oct 12 '20 at 09:06
  • 1
    @gkv311 Thanks! Exactly what I needed: https://stackoverflow.com/a/61336810/3405291 – Megidd Oct 12 '20 at 09:17
  • 1
    see https://stackoverflow.com/a/21930058/2521214 – Spektre Oct 13 '20 at 10:39

1 Answers1

0

Implemented smooth vertex normal like this:

std::vector<Vec3d> points = ...
std::vector<Vec3i> facets = ...

// Count how many faces/triangles a vertex is shared by
std::vector<int> counters;
counters.resize(points.size());

// Compute normals
norms.clear();
norms.resize(points.size());
for (Vec3i f : facets) {
    int i0 = f.x();
    int i1 = f.y();
    int i2 = f.z();
    Vec3d pos0 = points.at(i0);
    Vec3d pos1 = points.at(i1);
    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;
    norms[i2] += N;

    counters[i0]++;
    counters[i1]++;
    counters[i2]++;
}

for (int i = 0; i < static_cast<int>(norms.size()); ++i) {
    if (counters[i] > 0)
        norms[i] /= counters[i];
    else
        norms[i].normalize();
}
Megidd
  • 7,089
  • 6
  • 65
  • 142