3D Computer Graphics with Three.js in a web application

People interact with each other in three-dimension daily. Even though technology evolved, each interaction of the end-user with an application was still done on a two-dimensional representation. With the development of WebGL and using different JavaScript 3D libraries, this limitation vanished. Many companies were encouraged by the progress of 3D technology to integrate a 3D viewer for their products. Finally, the end-user can see various 3D content in his interaction with the application.

Author: Mirel Gabriel Albu

Three.js

What is Three.js?

Three.js is a JavaScript library built on top of WebGL that offers the possibility of rendering 3D computer graphics directly on the browser. Since its initial release in 2010, Three.js grew organically because of its enthusiastic community, remaining a valuable solution for integrating 3D content.

Why would you use Three.js?

Three.js is a lightweight library that does not rely on many dependencies. The performance represents a significant benefit of being a lightweight library. For somebody with little experience rendering 3D content in a web browser, the vast number of examples and good documentation offers a perfect place to start.

How to integrate Three.js?

Integrating 3D computer graphics into a part of the application is quickly done with Three.js. But first, it is essential to understand some core 3D terminology.

Achieving the perfect illustration of rendering 3D content using Three.js is like shooting a movie. For the ideal result, you will need:

  • an actor - represented in Three.js by a Mesh (a base class that inherits Object3D);
  • a location - characterized in Three.js by a Scene (the place where the 3D object is rendered);
  • a cameraman - exemplified in Three.js by a camera (E.g., PerspectiveCamera, OrthographicCamera, or CubeCamera);
  • the movement capability for the cameraman - is characterized in Three.js by different types of controls (E.g., OrbitControls, FlyControls, or TrackballControls)
  • good lighting - represented in Three.js by different types of lights (E.g., AmbientLight, DirectionalLight, HemisphereLight, PointLight, or SpotLight)
  • the one that shouts action - illustrated in Three.js by WebGLRenderer, giving that tremendous 3D experience.

Step 1 – Creating the Scene

const scene = new THREE.Scene();

Step 2 – Creating the Mesh

const geometry = new THREE.BoxGeometry( 200, 200, 200 );
 
const material = new THREE.MeshLambertMaterial();
 
const mesh = new THREE.Mesh( geometry, material );

Step 3 – Creating the Camera

const camera = new THREE.PerspectiveCamera( 
    40, window.innerWidth / window.innerHeight, 1, 100 );

Step 4 – Creating the Light

const light = new THREE.AmbientLight( 0x404040 );

Step 5 – Creating the Renderer

const rendere = new THREE.WebGLRenderer( { antialias: true } );

Step 6 – Creating the Controls

const controls = new OrbitControls(camera, renderer.domElement);

Step 7 – Call Action

const animate = () => {
  requestAnimationFrame(animate);
  renderer.render(scene, camera);
};

When you wrap all these steps together, you can easily integrate a 3D immersive experience into your application.

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta
      name="viewport"
      content="width=device-width, user-scalable=no, 
               minimum-scale=1.0, maximum-scale=1.0"
    />
  </head>
  <body>
    <script
      async
      src="https://unpkg.com/es-module-shims@1.3.6/dist/es-module-shims.js"
    ></script>
    
    <script type="importmap">
      {
        "imports": {
          "three": "https://unpkg.com/three@0.126.1/build/three.module.js"
        }
      }
    </script>
    
    <script type="module">
      
      import * as THREE from "three";
      import { OrbitControls } 
      from "https://unpkg.com/three@0.128.0/examples/jsm/controls/OrbitControls.js";
      
      let camera, scene, light, controls, renderer, mesh;
      
      init();
      animate();
      
      function init() {
        
        /** Step 1  - Create Scene */
        scene = new THREE.Scene();
        scene.background = new THREE.Color(0xffffff);

        /** Step 2  - Create the Mesh */        
        const geometry = new THREE.BoxGeometry(200, 200, 200);
        const material = new THREE.MeshLambertMaterial();
        mesh = new THREE.Mesh(geometry, material);
        
        scene.add(mesh);
        
        /** Step 3  - Create Camera */
        camera = new THREE.PerspectiveCamera(
          70,
          window.innerWidth / window.innerHeight,
          1,
          1000
        );
        camera.position.z = 400;
        
        /** Step 4  - Create Light */
        light = new THREE.HemisphereLight(0xffffff, 0x404040);
        scene.add(light);
        
        /** Step 5  - Create Renderer */
        renderer = new THREE.WebGLRenderer({ antialias: true });
        renderer.setPixelRatio(window.devicePixelRatio);
        renderer.setSize(window.innerWidth, window.innerHeight);
        
        /** Step 6  - Create Controls */
        controls = new OrbitControls(camera, renderer.domElement);
        
        document.body.appendChild(renderer.domElement);
        window.addEventListener("resize", onWindowResize);
      }
      
      function onWindowResize() {
        camera.aspect = window.innerWidth / window.innerHeight;
        camera.updateProjectionMatrix();
        
        renderer.setSize(window.innerWidth, window.innerHeight);
      }
      
      /** Step 7  - Call Action */
      function animate() {
        requestAnimationFrame(animate);
        
        mesh.rotation.x += 0.005;
        mesh.rotation.y += 0.01;
        
        renderer.render(scene, camera);
      }
      
    </script>
  </body>
</html>