Using Threejs to Display 3D Model

Page content

Hi everyone!

Three.js is a popular JavaScript library used to display 3D graphics in a web browser using WebGL. It is especially useful when developing AR/VR based applications.

A simple implementation could involve rendering a 3D model on the browser. Three.js provides a base class Loader through which developers can load 3D models depending upon the type of the model. The .obj file format is one of the most common formats for 3D models. However, if one is looking for an animated 3D model then perhaps an .fbx file format should suffice.

Here’s a small demo of how one I can load an animated 3D model (. fbx) using Three.js.

Create new Node.js based app and add dependencies

npm init threejs_node_javascript
npm install three three-fbx-loader --save

Create a simple HTML page to load the scripts

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <title>threejs demo</title>
    <style>
      body {
        margin: 0;
      }
      canvas {
        display: block;
      }
    </style>
  </head>
  <body>
    <div id="root"></div>
    <div>
        <button onclick="startRotatingModel()">Start rotating model</button>
    </div>
  </body>
  <script type="text/javascript" src="js/three.js"></script>
  <script type="text/javascript" src="js/FBXLoader.js"></script>
  <script type="text/javascript" src="js/ar.js"></script>
</html>

Add new script to load 3D model

ar.js


'use strict';

let renderer, camera, scene;
let loader, clock;
let ar_model;

function main() {
  // setup the WebGL renderer
  renderer = new THREE.WebGLRenderer({antialias: true});
  renderer.setSize(800, 600);
  document.body.appendChild(renderer.domElement);

  // setup the camera
  camera = new THREE.PerspectiveCamera(30, 800 / 600, 1, 10000);
  camera.position.set(0, 10, 100);
  camera.up.set(0, 1, 0);
  camera.lookAt(new THREE.Vector3(0, 0, 0));

  // setup the scene and lights
  scene = new THREE.Scene();
  scene.background = new THREE.Color(0xffffff);
  scene.add(new THREE.AmbientLight(0xcccccc));

  // load fbx model and texture
  const objs = [];
  loader = new THREE.FBXLoader();
  loader.load('../models/xsi_man_skinning.fbx', model => {
    // model is a THREE.Group (THREE.Object3D)
    const mixer = new THREE.AnimationMixer(model);
    // animations is a list of THREE.AnimationClip
    mixer.clipAction(model.animations[0]).play();
    ar_model = model;
    scene.add(model);
    objs.push({model, mixer});
  });

  // animation rendering
  clock = new THREE.Clock();
  (function animate() {
    // animation with THREE.AnimationMixer.update(timedelta)
    objs.forEach(({mixer}) => {
      mixer.update(clock.getDelta());
    });
    renderer.render(scene, camera);
    requestAnimationFrame(animate);
  })();
  return objs;
}

function startRotatingModel() {
  console.log('start rotating the model');
  (function animate() {
    if (ar_model != null) {
      ar_model.rotation.y += 0.01;
    }
    renderer.render(scene, camera);
    requestAnimationFrame(animate);
  })();
}

const objs = main();

The WebGLRenderer is mainly responsible for displaying the scenes using WebGL. Please ensure that the scene is setup correctly with proper lighting for the 3D model to be visible. Sometimes, due to improper lighting the model appears black. Finally, the The AnimationMixer is used for playing animations on a particular object (in this case our 3D model) in the scene.

Output

Before rotating the model

threejs-display-3d-model-1

After rotating the model

threejs-display-3d-model-2

In this way, one could load a simple 3D model and manipulate it based on what action needs to be done. In addition, there are many different loaders available that one can use. Here is a link that contains more examples using Three.js.

Hope this post was useful to you. Stay tuned for more! 😄