Enable smooth shading with Three.js

11,161

It could be one of two things that I can think of right now.

It could be that the material is set to FlatShading. In this case just somehow retrieve the object and use object.material.shading = THREE.SmoothShading; to fix.

If that doesn't change it, it's possible that the object contains per-vertex-normals (meaning that every vertex of every triangle has a normal attached to it) and that all normals for each triangle point in the same direction. This is something that should better be solved in the 3d-editing process, but you can also re-compute the normals in three.js:

object.geometry.computeVertexNormals(true);

This should [1] recompute the normals for smooth surfaces. However, it will only work for regular Geometries and Indexed BufferGeometries (or, to put it the other way around: it won't work if the geometry doesn't have information about vertices being reused for adjacent faces)

[1]: I didn't test it myself and just go after what I just read in the code

Share:
11,161
Berry Blue
Author by

Berry Blue

Updated on June 15, 2022

Comments

  • Berry Blue
    Berry Blue almost 2 years

    I'm rendering an object with textures using MTL and OBJ files with Three.js. My code here works but my model is displayed as flat shaded. How do I enable smooth shading?

    var scene = new THREE.Scene();  
    var mtlLoader = new THREE.MTLLoader();
    mtlLoader.setPath('assets/');
    mtlLoader.setBaseUrl('assets/');
    mtlLoader.load('asset.mtl', function(materials) {
    
        materials.preload();
    
        var objLoader = new THREE.OBJLoader();
        objLoader.setMaterials(materials);
        objLoader.setPath('assets/');
        objLoader.load('asset.obj', function(object) {
    
           //
           // This solved my problem
           //
           object.traverse(function(child) {
               if(child instanceof THREE.Mesh)
               {
                  child.material.shading = THREE.SmoothShading;
               }
           });
           //
           //
    
           scene.add(object);
        });
    });
    

    EDIT: I updated my code with a solution that fixed my problem based on the accepted answer.