Activate the feature of smooth shading using Three.js

When rendering an object with textures using MTL and OBJ files in Three.js, I encountered an issue where my model was displayed with flat shading. How can 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: After implementing the solution provided in the accepted answer, I was able to fix the flat shading issue in my code.

Answer №1

There are two potential solutions that come to mind in this situation.

Firstly, it could be that the material is set to FlatShading. To address this, you can access the object and utilize

object.material.shading = THREE.SmoothShading;
to correct it.

If the issue persists, it's likely that the object contains per-vertex-normals, where each vertex of every triangle has a normal attached that all point in the same direction. Ideally, this should be resolved during the 3D-editing phase, but you can also recompute the normals in three.js:

object.geometry.computeVertexNormals(true);

This action should recalculate the normals for smooth surfaces. Note that this method is effective for regular Geometries and Indexed BufferGeometries, and may not work if the geometry lacks information on reused vertices for adjacent faces.

[1]: I have not personally tested this method and am relying on information extracted from the code.

Answer №2

To achieve a more polished look, consider applying the following steps to your geometry:

geometry = BufferGeometryUtils.mergeVertices(geometry, 0.1);
geometry.computeVertexNormals(true);

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

"Have you ever wondered how the router object in express.js is seamlessly integrated with app.use(), considering that it only accepts

I am curious about the process of how the router object in express.js is passed to app.use(), which typically only accepts callbacks. Since router is an object of express, I am trying to understand why app.use() does not throw an error even though it req ...

What is the proper way to implement a $scope.$watch for a two-dimensional array in AngularJS?

Having trouble implementing an Angular watch on a multidimensional array I've got a screen where users can see two teams (outer array) with team sheets (inner array) for each team. They can drag and drop players to change the batting order. The batt ...

Trouble uploading an audio blob as a base64 string using Google Drive API with the drive.files.create method - File ID could not be located

My current challenge involves sending an audio blob to a specific Google Drive folder. To accomplish this, I convert the blob into a file before initiating the transfer process. However, I have encountered an error from the beginning: Error: File not fo ...

FireFox is causing issues with both ng-view and Angular functions, rendering them unusable

My AngularJS sample application is running smoothly in Google Chrome, but when I tried to test it in Firefox, I encountered issues with ng-view and other functions not working properly. This is the structure of my application: Index.html <!DOCTYPE ht ...

Guide on invoking the server-side method in Office 365 using JavaScript files

Exploring the capabilities of office 365 API apps and looking for documentation on how to access specific row(s) and cell(s) values / select a particular sheet programmatically in a .js file. Currently, I am utilizing the following code within a function: ...

Encountering a ReferenceError stating that the window object is not defined while building a React Leaflet application

In my upcoming nextjs project, I've incorporated react-leaflet. It behaves flawlessly in dev mode. However, upon attempting to build the project, it throws a ReferenceError: window is not defined. Despite setting ssr to false in dynamic, the error per ...

Change Node.js version to 6.11.5 on a Windows system

My current node version is v8.2.1, but Google Cloud Functions only supports v6.11.5. I need to switch my node version accordingly and preferably do it using npm. How can I achieve this? I have explored How to change to an older version of node.js for guid ...

Transferring my JavaScript variable to PHP through Ajax

I'm currently facing an issue where my JavaScript variable is not being successfully passed to a PHP variable using AJAX in order to update my SQL database. The function is being called, but for some reason the data is not being sent to PHP.php. UPDA ...

The shared hosting environment encountered an error during the Next JS build process

When I execute the command "npm run build" on my shared hosting server, it throws an error message: spawn ENOMEM. Interestingly, this command runs perfectly fine on my localhost and has been running smoothly on the hosting server for a few weeks until yest ...

Animating a ThreeJS Mesh using the TweenMax scaling method

Having issues trying to implement a scaling translation to my mesh[0] using TweenMax. While other animations like rotation work fine, I encounter an 'Uncaught TypeError: Cannot assign to read only property 'scale' of object '#'&apo ...

Retrieving HTML Content with Ajax

Currently using this script for an assignment in my class. Still learning! The script checks whether a site is down or not. I want to expand this script to display statuses for each website in the table without duplicating the script. Any suggestions on ...

What is the method to determine the index of a removed element within a subarray?

In my array, all = [2,3,4,12, 55,33], there is a sub-array named ar1 = [12, 55, 33] starting from the value 12. If I remove a value from all that is present in ar1 (e.g. 12), how can I determine the index of this value in ar1 (0 for 12) so I can also remo ...

The Add/Remove button functionality is not functioning as expected for duplicated form fields when using jQuery

I am experiencing an issue with the functionality of the "Add another" and "Remove row" buttons in my form. I implemented code from a specific Stack Overflow answer (jquery clone form fields and increment id) to create a cloneable section, but only the ori ...

npm installs a multitude of dependencies

Recently, I purchased an HTML template that includes various plugins stored in a directory named bower_components, along with a package.js file. While trying to add a new package that caught my interest, I opted to utilize npm for the task. Upon entering ...

Tips for customizing the main select all checkbox in Material-UI React data grid

Utilizing a data grid with multiple selection in Material UI React, I have styled the headings with a dark background color and light text color. To maintain consistency, I also want to apply the same styling to the select all checkbox at the top. Althou ...

bxSlider adds in an empty slide after deleting an image

Whenever I click a link in my navigation, I want to remove certain images from the page. I tried implementing a solution, but now I have two empty spaces where the images used to be. How can I remove those as well? I searched on Stack Overflow for a soluti ...

typescript error: passing an 'any' type argument to a 'never' type parameter is not allowed

Encountering an error with newUser this.userObj.assigned_to.push(newUser);, receiving argument of type 'any' is not assignable to parameter of type 'never' typescript solution Looking for a way to declare newUser to resolve the error. ...

Exploring the functionality of the $.each jQuery iterator. Can someone clarify the distinctions between these two methods?

Having vertices as an array of google.maps.LatLng objects means that they should return latlng points. The first code snippet works perfectly fine, however, I encounter issues when using the second one. // Iterate over the vertices. for (var index =0; ind ...

Tips for managing onClick events within a conditional component

I am currently attempting to implement an onClick event on the data that I have selected from the AsyncTypeahead. My goal is to pass a callback function to the Problem component, which will only render if an item has been selected. However, after selecting ...

What is the best way to leverage a webbrowser control for design purposes while keeping the functionality in C#?

Observing some apps, it seems they utilize HTML/CSS/Javascript for styling - a much simpler approach compared to crafting the same thing natively. However, these apps have their logic written in C#. Sadly, I am clueless on connecting the two. Research yiel ...