Here are all the things you need to get started with Three.JS.

Server setup

Express setup for Three.JS

How to make a basic scene

First create your html page.

You will need:

  • An element to attach the scene to. I'm using the body tags for this.

  • The Three.JS library included. Could use the node module if your app contains a transpiler.

  • The JavaScript for creating a scene.

<!DOCTYPE html>
<html>
  <head>
    <meta charset=utf-8>
    <title>Web Viewer</title>
    <link type="text/css" rel="stylesheet" href="main.css">
  </head>
  <body>
    <script src="public/three.min.js"></script>
    <script src="index.js"></script>
  </body>
</html>

*Bonus: If you want css to fix the margins so that you don't have any scrolling nonsense going on, you can add a main.css file like I have in the HTML above and add:

body {
  margin: 0;
  overflow: hidden;
}

The way I'm including the javascript is by including it after the body tag was created and the three.js library was imported.

In index.js in the same location as index.html, there are around 6 things needed to create a basic scene in Three.JS:

  // 1. Create the scene
  var scene = new THREE.Scene()
  // 2. Add a camera view
  var camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 )
  camera.position.z = 10
  // 3. Add a renderer to generate the camera's picture
  var renderer = new THREE.WebGLRenderer()
  renderer.setSize( window.innerWidth, window.innerHeight )
  // 4. Attach what we're rendering to the web page
  document.body.appendChild( renderer.domElement )
  // 5. Lighting + Objects
  var geometry = new THREE.BoxGeometry(2, 2, 2)
  var material = new THREE.MeshLambertMaterial({color: 0xfd59d7})
  var cube = new THREE.Mesh(geometry, material)
  scene.add(cube)

  var light = new THREE.PointLight(0xFFFF00)
  light.position.set(10, 0, 25)
  scene.add(light)

  // 6. Run the renderer
  var animate = function () {
    requestAnimationFrame( animate );

    cube.rotation.x += .1;
    cube.rotation.y += .1;
    camera.updateProjectionMatrix();

    renderer.render(scene, camera);
  };

  animate();

Creating a Background in Three.JS

The regular way to create a background is by setting this.scene.background to one of the three THREE classes: Color, Texture, or CubeTexture. For a surrounding background (e.g. panorama/cubemap) we want CubeTexture.

Let's start from the basics just to make sure we can get the background to change, and then increase the complexity from there.

Color background

To add a color as a background, we can do:

scene.background = new THREE.Color( 0xf0f0f0 )

There are a bunch of operations you can use to create a color with this class.

Texture Background

Lay a background that always is on the back of the canvas.

I copied the textures pack that is in the Three.JS repo here to assets/textures.

var texture = new THREE.TextureLoader().load( "assets/textures/water.jpg" );
texture.wrapS = THREE.RepeatWrapping;
texture.wrapT = THREE.RepeatWrapping;
texture.repeat.set( 4, 4 );
this.scene.background = texture;

Note: The middle three lines are extras essentially saying we want to repeat in the horizontal plane wrapS, the vertical plane wrapT and also repeat 4 time by 4 times. Otherwise, only keeping the first and last line stretches the image to the canvas.

If you try to move the scene around once you have controls built in (why not build them in now? Skip to Controls), you'll see that the background stays static. Kinda sucks, but I guess there may be a use for this.

CubeTexture Background

This is what we want for panoramas.

We can use a CubeTextureLoader to select the path of where all of our images are, and then load them as an array of images:

    var texture = new THREE.CubeTextureLoader()
    .setPath( 'assets/textures/cube/Bridge2/' )
    .load( [
      'posx.jpg',
      'negx.jpg',
      'posy.jpg',
      'negy.jpg',
      'posz.jpg',
      'negz.jpg'
    ] );
    this.scene.background = texture;

CubeTexture Background from a single image

This part is going to take some effort. There is an example here that does this.

I don't really like how they accomplish this with creating a 1x1x1 cube in the scene painted with the sides of the image, so I've externalized the steps to creating this scene here:

Boxgeometry Background Hack

Creating Controls

Be able to grab and drag the scene around. These don't seem to be built in, but some of the examples in the Three.JS repo has some things we can extract out of it.

  • Copy out the file from examples/js/controls/OrthographicTrackballControls.js to a place that makes sense to you in your repo. I placed it in assets/js/controls.

  • Open your html page and add a reference to that script:

<script src="../assets/js/controls/OrbitControls.js"></script>

Note: Be sure this is before your main Three.JS logic so you can use it immediately.

  • Add these lines somewhere. The this reference is because I'm actually creating a Visualizer instance and doing all of this inside the Visualizer class.
this.controls = new THREE.OrbitControls( this.camera, this.renderer.domElement );
this.controls.enableZoom = false;
this.controls.enablePan = false;
this.controls.enableDamping = true;

Feel free to remove the last three lines if you don't want those settings on.

Creating Objects

We can make a lot of different kinds of objects with different kinds of materials. I'm going to skip a bunch and go straight to sprites as this is what I'm dealing with right now.

Creating a sprite

We'll just place a regular sprite off-center in the scene:

const spriteMap = new THREE.TextureLoader().load( "../assets/textures/sprite2.png" );
const spriteMaterial = new THREE.SpriteMaterial( { map: spriteMap, color: 0xffffff } );
const sprite = new THREE.Sprite( spriteMaterial );

sprite.position.z = 10

this.scene.add( sprite );