VertexData.ComputeNormals() Issues

Hi all,
I’m trying to use the VertexData.ComputeNormals() function to generate the normals for a glTF mesh without normals, and have run into a couple of issues that can be seen in this playground:

https://playground.babylonjs.com/#7074FJ#12

  1. The top and middle meshes show how the computed normals look different (flat vs smooth) for the same geometry depending on whether or not they were exported with the “Optimize Vertices” option turned on in the Babylon Exporter. Anyone know why that would be?

  2. The middle mesh has a visible seam in the normals where the boundary of the UV map lies. Compare this with the bottom mesh, which had its normals pre-computed in Maya before exporting to glTF. There was a similar issue that was already addressed in the OBJ import process (see OBJ loader - Computed normals are wrong if OPTIMIZE_WITH_UV is set to true), is this something that also needs to be addressed for the computeNormals() function?

Let me see if I can get the ball rolling and share what I learned so far.

For your first question. Anyone know why that would be? Let actually take a look at the normals using the handy inspector. You can do this by click on the mesh in the scene explorer and then scrolling all the way down to debug and toggling Render Vertex normals.

Now this is just my observation but see how for the top mesh there are 2-3 normals for any given vertex. I think this is because you are getting 1 normal for each intersection point. While on the middle one I only see 1 in most places but 2 in the area of the seam. For the lowest one it seems to be some kind of average of all of the different normals so you only get a single normal.

I hope someone will have more follow up to this, and Ill be taking a look further myself to see if I can learn more. :slight_smile:

3 Likes

Cool, thanks @msDestiny14 for the visualization! Wondering if anyone else has any ideas about what the root cause of these inconsistent normal values is, and whether or not these are bugs. I would expect both the middle and top meshes to look like the bottom one after I use computeNormals() to update the normals.

1 Like

Maybe u can make this work for your needs GitHub - jeremy-coleman/normal-rust: A small Rust / Webassembly project to calculate Normals

3 Likes

Thanks @jeremy-coleman, will take a look when I get the chance. Still think it’s worth digging into what’s going on with computeNormals() since my team would like to be able to rely on the normals computation within Babylon. Anyone familiar with the function and might know why it’s being inconsistent in the given examples?

1 Like

1- back in the early days, smooth shading was deemed optimized versus flat. It is more compact, but just different. Apparently, computeNormals detects previous normals. Check source code.

2- I think seeing what happens with computeNormals when UVs are deleted would be instructive.

The rust code was a simplified (no options) version of computeNormals for the purpose of evaluating performance. Don’t think it will give different results, unless you are specifying options.

2 Likes

Removed UVs and exported with and without optimized vertices (3rd and 4th meshes from the top). computeNormals() generates flat shading for both.

https://playground.babylonjs.com/#BC8HYU

Does this help at all? My goal is to be able to consistently generate smooth shading normals in Babylon, like the ones on the bottom mesh, for a mesh without normals. And also for there to be no visible seam where the uv boundaries lie.

OK, I messed around some more and found that calling forceSharedVertices(); on the mesh before computing the normals results in smooth shaded normals free of any artifacts!

5 Likes