Visually Mapping out 3D with Three.js
Published: 2020-08-07 15:14:46

Every developer has their favorite tools, languages, and technologies to work with. Sometimes it derives from another passion such as solving mathematical problems, white-hat hacking, or organization. Luckily, open-source technologies allow everyone to pick up their tool of choice and create something amazing. Now let me show you how you can leverage one of my favorite tools, [Three.js](https://threejs.org/)

What is Three.js?
=================

Three.js is a JavaScript library for creating, rendering, and even animating 3D graphics in the browser. If you are into developing web-based games, creating web animations, or creative coding, this would be a great option to explore.

Under the hood, Three.js utilizes a low-level API called [WebGL](https://get.webgl.org/). The creator of Three.js, Ricardo Cabello (Mr.doob), knew the complexities of WebGL and simplified it into an easily accessible library for any developer to utilize.

Overview
========

There's a lot this library is capable of, but for this article, I will just be focusing on the process of setting up a [three.js scene](https://threejs.org/docs/#manual/en/introduction/Creating-a-scene). Personally, this was the most difficult part to remember. As a visual learner, I had to use mental images to understand how a 3D scene could be produced on a flat-screen.

*Disclaimer: Practice coding out the set up every time you start a new project. This process will never change but if you copy and paste the setup you won't understand why certain things aren't working as expected.*

*Also, Three.js is a Javascript library. There may be a fair amount of references to Object-Oriented Programming and the Javascript language.*

With that being said. Let's begin!

![Image for post](https://miro.medium.com/max/1686/1*AhUaM6RFqWK6SBsxkswagQ.png)


Setting up Three.js
===================

*To start off with a metaphoric example. Pretend you are building a stage set for a play. Right now your stage is empty, but you need to add things to it before your actors and actresses can use it.*

Setting up Three.js is very similar to that scenario above. You start with one Scene and pull the parts needed into that scene.

Here are the things you will need: [Scene](https://threejs.org/docs/#api/en/scenes/Scene), [Camera](https://threejs.org/docs/#api/en/cameras/Camera) and [Renderer](https://threejs.org/docs/#api/en/renderers/WebGLRenderer)

Scene
-----

[The Scene allows you to set up what is to be rendered by three.js. This is where you place objects, lights, and cameras.](https://threejs.org/docs/#api/en/scenes/Scene)

Your scene is the first component you will set up. Three.js uses the [Object-Oriented Paradigm](https://en.wikipedia.org/wiki/Object-oriented_programming) so Scene is an [Object Constructor](https://medium.com/@likewaterdesignco/creating-an-object-using-constructors-in-javascript-c1b33e07b3e2). This allows you to create one or more instances of Scene and use it in your app. [*If your unfamiliar with Constructors check out this article*](https://medium.com/@likewaterdesignco/creating-an-object-using-constructors-in-javascript-c1b33e07b3e2).

![Image for post](https://miro.medium.com/max/613/1*am039nNsJJbZptDIm1Q1tw.jpeg)


Camera
------

[The Camera is an abstract base class for cameras. This class should always be inherited when you build a new camera.](https://threejs.org/docs/#api/en/cameras/Camera)

The next thing you will need to set up is your Camera. Just like setting up a stage for a performance or show, the camera is one of the most essential objects needed to capture everything within the scene.

Similarly to the Scene, the Camera is just another Object Constructor.

![Image for post](https://miro.medium.com/max/613/1*fzTRtIv_rG9sYEMI1asOgg.jpeg)

Renderer
--------

Once your Scene and Camera are set up, you will need to add them to your app. Like any other web components, you'll have to add the Scene to the [Document Object Model](https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model/Introduction). This is where the Renderer comes in.

Three.js uses a Constructor called [WebGLRenderer](https://threejs.org/docs/#api/en/renderers/WebGLRenderer) to add your Scene and Camera to the DOM. The Three.js documentation states, "[The WebGL renderer displays your beautifully crafted scenes using WebGL](https://threejs.org/docs/#api/en/renderers/WebGLRenderer)".

![Image for post](https://miro.medium.com/max/613/1*cAkigSUG63EaKfslHQcu9Q.jpeg)

Recap
=====

So to recap the visuals above:

1.  Create a Scene
2.  Set up a Camera
3.  Add a Renderer
4.  Place the Scene and Camera into the Renderer

These are the initial steps to create a scene and add it to your application.

The Code
========

Now that you have a visual idea of how the Scene, Camera, and Renderer work, you are better suited for understanding the code.

Below is the Javascript code for setting up a Three.js project. I'll go over each section in detail.

*Disclaimer: I recommend using *[*CodePen*](https://codepen.io/)* to follow along. This will allow us to focus only on the Javascript set up.*

```
let scene, camera, renderer;
init();
function init(){
    scene = new THREE.Scene();
    camera = new THREE.PerspectiveCamera(75, window.innerWidth /    window.innerHeight, 0.01, 1000);
    camera.position.set(0,0,10);
    
    renderer = new THREE.WebGLRenderer();
    renderer.setSize(window.innerWidth, window.innerHeight);
    
    document.body.appendChild(renderer.domElement);
    
    window.addEventListener('resize', resize, false);
    
    update();
}

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

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

Set variables
-------------

Initialize your global variables. We're making these variables global in order to access them in all of our functions. When working on a real application, you will most likely have these within the scope of your 3D component, so they don't clash with other components of your application.

```
let scene, camera, renderer;
```

Create Initialize function
--------------------------

The initialization, also known as the init function, is the main function that holds all your three.js objects. This includes your Scene, Camera, and Renderer.

```
init()
function init(){ 
//threejs init code goes here
}
```

Create a Scene
--------------

Within the init function you will create a Scene, Camera, and Renderer instance.

```
let scene, camera, renderer;
function init(){
    scene = new THREE.Scene();
    camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.01, 1000);
    camera.position.set(0,0,10);
    renderer = new THREE.WebGLRenderer();
    renderer.setSize(window.innerWidth, window.innerHeight);
}
```

Camera Setup
------------

```
camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.01, 1000);
camera.position.set(0,0,10);
```

The Perspective Camera constructor takes 4 arguments:

1.  Point of View --- I usually start with 75
2.  Aspect Ratio --- the window's inner width divided by the window's inner height
3.  Near Clipping Path
4.  Far Clipping Path

Clipping Paths are the limits in which your scene can be seen. In this example, anything before 0.01 and anything farther than 1000 will disappear. For a better description check the [PerspectiveCamera](https://threejs.org/docs/#api/en/cameras/PerspectiveCamera).

After your Camera is set you'll need to position your camera. A good start could be:

```
// positions.set parameters are (x,y,z) axis\
camera.position.set(0,0,20);
```

Renderer Setup
--------------

To create the renderer, you'll need to use the [WebGLRenderer](https://threejs.org/docs/#api/en/renderers/WebGLRenderer) Constructor. Once created, you can use the setSize method to set the renderer size to fit the whole screen.

```
renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
```

Create a DOM Element
--------------------

Once your Scene, Camera, and Renderer is set up, we now have to create the [canvas](https://www.w3schools.com/html/html5_canvas.asp) which will house all the components. The [canvas](https://www.w3schools.com/html/html5_canvas.asp) will also allow us to display our 3D application in the [DOM](https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model/Introduction). The WebGLRenderer's has a method called [domElement](https://threejs.org/docs/#api/en/renderers/WebGLRenderer.domElement). When [domElement](https://threejs.org/docs/#api/en/renderers/WebGLRenderer.domElement) is called it will display the canvas to the [DOM](https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model/Introduction).

```
renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement)
```

Resize and Update Functions
---------------------------

Lastly, we need to create two essential functions and call them inside your init function.

1.  resize --- a function to resize your application on tablet and mobile.
2.  update --- a function to render the scene and camera and update them every frame.

```
let scene, camera, renderer;

init();

function init(){
    // init code goes here
}

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

//update function
function update(){
  requestAnimationFrame(update);
  renderer.render(scene, camera);
}
```

Final Steps
-----------

Both the resize and update functions will be called within the init function. Lastly, call the init function, if the screen turns black, that means you've just rendered your first Three.js scene!

You're now set up to start adding geometry to your scene. Check out the [Three.js documentation](https://threejs.org/docs/#api/en/geometries/BoxGeometry) for more information.

View the final steps below.

```
let scene, camera, renderer;

init();

function init(){

//scene
scene = new THREE.Scene();
  
//camera
camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.01, 1000);
camera.position.set(0,0,10);
  
//renderer
renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
  
//render to dom  
document.body.appendChild(renderer.domElement);
  
// call resize function on resize
window.addEventListener('resize', resize, false);
  
//update
update();
}

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

//update function
function update(){
  requestAnimationFrame(update);
  renderer.render(scene, camera);
}
```

See code in action below
------------------------
https://codepen.io/lwdstudio/pen/NWxKWdb