Search code examples
javascripthtmlthree.js3dgltf

THREE.js GLTFLoader does not works on loading the 3D model


Hi I am facing a problem on cannot display the 3D model THREE.js GLTFLoader(), the following is my script:

Here is the html file:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <link rel="stylesheet" href="./style.css" />
    <title>Document</title>
  </head>
  <body>
    <nav>
        <ul>
            <li>hey</li>
            <li>heysda</li>
        </ul>
    </nav>
    
    <div class="scene"></div>
    <script src="./three.min.js"></script>
    <script src="./GLTFLoader.js"></script>
    <script src="./app.js"></script>
  </body>
</html>

here is the js file:

//Variables for setup

let container;
let camera;
let renderer;
let scene;
let house;

function init() {
  container = document.querySelector(".scene");

  //Create scene
  scene = new THREE.Scene();

  const fov = 35;
  const aspect = container.clientWidth / container.clientHeight;
  const near = 0.1;
  const far = 1000;

  //Camera setup
  camera = new THREE.PerspectiveCamera(fov, aspect, near, far);
  camera.position.set(0, 0, 100);

  const ambient = new THREE.AmbientLight(0x404040, 2);
  scene.add(ambient);

  const light = new THREE.DirectionalLight(0xffffff, 2);
  light.position.set(50, 50, 100);
  scene.add(light);
  //Renderer
  renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });
  renderer.setSize(container.clientWidth, container.clientHeight);
  renderer.setPixelRatio(window.devicePixelRatio);

  container.appendChild(renderer.domElement);

  //Load Model
  let loader = new THREE.GLTFLoader();
  loader.load("./house/scene.gltf", function(gltf) {
    scene.add(gltf.scene);
    house = gltf.scene.children[0];
    animate();
  });
}

function animate() {
  requestAnimationFrame(animate);
  house.rotation.z += 0.005;
  renderer.render(scene, camera);
}

init();

function onWindowResize() {
  camera.aspect = container.clientWidth / container.clientHeight;
  camera.updateProjectionMatrix();

  renderer.setSize(container.clientWidth, container.clientHeight);
}

window.addEventListener("resize", onWindowResize);

I ran the code on notepad++ and chrome browser, but it turned out blank screen without showing my 3D model.

Anyone knows the solution? thanks in advance!


Solution

  • The way how you work with container is problematic since clientHeight is zero when you access it to compute the aspect ratio. I suggest you start with using window.innerWidth and window.innerHeight at the beginning.

    Besides, there are two minor issues with your model. The model has an extreme scale so you won't see it with your current camera position. You are way too close. Besides, the model has an offset so it's recommended to center it. Try it with this code:

    //Variables for setup
    
    let camera;
    let renderer;
    let scene;
    let house;
    
    init();
    
    function init() {
    
        //Create scene
        scene = new THREE.Scene();
    
        const fov = 60;
        const aspect = window.innerWidth / window.innerHeight;
        const near = 0.1;
        const far = 1000;
    
        //Camera setup
        camera = new THREE.PerspectiveCamera( fov, aspect, near, far );
        camera.position.set( 0, 0, 5 );
    
        const ambient = new THREE.AmbientLight( 0xffffff, 0.4 );
        scene.add( ambient );
    
        const light = new THREE.DirectionalLight( 0xffffff, 0.8 );
        light.position.set( 0, 0, 10 );
        scene.add( light );
    
        //Renderer
        renderer = new THREE.WebGLRenderer( { antialias: true } );
        renderer.setPixelRatio( window.devicePixelRatio );
        renderer.setSize( window.innerWidth, window.innerHeight );
        document.body.appendChild( renderer.domElement );
    
        //Load Model
        const loader = new THREE.GLTFLoader();
        loader.load( './house/scene.gltf', function ( gltf ) {
    
            house = gltf.scene;
    
            // scale model down
    
            house.scale.setScalar( 0.001 );
    
            // center it
    
            const box = new THREE.Box3().setFromObject( house );
            const center = box.getCenter( new THREE.Vector3() );
    
            house.position.x += ( house.position.x - center.x );
            house.position.y += ( house.position.y - center.y );
            house.position.z += ( house.position.z - center.z );
    
            scene.add( house );
    
            animate();
    
        } );
    
    }
    
    function animate() {
    
        requestAnimationFrame( animate );
        renderer.render( scene, camera );
    
    }
    
    function onWindowResize() {
    
        camera.aspect = window.innerWidth / window.innerHeight;
        camera.updateProjectionMatrix();
    
        renderer.setSize( window.innerWidth, window.innerHeight );
    
    }
    
    window.addEventListener( 'resize', onWindowResize );