cs291 ยป

# three.js reference

This reference page is here to save you time skimming through videos to find and copy code snippets. Relevant snippets of three.js code are shown by lesson, with an additional comment or two; the course's source code contains more. See the three.js documentation site for more about three.js. See the syllabus for links to the individual lessons.

## Lesson 2: Points, Vectors, and Meshes

Creating Geometry in three.js

``````var material = new THREE.MeshBasicMaterial( { color: 0xff0000, side: THREE.DoubleSide } );

var geometry = new THREE.Geometry();
geometry.vertices.push( new THREE.Vector3( 5, 10, 0 ) );  // vertex 0
geometry.vertices.push( new THREE.Vector3( 5, 5, 0 ) );   // vertex 1
geometry.vertices.push( new THREE.Vector3( 10, 5, 0 ) );  // vertex 2

geometry.faces.push( new THREE.Face3( 0, 1, 2 ) );  // make a triangle

var mesh = new THREE.Mesh( geometry, material );  // create an object

scene.add( mesh ); // add object to the scene to make it visible
``````

Build A Stairway

``````var geoBlock = new THREE.CubeGeometry( width, height, thickness );
var blockMesh = new THREE.Mesh( geoBlock, material );
// set the X,Y,Z position
stepMesh.position.x = xPosition;
stepMesh.position.y = yPosition;
stepMesh.position.z = zPosition;
``````

The Drinking Bird

``````// values 32, 16 are longitude and latitude tessellations
var sphere = new THREE.Mesh(
new THREE.SphereGeometry( radius, 32, 16 ), sphereMaterial );

