Fast-Quadric-Mesh-Simplification icon indicating copy to clipboard operation
Fast-Quadric-Mesh-Simplification copied to clipboard

Dealing with normals

Open Zylann opened this issue 4 years ago • 2 comments

From what I can see from the OBJ example, normals appear to be lost in the conversion process. I can see they are generated in update_mesh, but that's per triangle, and the original normals aren't used. I even saw that the THREE.JS example looses its smooth shading in the process of decimation.

So how are we supposed to get back a mesh with smooth normals? Do we have to take those from Triangle, average (how to do fast?) and renormalize them so we can store them per vertex?

I can branch and choose either smooth generation or flat generation, but that means any mix of the two from the original mesh would be lost (i.e if I decimate a cylinder, how do I make the round part smooth and the caps flat?). Note: I don't necessarily know which mesh I decimate, I'd like to use this with user-made and procedurally generated meshes.

Zylann avatar Jul 17 '20 20:07 Zylann

  1. Initialize an array with one normal (3D vector) for each vertex where all components (X,Y,Z) are set to zero.
  2. For each face (triangle with 3 vertices), compute the surface normal (merely the cross-product) assuming CCW winding. Add this vector to each of the three vertices that contributed to the triangle.
  3. For each vertex, normalize the normal length to 1.

Here is my pascal code:

  setlength(vNorm, length(vertices) );
  //compute vertex normals
  fNorm := ptf(0,0,0);
  for i := 0 to (length(vertices)-1) do
    vNorm[i] := fNorm;
  for i := 0 to (length(faces)-1) do begin //compute the normal for each face
    fNorm := getSurfaceNormal(vertices[faces[i].X], vertices[faces[i].Y], vertices[faces[i].Z]);
    vectorAdd(vNorm[faces[i].X] , fNorm);
    vectorAdd(vNorm[faces[i].Y] , fNorm);
    vectorAdd(vNorm[faces[i].Z] , fNorm);
  end;
  for i := 0 to (length(vertices)-1) do
    vectorNormalize(vNorm[i]);

neurolabusc avatar Oct 08 '20 14:10 neurolabusc

See here for a Python solution. I am not familiar with three.js, but I think BufferGeometry.computeVertexNormals can re-generate normals. Does this resolve your issue?

neurolabusc avatar Jan 18 '22 15:01 neurolabusc