Search code examples
aframe

Aframe ambient light not work with gltf model


I tried a easy aframe demo with glft

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Test</title>
    <script src="../../../dist/aframe-master.js"></script>
    <script src="js/aframe-extras.loaders.min.js"></script>
  </head>
  <body>
    <a-scene  >
     <a-entity light="type: ambient; intensity: 0.2"></a-entity>        
<a-entity     
        gltf-model="assets/cow02.glb"
        scale="100 100 100"
         rotation='0 0 0'
         animation="property: rotation; to: 0 360 0; loop: true; dur: 20000"
        position="-2 1 -5"
      > 
      </a-entity>     
    </a-scene>
  </body>
</html>

and now the issue is this ambientlight <a-entity light="type: ambient; intensity: 0.2"></a-entity> not working ,I mean nothing change after add this light.


Solution

  • I'm not sure how the gltf-loader decides what material to use, but it seems Your models material is simple enough to be interpreted as a MeshBasicMaterial. According to the docs - it is not affected by any lights.

    Probably if You'd set the metalness, roughness, add a normal map - the loader would use a MeshStandardMaterial (or any other with those properties - which are affected by lighting).

    If you want to change the material using three.js, you could write a component like this:

        // wait until the model is loaded
        this.el.addEventListener("model-loaded", e => {
          // grab the mesh 
          let model = this.el.getObject3D("mesh");
          // find the node with the basic material     
          model.traverse(function(node) {
            // ignore bones and other nodes without any material 
            if (!node.material) return;
    
            // keep the reference to the old material - we want to dispose it later
            var tmp = node.material
            // substitute the material     
            node.material = new THREE.MeshStandardMaterial({
               skinning: true, // the original material is using skinning
               map: node.material.map // we want the original texture
            });
            // update and clean up
            node.material.needsUpdate = true;
            tmp.dispose()
          }
        })
    

    Check it out in this glitch.