var cylinder = new THREE.Mesh(
``````

## Lesson 3: Colors and Materials

Setting the Color

``````var sphereMaterial = new THREE.MeshLambertMaterial( );
// three separate floats to set RGB
sphereMaterial.color.r = 1.0;
sphereMaterial.color.g = 0.0;
sphereMaterial.color.b = 0.0;
// or use the setRGB method
sphereMaterial.color.setRGB( 0.972, 0.749, 0.141 );
// or use a hex value, 0x00 to 0xFF (0-255), for each channel
sphereMaterial.color.setHex( 0x1280FF );

// or initialize your material with the color
var cylMaterial = new THREE.MeshLambertMaterial( { color: 0xF4F100 } );
``````

Vertex Attributes

``````// how to set the three vertex colors for face #0
var color1 = new THREE.Color( 0xF08000 ); // orange
var color2 = new THREE.Color( 0x808000 ); // olive
var color3 = new THREE.Color( 0x0982FF ); // bright blue
geometry.faces[0].vertexColors = [ color1, color2, color3 ];
``````

Diffuse Material

``````material = new THREE.MeshBasicMaterial( { color: 0x80fc66, shading: THREE.FlatShading } );
material.color.setRGB( red, green, blue );
var newRed = material.color.r * 0.7;
material.ambient.setRGB( ... );
``````

Ka, Kd, and HSL

``````var color = new Color();
// hue, saturation, and lightness, all 0-1
color.setHSL( 0.117, 0.937, 0.557 ); // orange
``````

Transparency and Three.js

``````var movingBoxMaterial = new THREE.MeshLambertMaterial(
{ color: 0xE53319, opacity: 0.7, transparent: true } );
``````

## Lesson 4: Transforms

Translation

``````sphere.position.x = xPosition;
sphere.position.y = yPosition;
sphere.position.z = zPosition;
``````

Rotation

``````cube.rotation.x = xRotationInRadians; // e.g. -70 * Math.PI/180
``````

Rigid Body Transforms vs Scaling

``````cube.scale.x = xSize;
cube.scale.y = ySize;
cube.scale.z = zSize;
``````

Scale Rotate Translate

``````// This is always the order of application:
cube.scale.set( xSize, ySize, zSize );
cube.position.set( xPosition, yPosition, zPosition );
``````

Object3D

``````var block = new THREE.Mesh(
new THREE.CubeGeometry( 100, 4, 4 ), clockHandMaterial );
block.position.x = 40;
// make the parent object
var clockHand = new THREE.Object3D();

clockHand.rotation.y = -70 * Math.PI/180;
``````

## Lesson 5: Matrices

Identity Matrix

``````var mtx = new THREE.Matrix4();
mtx.identity();
``````

Using a Matrix

``````var mtx = new THREE.Matrix4(
1, 0, 0, 12,
0, 1, 0, 16,
0, 0, 1, -5,
0, 0, 0,  1 );

mtx.makeTranslation( x, y, z );
mtx.makeTranslation(12,16,-5 );

forearm.matrix = mtx;
forearm.matrixAutoUpdate = false;
``````

Axis of Rotation

``````mtx.makeRotationAxis( axis, theta );
``````

Angle of Rotation

``````// get two diagonally-opposite corners of the cube
// and compute the cylinder axis direction and length
var maxCorner = new THREE.Vector3(  1, 1, 1 );
var minCorner = new THREE.Vector3( -1,-1,-1 );
var cylAxis = new THREE.Vector3();
cylAxis.subVectors( maxCorner, minCorner );
var cylLength = cylAxis.length();

// take dot product of cylAxis and up vector
// to get cosine of angle
cylAxis.normalize();
var theta = Math.acos(
cylAxis.dot( new THREE.Vector3(0,1,0) ) );

// alternate version:
var theta = Math.acos( cylAxis.y );
``````

Cross Product

``````var rotationAxis = new THREE.Vector3();
rotationAxis.crossVectors( cylAxis, new THREE.Vector3(0,1,0) );

var negRotationAxis = new THREE.Vector3();
negRotationAxis.crossVectors( new THREE.Vector3(0,1,0), cylAxis );

// special case: if rotationAxis is just about zero, set to X axis,
// so that the angle can be given as 0 or PI
if ( rotationAxis.length() == 0 )
{
rotationAxis.set( 1, 0, 0 );
}
rotationAxis.normalize();
``````

Make an Ornament or Caltrop

``````var cylinder = new THREE.Mesh(
new THREE.CylinderGeometry( 0.2, 0.2, cylLength, 32 ), cylinderMaterial );

var rotationAxis = new THREE.Vector3(1,0,-1);
// makeRotationAxis wants its axis normalized
rotationAxis.normalize();
// don't use position, rotation, scale
cylinder.matrixAutoUpdate = false;
cylinder.matrix.makeRotationAxis( rotationAxis, theta );
``````

Rotation Times Rotation

``````airplane.rotation.x = effectController.ex * Math.PI/180;    // pitch
airplane.rotation.y = effectController.ey * Math.PI/180;    // yaw
airplane.rotation.z = effectController.ez * Math.PI/180;    // roll
``````

## Lesson 6: Lights

Directional Light in three.js

``````var light = new THREE.DirectionalLight( 0xFFFAAD, 0.7 );
light.position.set( 200, 500, 600 );

light.position.set( 2, 5, 6 );
light.position.set( 0.02, 0.05, 0.06 );
``````

Ambient Lighting

``````scene.add( new THREE.AmbientLight( 0x222222 ) );

var someMaterial = new THREE.MeshLambertMaterial( );
someMaterial.color.setRGB( 0.8,0.2,0.1);
someMaterial.ambient.copy( someMaterial.color );
``````

``````var light = new THREE.PointLight( 0xFFFFFF, 1.0 );
light.position.set( 1000, 1000, 1000 );

function render() {
var delta = clock.getDelta();
cameraControls.update(delta);

renderer.render(scene, camera);
}
``````

``````renderer.shadowMapEnabled = true;

bbird.traverse( function ( object ) {
if ( object instanceof THREE.Mesh ) {
}
} );

``````

## Lesson 7: Cameras

Three.js Orthographic Camera

``````viewSize = 900;
aspectRatio = canvasWidth/canvasHeight;
// OrthographicCamera( left, right, top, bottom, near, far )
camera = new THREE.OrthographicCamera(
-aspectRatio*viewSize / 2, aspectRatio*viewSize / 2,
viewSize / 2, -viewSize / 2,
-1000, 1000 );

camera.position.set( -890, 600, -480 );
cameraControls = new THREE.OrbitAndPanControls(camera, renderer.domElement);
cameraControls.target.set(0,310,0);
``````

Three.js Perspective Camera

``````// PerspectiveCamera( angle, aspectRatio, near, far )
camera = new THREE.PerspectiveCamera( 30, aspectRatio, 1, 10000 );
camera.position.set( -170, 170, 40 );
cameraControls = new THREE.OrbitAndPanControls(camera, renderer.domElement);
cameraControls.target.set(0,50,0);

camera.updateProjectionMatrix();
``````

Antialiasing

``````renderer = new THREE.WebGLRenderer( { antialias: true } );
``````

Four Viewports

``````// don't clear when multiple viewports are drawn
renderer.autoClear = false;

// OrthographicCamera( left, right, top, bottom, near, far )
topCam = new THREE.OrthographicCamera(
-aspectRatio*viewSize / 2, aspectRatio*viewSize / 2,
viewSize / 2, -viewSize / 2,
-1000, 1000 );
// set X to be the up axis
topCam.up.set( 1, 0, 0 );

render();

// top view
topCam.position.copy( cameraControls.target );
// move up a unit and look down at target
topCam.position.y +=1 ;
topCam.lookAt( cameraControls.target );
``````

## Lesson 8: Textures and Reflections

How Texturing Works

``````var crateTxr = THREE.ImageUtils.loadTexture( 'textures/crate.gif' );
var material = new THREE.MeshBasicMaterial( { map: crateTxr } );
``````

UVs in three.js

``````var geo = new THREE.Geometry();

// generate vertices
geo.vertices.push( new THREE.Vector3( 0.0, 0.0, 0.0 ) );
geo.vertices.push( new THREE.Vector3( 4.0, 0.0, 0.0 ) );
geo.vertices.push( new THREE.Vector3( 4.0, 4.0, 0.0 ) );

var uvs = [];
uvs.push( new THREE.Vector2( 0.0, 0.0 ) );
uvs.push( new THREE.Vector2( 1.0, 0.0 ) );
uvs.push( new THREE.Vector2( 1.0, 1.0 ) );

// generate faces
geo.faces.push( new THREE.Face3( 0, 1, 2 ) );
geo.faceVertexUvs[ 0 ].push( [ uvs[0], uvs[1], uvs[2] ] );
geo.faces.push( new THREE.Face3( 8, 2, 6 ) );
geo.faceVertexUvs[ 0 ].push( [ uvs[8], uvs[2], uvs[6] ] );
``````

Wrap Modes

``````var texture = new THREE.Texture();
texture.wrapS = texture.wrapT = THREE.RepeatWrapping;
texture.wrapS = texture.wrapT = THREE.MirroredRepeatWrapping;
texture.wrapS = texture.wrapT = THREE.ClampToEdgeWrapping;
``````

Texture Transform

``````var texture = new THREE.Texture();
texture.repeat.set( 1, 1 );
texture.offset.set( 0, 0 );
``````

Texture Magnification

``````var texture = new THREE.Texture();
texture.magFilter = THREE.NearestFilter; // one "tap"
texture.magFilter = THREE.LinearFilter; // four "taps"
``````

Sampling and Filtering

``````var texture = new THREE.Texture();
texture.magFilter = THREE.NearestFilter;
texture.magFilter = THREE.LinearFilter; // the norm

texture.minFilter = THREE.NearestFilter;
texture.minFilter = THREE.LinearFilter;
texture.minFilter = THREE.LinearMipMapLinearFilter; // the norm

texture.anisotropy = 1;
texture.anisotropy = renderer.getMaxAnisotropy();
``````

Making Particles

``````var disk = THREE.ImageUtils.loadTexture( "textures/disc.png" );
var material = new THREE.ParticleBasicMaterial(
{ size: 35, sizeAttenuation: false, map: disk, transparent: true } );
material.color.setHSL( 0.9, 0.2, 0.6 );

var particles = new THREE.ParticleSystem( geometry, material );
particles.sortParticles = true;

var geometry = new THREE.Geometry();
for ( var i = 0; i < 8000; i ++ ) {
var vertex = new THREE.Vector3();
do {
vertex.x = 2000 * Math.random() - 1000;
vertex.y = 2000 * Math.random() - 1000;
vertex.z = 2000 * Math.random() - 1000;
} while ( vertex.length() > 1000 );
geometry.vertices.push( vertex );
}
``````

``````uniform vec3 uMaterialColor;
uniform vec3 uDirLight;

varying vec3 vColor;

void main() {
// Transform the vertex from model space to clip coordinates
gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
vec3 light = normalize( uDirLight );

// Compute a diffuse color using Lambertian reflection, N * L
float diffuse = max( dot( normal, light ), 0.0);

vColor = uMaterialColor * diffuse;
}
``````

``````varying vec3 vColor;

void main() {
gl_FragColor = vec4(vColor, 1.0);
}

vec3 uSpecularColor;
float specular;
...
gl_FragColor.rgb += specular * uSpecularColor;
``````

``````float diffuse = max(
dot( normal, light ), 0.0);
``````

``````gl_FragColor = vec4( uKd * uMaterialColor * uDirLightColor * diffuse, 1.0 );
``````

Anisotropic Material

``````for ( int i = 0; i < 2; i++ ) {
... do things ...
}
``````

Gamma Correction

``````renderer.gammaInput = true;
renderer.gammaOutput = true;
``````

Texturing and Post-Processing

``````vec4 texelColor = texture2D( map, vUv );

vec4 cubeColor = textureCube( tCube,
vec3( -vReflect.x, vReflect.yz ) );

varying vec2 vUv;

void main() {
vUv = uv;
gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
}

uniform sampler2D tDiffuse;
varying vec2 vUv;

void main() {
vec4 cTextureScreen = texture2D( tDiffuse, vUv );

// luma, for non-gamma-corrected computations
vec3 lumaColor = vec3(
cTextureScreen.r * 0.3 +
cTextureScreen.g * 0.59 +
cTextureScreen.b * 0.11 );

gl_FragColor.rgb = vec4( lumaColor, 1.0 );
}
``````

Make a Moving Flashlight

``````if ( length( vViewPosition.xy ) > uFlashRadius ) {
return;
}

uniform vec2 uFlashOffset;
``````

Model Deformation

``````varying vec3 vNormal;
varying vec3 vViewPosition;

void main() {
gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
vNormal = normalize( normalMatrix * normal );
vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );
vViewPosition = -mvPosition.xyz;
}
``````

