Import 3D models to three.js

Published on Mar 8, 2021

Reading time 3 min

I’ve found threejs pretty tricky at the current state of the library. They are always making improvements and breaking some applications with the new updates. So here, I"m going to talk about how I’ve found it’s good to structure your threejs application for importing 3D objects. Here is a working example.

Basic Setup

The current version of threejs doesn’t require any special tags in the HTML, only the <script type="module"> tag where we are going to develop the logic of the program.

When using type="module" we can use the features of es5 such as import so we are going to use them. We have to import threejs and GLTFLoader. And any other component you use, such as OrbitControls. I’m going to define some variables gloablly as I’m assigning them afterwards in the init() function. You can extend on the configuration in this function in the documentation

import * as THREE from 'https://unpkg.com/[email protected]/build/three.module.js';
import { GLTFLoader } from 'https://unpkg.com/three/examples/jsm/loaders/GLTFLoader.js'

let camera, scene, renderer, loader, model;

init();
animate()

function init () {
    scene = new THREE.Scene();
    camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 );
    renderer = new THREE.WebGLRenderer({ antialias: true})
    loader = new GLTFLoader();

    // renderer
    renderer.setSize( window.innerWidth, window.innerHeight );
    renderer.setClearColor("#121212") // set the background color
    document.body.appendChild( renderer.domElement );

    camera.position.z = 3;
}

function animate() {
    requestAnimationFrame( animate );
    renderer.render( scene, camera );
}

For adjusting the size when changing resizing the window we have to add an event listener and to change both the aspect ratio and the size of the renderer.

function init () {
    // ...
    window.addEventListener('resize', onWindowResize);
}

function onWindowResize() {
    camera.aspect = window.innerWidth / window.innerHeight;
    camera.updateProjectionMatrix();
    renderer.setSize( window.innerWidth, window.innerHeight );
}

Loading object

Now we have to load the object and define the lighting for the scene.

function init () {
    // ...

    // ambient light
    const ambientLight = new THREE.AmbientLight ( 0xffffff, 0.2)
    scene.add( ambientLight )

    // point light
    const pointLight = new THREE.PointLight( 0xffffff, 1 );
    pointLight.position.set( 30, 50, 25 );
    scene.add( pointLight );

    loader.load( '/path/to/object.gltf', function ( gltf ) {
        model = gltf.scene // assign the model to the global variable
        scene.add( model );

    }, undefined, function ( error ) {
        console.error( error );
    } );
}

Animation

To add a simple animation rotation to the model we have to add or substract to the rotation of the object in every animation frame, for example. However, there are much more ways of animating and with different purposes.

function animate() {
    requestAnimationFrame( animate );
    if (model) {
        model.rotation.y -= 0.01
    }     
    renderer.render( scene, camera );
}

Complete implementation

You can check to the complete implementation in this Github gist.