The GLTFLoader does not support the replacement of its default materials

I am currently working on a scene that includes:

AmbientLight color: light blue

PointLight color: pink

a gltf object loaded with textures

Using the GLTFLoader, I successfully loaded a gltf object with texture map. The model is displayed correctly with textures using the default MeshStandardMaterial as shown in picture 1. Now, my goal is to change all the MeshStandardMaterial to MeshPhongMaterial. To achieve this, I loop through all the meshes and update the material as follows:

// find gltf scene
var gltfScene = scene.children.find(ele => ele.type === 'Scene');    
var meshes = gltfScene.children;
for (var i = 0; i < meshes.length; i++) {
  // for each mesh, change to MeshPhongMaterial
  meshes[i].material = new THREE.MeshPhongMaterial()
}

However, after making this change, all the mesh colors become flat and match my AmbientLight color. The meshes no longer respond to lighting from sources such as SpotLight or PointLight, as seen in picture 2 where the pink light from the PointLight is missing.

If anyone can provide assistance on why this happens and how I can replace the materials with MeshPhongMaterial, it would be greatly appreciated.

You can view the issue on Codepen here. The problem occurs when you click on Replace Horse Mesh, resulting in the disappearance of the pink light.

https://i.sstatic.net/6tkJ8.png

https://i.sstatic.net/POJpb.png

Answer №1

It appears that your traversal of the glTF scene is not correct. The correct way to traverse through it is shown below:

gltf.scene.traverse( ( child ) => { 

    if ( child.isMesh ) {

        child.material = new THREE.MeshPhongMaterial();

    }

} );

three.js R111

Answer №2

Big shoutout to @Mugen87 for the helpful tip! I found this gem on GitHub, and it's all about adding {flatShading: true}

gltf.scene.traverse( ( element ) => { 

    if ( element.isMesh ) {

        element.material = new THREE.MeshPhongMaterial({flatShading: true});

    }

} );

Answer №3

It took a few additional steps to make it work for me, especially with gltf integration.

gltf.scene.traverse((child) => {

        if (child.isMesh) {

          const originalMaterial = child.material;
          const newMaterial = new THREE.MeshPhongMaterial();

          // necessary steps that were missing
          child.geometry.computeVertexNormals();
          // keep the texture from the original material
          newMaterial.map = originalMaterial.map;

          child.material = newMaterial;
      }
})

note: flatShading = true may provide some functionality but might not achieve the smooth shading effect desired by most users.

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

When I implement JavaScript on my website, my HTML content does not show up

Whenever I try to fetch content from a specific URL using AJAX and a script, my HTML content does not show up. In other words, the table element is not displayed on the page. Instead, I am able to retrieve data from the specified URL and display it in an a ...

javascript guide on converting an array into the correct JSON format

I'm working with an array that has the following structure: var arr = [ [{a:1}], [{b:1}], [{c:1}], [{d:1}], [{e:1}] ] My goal is to format it into the proper format as shown below: [{a:1},{b:1},{ ...

Replacing text within a paragraph using D3.js

