Wrong normals when loading draco models

I have been testing draco since a month, I use DracoLoader for ThreeJs.

I still have one problem.
I’m exporting obj file without normals to keep small file size for uncompression and decoding speed. Almost all meshes are rendered correctly, the normals are well computed.
But I have problem with some meshes, as you can see in the screenshots (smooth, flat, wireframe).

Rendering without modification (smooth) causes normals problems, when I set ‘flatShading’ to true on the material the mesh is correctly rendered.

I tested OBJLoader2 from ThreeJs with the option ‘useIndices’ and the mesh was correctly rendered.

According to a collaborator of Draco, the problem comes from threejs and not from Draco as the latter doesn’t compute the normals if they aren’t provided in the models whereas the former does.

How can I solve this problem? Where should I compute the normals?

Does threejs compute smooth normals?

Best regards,

Have you tried setting flat shading on the mesh?

object.traverse((node) => {
  if (node.isMesh) {
    node.material.flatShading = true;
    node.material.needsUpdate = true;

If unspecified, three.js will use smooth shading.

THREE.Material docs, r90.

This is exactly what we are already doing but it’s only a workaround because we want to use smooth shading and as we don’t provide the normals in the model, it’s up to threejs to compute them and they seem to be wrongly computed as you can see in the first image (left).

The problem seems to be inside threejs: https://github.com/google/draco/issues/348#issuecomment-369340117

I don’t understand why it works correctly with OBJLoader2 and the option useIndices whereas it doesn’t work with the DracoLoader.
I don’t want to use flatShading in production.

Oh sorry, I see what you mean. This issue is discussed here: https://github.com/mrdoob/three.js/issues/8378

In short, correct smooth normals depend on having properly interconnected triangles, which indices enable… I’m not sure why this particular model is a problem and others are not, or whether Draco can encode an OBJ with indices preserved. You may want to ask them about indexed meshes. I’m guessing you must include either indices or normals to get the right result here.

Not sure what the rest of your workflow is like, but creating a glTF file (directly from your modeling tool, ideally, or with obj2gltf) and then draco-encoding that, would at least give you a way to preserve indices. That feature is very new and only on the dev branch right now. Docs.

Where is implemented the computation of smooth normals in threejs?

I’ve found the implementation of flat normals computation in BufferGeometry.computeVertexNormals but threejs seems to implement the computation of smooth normals elsewhere, I assume that it uses weighted vertex normals because I get the same rendering when I compute the weighted vertex normals by myself: https://stackoverflow.com/a/45496726

Is it implemented in a shader?

We decided finally to embedded the normals, we did not have time anymore to find another solution…
It take more physical space (the double), the dowloading time is a little more longer, but the loading time remains very correct.
If someone finds another way, it will be with pleasure…