## Lesson 10: Interaction and Animation

Events

``````document.addEventListener( 'mousedown', onDocumentMouseDown, false );

function onDocumentMouseDown( event ) {
even.preventDefault();
``````

Picking

``````function onDocumentMouseDown( event ) {
var mouseVector = new THREE.Vector3(
2 * ( event.clientX / canvasWidth ) - 1,
1 - 2 * ( event.clientY / canvasHeight ));
var projector = new THREE.Projector();
var raycaster = projector.pickingRay( mouseVector.clone(), camera );

// hit testing
var intersects = raycaster.intersectObjects( objects );
if ( intersects.length > 0 ) {
intersects[ 0 ].object.material.color.setRGB(
Math.random(), Math.random(), Math.random() );

var sphere = new THREE.Mesh( sphereGeom, sphereMaterial );
sphere.position = intersects[ 0 ].point;
}

// various returned values:
intersects[ 0 ].object
intersects[ 0 ].face
intersects[ 0 ].faceIndex
intersects[ 0 ].distance
intersects[ 0 ].point
``````

The Rendering Loop

``````renderer.render(scene, camera);

function animate() {
window.requestAnimationFrame(animate);
render();
}

function render() {
var delta = clock.getDelta();
cameraControls.update(delta);
renderer.render(scene, camera);
}
``````

Incremental Animation

``````var bodyhead = new THREE.Object3D();

// add field for animated part, for simplicity

var tiltDirection = 1;

function render() {
bird.animated.rotation.z += tiltDirection * 0.5 * Math.PI/180;
if ( bird.animated.rotation.z > 103 * Math.PI/180 ) {
tiltDirection = -1;
bird.animated.rotation.z = 2*(103 * Math.PI/180) - bird.animated.rotation.z;
} else if ( bird.animated.rotation.z < -22 * Math.PI/180 ) {
tiltDirection = 1;
bird.animated.rotation.z = 2*(-22 * Math.PI/180) - bird.animated.rotation.z;
}

renderer.render(scene, camera);
}
``````

Timed Animation

``````var clock = new THREE.Clock();

function render() {
var delta = clock.getDelta();

// fixed step size:
bird.animated.rotation.z +=
tiltDirection * 0.5 * Math.PI/180;

// clock controlled:
bird.animated.rotation.z +=
tiltDirection * 30 * delta * Math.PI/180;

// final code:
var angle = (30 * clock.getElapsedTime()) % 250;
if ( angle < 125 ) {
// go from -22 to 103 degrees
bird.animated.rotation.z =
(angle - 22) * Math.PI/180;
} else {
// go back from 103 to -22 degrees
bird.animated.rotation.z =
((250-angle) - 22) * Math.PI/180;
}
``````