Is it possible to develop a D3 function that can choose a paragraph, delete its content, and replace it with new text? If so, what would be the most effective way to accomplish this? I attempted the following: d3.select("#triggerButton") .on("clic ...

Exploring the benefits of event subscription nesting

One feature I'm currently utilizing is the Angular dragula drag and drop functionality, which enables me to effortlessly move around Bootstrap cards within the view. When an item is "dropped," it triggers the this.dragulaService.drop.subscribe() funct ...

Endless Loop of Http Redirects in Node.js with Express

I need assistance with the code below which is meant to redirect all http traffic to https. // Implement redirect logic to ensure usage of https in production, staging, and development environments app.use((req, res, next) => { // Do not redirect to h ...

Having trouble retrieving the URL from JSON data - every time I attempt to access it, it just shows as undefined. Any suggestions

Having trouble extracting the URL from JSON, as it shows undefined. Any suggestions? <html> <head> <meta http-equiv="Content-Type" content="text/html;charset=utf-8" ></meta> <script language="JavaScript" type="text/javascript" ...

How can you access a function from within another function in the same object while keeping the object structure largely intact?

Seeking a solution using JavaScript (ES6), I am in need of referencing a handler function called onKeyup. This will allow me to both add and remove an event listener in two functions that are declared within the same object. Can you suggest how I can acce ...

Troubleshooting the Owl carousel's responsiveness with a div width of 1170px

Whenever my display size is less than 1170px, the width of the owl carousel div overflows. How can I fix this issue? jQuery(document).ready(function($) { "use strict"; // CUSTOMERS TESTIMONIALS CAROUSEL $('#customers-testimonials&a ...

Instantly reveal menu by pressing button

Is there a way to make my mobile menu open immediately upon touching the button? I have used ontouchstart="" in both buttons to create an overlay on the content when the offcanvas menu is visible. This functions well as soon as the user touches either butt ...

Having a flash video load on a new page in the same position as it was on the previous page

On my website, I have a subtle flash video playing in the background that loops every 30 seconds. It's not necessary for navigation, just a nice visual touch. However, every time a new page is loaded, the video restarts from the beginning. I'm l ...

Tips for showcasing a date using date-fns tailored in a Mui DatePicker as Thursday, January 13th

I'm currently working on a project using CodeSandbox to format dates as dddd, MMMM Do. The expected output is Thursday, January 13th, but instead I'm receiving 0013, January 13th. According to the date-fns documentation found at Date-fns format, ...

Incorporating the angular UI router effectively by reusing the same templateUrl and controller multiple times

Exploring the AngularUI Router framework for the first time, I am curious about how to enhance the code snippet below. Everything is functioning well at the moment, but as the project progresses, it will feature 20 questions or more. I want to avoid repea ...

"The onkeydown event dynamically not triggering for children elements within a parent element that is contentEditable

Can anyone offer some insights into why this code isn't functioning as expected? My goal is to attach the listener to the children elements instead of the body so that I can later disable specific keystrokes, such as the return key. <!DOCTYPE html ...

Placing an image onto a THREE.js plane

Whenever I attempt to place a .png image on my plane, it simply vanishes. Could it be that THREE.js isn't compatible with Vue.js? Is there another 3D library that supports Vue.js? I'm also interested in adding an SVG, but I haven't quite f ...

Unraveling unicode escape sequences in JavaScript strings

My code includes a string like \uC88B\uC544\uC694. When I use this string in a node repl (v7.4.0), it displays '좋아요' correctly. However, when I try to use the same string in the following code snippet, it does not work as ex ...

Enhancing serialized form with additional information through an ajax request

I'm currently facing an issue with adding additional data to my serialized form string. The situation is that I have a form with a set of fields called "Services", and users are able to add as many services as they want dynamically using a button in t ...

There are a total of 152 issues found in the index.tsx file within the react

Despite everything working correctly, I am continuously encountering these errors. Is this a common occurrence? What steps can I take to resolve them? I have developed my react application using Javascript instead of Typescript; however, I don't belie ...

What is causing the unexpected behavior of deferred.resolve in the q manual?

I can't seem to grasp this concept and it might be a silly question. Let's analyze the code snippet below: function throwError() { throw Error("can't touch this."); } var def = q.defer(); def.promise.then( function() { co ...

Switch button while moving cursor

I'm struggling with getting this 2048x512 image, which has 4 stages of transition, to work properly. https://i.sstatic.net/1PBvX.png While I know how to switch it to the final stage on hover, I can't seem to figure out how to incorporate a trans ...

Passing the value of an Angular component to a different component

I have a menu in my application that uses IDs to route content, and I also have a detailed view where the content should be displayed based on those same IDs. Currently, I am trying to display objects by their ID when a button is clicked. However, I' ...