Three Js
Three Js
Three Js
js
#three.js
Table of Contents
About 1
Remarks 2
Versions 2
Examples 2
Installation or Setup 2
Hello world! 4
Introduction 6
Examples 6
Orbit Controls 6
index.html 6
scene.js 6
index.html 7
scene.js 8
Chapter 3: Geometries 10
Remarks 10
Examples 10
THREE.BoxGeometry 10
Cubes 10
Cuboids 11
Colourful 11
Notes 12
THREE.CylinderGeometry 12
Cylinder 13
Introduction 15
Syntax 15
Remarks 15
Examples 15
Examples 16
Introduction 20
Remarks 20
Examples 21
Spinning Cube 21
Introduction 22
Parameters 22
Remarks 22
Examples 22
Credits 35
About
You can share this PDF with anyone you feel could benefit from it, downloaded the latest version
from: three-js
It is an unofficial and free three.js ebook created for educational purposes. All the content is
extracted from Stack Overflow Documentation, which is written by many hardworking individuals at
Stack Overflow. It is neither affiliated with Stack Overflow nor official three.js.
The content is released under Creative Commons BY-SA, and the list of contributors to each
chapter are provided in the credits section at the end of this book. Images may be copyright of
their respective owners unless otherwise specified. All trademarks and registered trademarks are
the property of their respective company owners.
Use the content presented in this book at your own risk; it is not guaranteed to be correct nor
accurate, please send your feedback and corrections to [email protected]
https://riptutorial.com/ 1
Chapter 1: Getting started with three.js
Remarks
The aim of the project is to create a lightweight 3D library with a very low level of complexity — in
other words, for dummies. The library provides canvas, svg, CSS3D and WebGL renderers.
Versions
Examples
Installation or Setup
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r83/three.js"></script>
• You can use the three.js editor to give it a try and download the project as an example or
starting point.
This is the basic HTML file that can be used as a boilerplate when starting a project. This
https://riptutorial.com/ 2
boilerplate uses orbit controls with damping (camera that can move around an object with
deceleration effect) and creates a spinning cube.
<!DOCTYPE html>
<html>
<head>
<title>Three.js Boilerplate</title>
<style>
body{
margin:0;
overflow:hidden;
}
/*
Next 2 paragraphs are a good practice.
In IE/Edge you have to provide the cursor images.
*/
canvas{
cursor:grab;
cursor:-webkit-grab;
cursor:-moz-grab;
}
canvas:active{
cursor:grabbing;
cursor:-webkit-grabbing;
cursor:-moz-grabbing;
}
</style>
</head>
<body>
<script src='three.js/build/three.js'></script>
<script src='three.js/examples/js/controls/OrbitControls.js'></script>
<script>
var scene, renderer, camera, controls, cube;
init();
function init () {
renderer = new THREE.WebGLRenderer();
https://riptutorial.com/ 3
);
camera.position.set( 1, 3, 5 );
animate();
}
function animate () {
requestAnimationFrame( animate );
controls.update();
renderer.render( scene, camera );
cube.rotation.x += 0.01;
}
</script>
</body>
</html>
Hello world!
You may want to download three.js and change the script source below.
HTML:
<html>
<head>
<meta charset=utf-8>
<title>My first Three.js app</title>
<style>
body { margin: 0; }
canvas { width: 100%; height: 100% }
</style>
</head>
<body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r83/three.js"></script>
<script>
// Our JavaScript will go here.
</script>
https://riptutorial.com/ 4
</body>
camera.position.z = 5;
function render() {
requestAnimationFrame( render );
renderer.render( scene, camera );
}
render();
https://riptutorial.com/ 5
Chapter 2: Camera Controls in Three.js
Introduction
This document outlines how you can easily add some existing Camera Controls to your scene, as
well as provide guidance on creating custom controls. Note, the pre-made control scripts can be
found in the /examples/js/controls folder of the library.
Examples
Orbit Controls
An Orbit Camera is one that allows the user to rotate around a central point, but while keeping a
particular axis locked. This is extremely popular because it prevents the scene from getting "tilted"
off-axis. This version locks the Y (vertical) axis, and allows users to Orbit, Zoom, and Pan with the
left, middle, and right mouse buttons (or specific touch events).
index.html
<html>
<head>
<title>Three.js Orbit Controller Example</title>
<script src="/javascripts/three.js"></script>
<script src="/javascripts/OrbitControls.js"></script>
</head>
<body>
<script src="javascripts/scene.js"></script>
</body>
</html>
scene.js
var scene, renderer, camera;
var cube;
var controls;
init();
animate();
function init()
{
renderer = new THREE.WebGLRenderer( {antialias:true} );
var width = window.innerWidth;
var height = window.innerHeight;
renderer.setSize (width, height);
document.body.appendChild (renderer.domElement);
https://riptutorial.com/ 6
scene = new THREE.Scene();
function animate()
{
controls.update();
requestAnimationFrame ( animate );
renderer.render (scene, camera);
}
The OrbitControls script has a several settings that can be modified. The code is well documented,
so look in OrbitControls.js to see those. As an example, here is a code snippet showing a few of
those being modified on a new OrbitControls object.
Here's an example of a custom camera controller. This reads the position of the mouse within the
client window, and then slides the camera around as if it were following the mouse on the window.
index.html
<html>
<head>
<title>Three.js Custom Mouse Camera Control Example</title>
<script src="/javascripts/three.js"></script>
</head>
<body>
<script src="javascripts/scene.js"></script>
</body>
https://riptutorial.com/ 7
</html>
scene.js
var scene, renderer, camera;
var cube;
var cameraCenter = new THREE.Vector3();
var cameraHorzLimit = 50;
var cameraVertLimit = 50;
var mouse = new THREE.Vector2();
init();
animate();
function init()
{
renderer = new THREE.WebGLRenderer( {antialias:true} );
var width = window.innerWidth;
var height = window.innerHeight;
renderer.setSize (width, height);
document.body.appendChild (renderer.domElement);
function onWindowResize ()
{
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize (window.innerWidth, window.innerHeight);
}
function animate()
{
updateCamera();
requestAnimationFrame ( animate );
https://riptutorial.com/ 8
renderer.render (scene, camera);
}
function updateCamera() {
//offset the camera x/y based on the mouse's position in the window
camera.position.x = cameraCenter.x + (cameraHorzLimit * mouse.x);
camera.position.y = cameraCenter.y + (cameraVertLimit * mouse.y);
}
function onDocumentMouseMove(event) {
event.preventDefault();
mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}
As you can see, here we are merely updating the Camera position during the rendering's animate
phase, like we could for any object in the scene. In this case, we are simply re-positioning the
camera at a point offset from it's original X and Y coordinates. This could just as easily be the X
and Z coordinates, or a point along a path, or something completely different not even related to
the mouse's position at all.
https://riptutorial.com/ 9
Chapter 3: Geometries
Remarks
Examples work as of three.js R79 (revision 79).
Examples
THREE.BoxGeometry
Cubes
Cubes created using THREE.BoxGeometry would use the same length for all sides.
JavaScript
//The Box!
//Sets camera's distance away from cube (using this explanation only for simplicity's sake -
in reality this actually sets the 'depth' of the camera's position)
camera.position.z = 5;
//Rendering
function render() {
requestAnimationFrame( render );
renderer.render( scene, camera );
https://riptutorial.com/ 10
}
render();
Notice the 'render' function. This renders the cube 60 times a second.
<!DOCTYPE html>
<html>
<head>
<title>THREE.BoxGeometry</title>
<script src="http://threejs.org/build/three.js"></script>
</head>
<body>
<script>
//Above JavaScript goes here
</script>
</body>
</html>
Cuboids
The line var geometry = new THREE.BoxGeometry( 1, 1, 1 ); gives us a cube. To make a cuboid, just
change the parameters - they define the length, height and depth of the cube respectively.
Example:
...
//Longer cuboid
var geometry = new THREE.BoxGeometry( 2, 1, 1 );
...
...
cube.rotation.x += 0.05;
cube.rotation.y += 0.05;
...
And watch as the merry cube spins round... and round... and round...
https://riptutorial.com/ 11
Colourful
Not for the faint-hearted...
The uniform colour for the entire cube is... green. Boring. To make each face a different colour,
we've to dig to the geometry's faces.
/*Spawn face*/
geometry.faces[8].color = new THREE.Color(0, 1, 0);
geometry.faces[9].color = new THREE.Color(0, 1, 0);
NOTE: The method of colouring the faces is not the best method, but it works well (enough).
Notes
Where's the canvas in the HTML document's body?
There is no need to add a canvas to the body manually. The following three lines
create the renderer, its canvas and add the canvas to the DOM.
THREE.CylinderGeometry
https://riptutorial.com/ 12
THREE.CylinderGeometry build cylinders.
Cylinder
Continuing from the previous example, the code to create the box could be replaced with the
below.
//The Cylinder!
//Sets camera's distance away from cube (using this explanation only for simplicity's sake -
in reality this actually sets the 'depth' of the camera's position)
camera.position.z = 30;
//Rendering
function render() {
requestAnimationFrame( render );
renderer.render( scene, camera );
}
render();
...
cylinder.rotation.x += 0.05;
cylinder.rotation.z += 0.05;
...
And the happy bright cylinder would spin randomly, amidst a dark, black background...
https://riptutorial.com/ 14
Chapter 4: Meshes
Introduction
A Three.js Mesh is a base class that inherits from Object3d and is used to instantiate polygonal
objects by combining a Geometry with a Material. Mesh is also the base class for the more
advanced MorphAnimMesh and SkinnedMesh classes.
Syntax
• new THREE.Mesh(geometry, material);
Remarks
Both the geometry and material are optional and will default to BufferGeometry and
MeshBasicMaterial respectively if they are not provided in the constructor.
Examples
Render a cube mesh with a box geometry and a basic material
renderer.render(scene, camera);
};
render();
https://riptutorial.com/ 15
Chapter 5: Object Picking
Examples
Object picking / Raycasting
Raycasting means throwing a ray from the mouse position on the screen to the scene, this is how
threejs determines what object you want to click on if you have implemented it. Threejs gets that
information using an octree, but still in production you may not want to compute the result at each
frame or on the mousemove event, but rather on the click event for a more accessible app with low
requirements.
init();
function init () {
function raycast ( e ) {
//1. sets the mouse position with a coordinate system where the center
// of the screen is the origin
mouse.x = ( e.clientX / window.innerWidth ) * 2 - 1;
mouse.y = - ( e.clientY / window.innerHeight ) * 2 + 1;
//2. set the picking ray from the camera position and mouse coordinates
raycaster.setFromCamera( mouse, camera );
https://riptutorial.com/ 16
CAUTION! You may lose your time gazing at the blank screen if you don't read the
next part.
If you want to detect the light helper, set the second parameter of raycaster.intersectObjects(
scene.children ); to true.
If you want it to detect normal objects as well as light helper, you need to copy the above raycast
function again. See this question.
function raycast ( e ) {
// Step 1: Detect light helper
//1. sets the mouse position with a coordinate system where the center
// of the screen is the origin
mouse.x = ( e.clientX / window.innerWidth ) * 2 - 1;
mouse.y = - ( e.clientY / window.innerHeight ) * 2 + 1;
//2. set the picking ray from the camera position and mouse coordinates
raycaster.setFromCamera( mouse, camera );
//2. set the picking ray from the camera position and mouse coordinates
raycaster.setFromCamera( mouse, camera );
https://riptutorial.com/ 17
- face : intersected face (THREE.Face3)
- faceIndex : intersected face index (number)
- point : intersection point (THREE.Vector3)
- uv : intersection point in the object's UV coordinates (THREE.Vector2)
*/
}
Object picking using Raycasting might be a heavy task for your CPU depending on your setup (for
example if you don't have an octree like setup) and number of objects in the scene.
If you don't need the world coordinates under the mouse cursor but only to identify the object
under it you can use GPU picking.
Short explanation, GPU can be a powerful tool for computation but you need to know how to get
the results back. The idea is, if you render the objects with a color that represents their id, you can
read the color of the pixel under the cursor and findout the id of the object that is picked.
Remember RGB is just a hex value so there is a conversion exists between id (integer) and color
(hex).
1. Create a new scene and a new rendering target for your object
var vs3D = `
attribute vec3 idcolor;
varying vec3 vidcolor;
void main(){
vidcolor = idcolor;
gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0);
}`;
var fs3D = `
varying vec3 vidcolor;
void main(void) {
gl_FragColor = vec4(vidcolor,1.0);
}`;
https://riptutorial.com/ 18
3. Add your mesh/line geometries a new attribute that represents their id in RGB, create the
pickingObject using the same geometry and add it to the picking scene, and add the actual
mesh to a id->object dictionary
pickingScene.add(pickingObject);
selectionObjects[mesh.id] = mesh;
}
if (id>0){
//this is the id of the picked object
}else{
//it's 0. clicked on an empty space
}
https://riptutorial.com/ 19
Chapter 6: Render Loops for Animation:
Dynamically updating objects
Introduction
This document describes some common ways to add animation directly into your Three.js scenes.
While there are libraries and frameworks that can add dynamic movement to your scene (tweens,
physics, etc), it is helpful to understand how you can do this yourself simply with a few lines of
code.
Remarks
The core concept of animation is updating an object's properties (rotation and translation, usually)
in small amounts over a period of time. For example, if you translate an object by increasing the X
position by 0.1 every tenth of a second, it will be 1 unit further on the X axis in 1 second, but the
viewer will perceive it as having smoothly moved to that position over that time instead of jumping
directly to the new position.
In the spinning cube example above, we use this idea - small incremental updates - to change the
rotation of the cube every time a new frame of animation is requested. By incrementing the
rotation.x and rotation.y properties of the cube object on every frame, the cube appears to spin
on those two axes.
As another example, it's not uncommon to separate your needed update into other functions,
where you can do additional calculations and checks while keeping the render loop uncluttered.
For example, the render loop below calls four different update functions, each one intended to
update a separate object (or an array of objects, in the case of updatePoints()) in the scene.
//render loop
function render() {
requestAnimationFrame( render );
updateGrid();
updateCube();
updateCamera();
updatePoints(pList);
renderer.render( scene, camera);
}
render();
https://riptutorial.com/ 20
You may notice in examples online that the camera controls are also part of the render loop.
This is because the script for controlling the camera is doing the same thing; updating it over time.
The changes might be caused by user input such as a mouse position, or something
programmatic like following a path. In either case though, we are just animating the camera as
well.
Examples
Spinning Cube
camera.position.z = 5;
cube.rotation.x += 0.1;
cube.rotation.y += 0.1;
renderer.render(scene, camera);
};
render();
https://riptutorial.com/ 21
Chapter 7: Textures and Materials
Introduction
A nice introduction to material and textures.
Parameters
Parameter Details
Remarks
Demo Link
Examples
Creating a Model Earth
https://riptutorial.com/ 22
Textures for this example are available at: http://planetpixelemporium.com/planets.html
Installation or Setup
<script type="text/javascript"
src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r85/three.min.js" />
HTML:
<html>
<head>
<meta charset=utf-8>
<title>Earth Model</title>
<style>
body { margin: 0; }
canvas { width: 100%; height: 100% }
</style>
</head>
<body>
<script type="text/javascript"
src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r83/three.js" />
<script>
// Our Javascript will go here.
</script>
</body>
</html>
To actually be able to display anything with three.js, we need three things: A scene, a camera, and
a renderer. We will render the scene with the camera.
https://riptutorial.com/ 23
var geometry = new THREE.SphereGeometry(1, 32, 32);
var material = new THREE.MeshPhongMaterial();
var earthmesh = new THREE.Mesh(geometry, material);
The diffuse texture set the main color of the surface. When we apply it to a sphere, we get the
following image.
https://riptutorial.com/ 24
https://riptutorial.com/ 25
material.map = THREE.ImageUtils.loadTexture('images/earthmap1k.jpg');
https://riptutorial.com/ 26
https://riptutorial.com/ 27
material.bumpMap = THREE.ImageUtils.loadTexture('images/earthbump1k.jpg');
material.bumpScale = 0.05;
• In this case, only the sea is specular because water reflects light more than earth.
• You can control the specular color with the specular parameter.
https://riptutorial.com/ 28
https://riptutorial.com/ 29
material.specularMap = THREE.ImageUtils.loadTexture('images/earthspec1k.jpg')
material.specular = new THREE.Color('grey')
https://riptutorial.com/ 30
https://riptutorial.com/ 31
https://riptutorial.com/ 32
var geometry = new THREE.SphereGeometry(0.51, 32, 32)
var material = new THREE.MeshPhongMaterial({
map : new THREE.Texture(canvasCloud),
side : THREE.DoubleSide,
opacity : 0.8,
transparent : true,
depthWrite : false,
});
var cloudMesh = new THREE.Mesh(geometry, material)
earthMesh.add(cloudMesh)
https://riptutorial.com/ 33
As a final touch, we will animate the cloud layer in order to make it look more realistic.
updateFcts.push(function(delta, now) {
cloudMesh.rotation.y += 1 / 8 * delta;
earthMesh.rotation.y += 1 / 16 * delta;
})
https://riptutorial.com/ 34
Credits
S.
Chapters Contributors
No
Camera Controls in
2 Hectate
Three.js
Textures and
7 Geethu Jose, Xander Luciano
Materials
https://riptutorial.com/ 35