(click anywhere to close)

[Three.js] Tutorial for Professionals!

category: Games | course: Threejs | difficulty:

If you've read the beginner and advanced tutorials, you can create all basic types of objects and make them appear via lightning and materials. Here I'll teach you how to take it one step further and create some more varied visuals.


Fog applied throughout the whole world:

//Fog(color of the fog, min distance to apply fog, max distance)
scene.fog = new THREE.Fog( hex, near, far )

Different Cameras

Next to the perspective camera we've introduced earlier, there's also anorthographic camera. This displays the world as though it was 2D, so it's best use would be for a 2D game or the 2D GUI/HUD of a game.

// left, right, top, bottom, near, far
var camera = new THREE.OrthographicCamera( width / - 2, width / 2, height / 2, height / - 2, 1, 1000 );

scene.add( camera );

And last but not least, cameras come with the useful featurelookAt to make it look at certain points (Vector3's) in the world or objects.

//It's useful to first set the 'up' value for the camera, to make sure it's properly rotated
camera.up = new THREE.Vector3(0,0,1);

//Then make it look at the origin
camera.lookAt(new THREE.Vector3(0,0,0));


Every material has a certain.map property, which you can assign a certain texture you loaded earlier (you'll learn about loading stuff in a second). Like this:

var cubeTexture = //some image loaded here.. (you'll learn that in a few paragraphs)
var cubeMaterial = new THREE.MeshLambertMaterial({ map: cubeTexture });

Another possibility is to draw something using JavaScript's canvas and then assign that as a texture. The following code draws a canvas with black/white stripes alternating and then creates a texture from it:

var canvas  = document.createElement( 'canvas' );
canvas.width = 32;
canvas.height    = 64;
var context = canvas.getContext( '2d' );

context.fillStyle = '#ffffff';
context.fillRect( 0, 0, 32, 64 );

for( var y = 2; y < 64; y += 2 ){
  for( var x = 0; x < 32; x += 2 ){
      var value   = Math.floor( Math.random() * 64 );
      context.fillStyle = 'rgb(' + [value, value, value].join( ',' )  + ')';
      context.fillRect( x, y, 2, 1 );

var texture  = new THREE.Texture(canvas);


There are a few things you're most likely to be loading throughout your Three.js career: images, materials and 3D objects made in external software.

new THREE.ImageLoader.load(url, onLoad, onProgress, onError);

new THREE.MaterialLoader.load(url, onLoad, onProgress, onError);

//3D Objects
//You'll most likely need an exporter for your 3D software to export your creations to JSON (JavaScript Object Notation, used a lot in HTMl5 games)
new THREE.JSONLoader.load(url, onCompleteCallback, pathToTexture);


Particles are very small parts of something that you need a whole bunch of (like snow, rain, glitters, confetti, etc.). To make this as efficient as possible, we need to put all the particles in one geometry, so we need to only make one call to Three.js to create a particle system out of it.

//Create an empty geometry object
var particles = new THREE.Geometry;

//Add 2000 'particles' at random positions, and pass them to the geometry as standalone vertices
for (var p = 0; p < 2000; p++) {
    var particle = new THREE.Vector3(Math.random() * 500 - 250, Math.random() * 500 - 250, Math.random() * 500 - 250);

//Create a basic particle material, setting color and size
var particleMaterial = new THREE.ParticleBasicMaterial({ color: 0xeeeeee, size: 2 });

//Create a system from geometry and material (just as with meshes)
var particleSystem = new THREE.ParticleSystem(particles, particleMaterial);

//Add the system to the scene

//And for the sake of this example, put this in the looping render function to make it all rotate
particleSystem.rotation.y += 1/60;


Rays are an often overlooked, but really really useful and essential part of 3D gaming. A ray is basically an invisible line from a certain point, in a certain direction, through the scene. This line then checks which objects it collides with, and you can do something with that information (often used for getting 3D coordinates in a world from a 2D mouse position, or for checking whether or not there's something in front of an AI enemy, so it doesn't bump into everything all the time).

var rayCaster = new THREE.Raycaster();
rayCaster.set(startingPosition, direction);

//startingPosition can be any array of x,y coordinates, or simply playerMesh.position
//direction is a Vector3(x,y,z). Often though, if you see it's not working, you'll need to .normalize it

//Check for intersection (returns array of all objects)
//obstacles is a group of objects it must check collision with
var collidingWith = rayCaster.intersectObjects(obstacles);


Sadly, Three.js doesn't come with some useful built in methods or functions for handling user input. But, lucky us, there's some genius out there (Jerome Etienne) who's made all sorts of Three.js plugins (which he calls THREEx).

Mouse/Touch Events

Get the THREEx Dom Events Extension at this page

Then you need to include it at the top of your page:

<script src='threex.domevent.js'></script>

First, instantiate a new DOM Events layer:

//Requires the current camera and renderer
var domEvents   = new THREEx.DomEvents(camera, renderer.domElement)

The extension works just like event listeners: you can add an event on a function, and if you don't need it anymore you can remove it.

//Add an event listener for a click on a certain object
someMesh.on('click', function(){
    //Execute code block here
    someMesh.scale.x *= 2;

//To remove it, simply use...
someMesh.off('click', callback);

//Currently supported events:
click, dblclick, mouseup, mousedown, mouseover and mouse out
Keyboard events

Again, download the plugin here

Include it with your page's header:

<script src='THREEx.KeyboardState.js'></script>

Then, instantiate it:

var keyboard = new THREEx.KeyboardState();

Then check whether a key (or combination of keys is pressed)!

//Combination of SHIFT and P
if(keyboard.pressed("shift+P")) {

//Just P
if(keyboard.pressed("P")) {

//If you don't need it anymore, destroy the listener

Trackballcontrols? Trackballcontrols. It's an extra script from the Three.js author himself that you can include, and it enables you to zoom in/out and pan and move around the scene with the camera. It's not enormously useful in most games, but invaluable when debugging.

Get the trackballscript here(and include it, you know the drill)

//Create new controls variable containing the trackballcontrols, applied to a certain camera
//Then set some properties, and that's it!
controls = new THREE.TrackballControls( camera );

controls.rotateSpeed = 1.0;
controls.zoomSpeed = 1.2;
controls.panSpeed = 0.8;

controls.noZoom = false;
controls.noPan = false;

controls.staticMoving = true;
controls.dynamicDampingFactor = 0.3;

controls.addEventListener( 'change', render );


TO DO: Sprites. Beziercurves and splines. Animations.
Do you like my tutorials?
To keep this site running, donate some motivational food!
Chocolate Milk