Three.js: MeshPhongMaterial does Not react to lighting

Created on 2 Dec 2019  路  2Comments  路  Source: mrdoob/three.js

MeshPhongMaterial does Not react to lighting

Setup: https://codepen.io/chen-xu/pen/XWJWbwj

  1. AmbientLight
  2. PointLight
  3. A loaded GLTF model.

I loaded a GLTF model with textures using GLTFLoader, and it is using default MeshStandardMaterial, everything is loaded correctly, but I want to replace all MeshStandardMaterial to MeshPhongMaterial, so I just looped through all materials and replace them with MeshPhongMaterial, something like:

  gltfScene.traverse( ( child ) => {
    if ( child.isMesh ) {
        child.material = new THREE.MeshPhongMaterial();
    }
  } );

However, all the meshes turn into the color of AmbientLight, and PointLight does not have any effect on the replace MeshPhongMaterial any more.

Here is a codepen I created https://codepen.io/chen-xu/pen/XWJWbwj, you will see the bug occurs when you click on Replace Horse Mesh to MeshPhongMaterial button. I also created two SphereBufferGeometry, 1 is MeshPhongMaterial, and 1 is MeshStandardMaterial, when you toggle on these two, the lighting effect is still there.

Three.js version
  • [x] r111
Browser
  • [x] All of them
  • [ ] Chrome
  • [ ] Firefox
  • [ ] Internet Explorer
OS
  • [x] All of them
  • [ ] Windows
  • [ ] macOS
  • [ ] Linux
  • [ ] Android
  • [ ] iOS
Help (please use the forum)

Most helpful comment

The problem is that your glTF model has no normal data. Hence, you have to set Material.flatShading to true to achieve a similar material setting as before. So this should solve the issue:

gltfScene.traverse( ( child ) => {
    if ( child.isMesh ) {
        child.material = new THREE.MeshPhongMaterial( { flatShading: true } );
    }
  } );

Please use the forum or stackoverflow for more help.

All 2 comments

The problem is that your glTF model has no normal data. Hence, you have to set Material.flatShading to true to achieve a similar material setting as before. So this should solve the issue:

gltfScene.traverse( ( child ) => {
    if ( child.isMesh ) {
        child.material = new THREE.MeshPhongMaterial( { flatShading: true } );
    }
  } );

Please use the forum or stackoverflow for more help.

@Mugen87 it works now!, thanks !

Was this page helpful?
0 / 5 - 0 ratings