Intro to WebGLwith Three.js

WebGL

JavaScript API for rendering interactive 2D and 3D graphics
inside an HTML <canvas> element.

Browser Support

three.js

threejs.org

3D Javascript Library

Renderers: WebGL, <canvas>, <svg>, CSS3D / DOM, and more

Scenes, Cameras, Geometry, 3D Model Loaders, Lights, Materials,
Shaders, Particles, Animation, Math Utilities

<!DOCTYPE html>
<html>
  <head>
    <title>Basic Three.js App</title>
    <style>
      html, body { margin: 0; padding: 0; overflow: hidden; }
    </style>
  </head>
  <body>
    <script src="js/three.min.js"></script>
    <script>
      // Javascript will go here.
    </script>
  </body>
</html>
var scene = new THREE.Scene();
var aspect = window.innerWidth / window.innerHeight;
var camera = new THREE.PerspectiveCamera( 75, aspect, 0.1, 1000 );
var renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );

var geometry = new THREE.BoxGeometry( 1, 1, 1 ); var material = new THREE.MeshNormalMaterial(); var cube = new THREE.Mesh( geometry, material ); scene.add( cube ); camera.position.z = 5;
var render = function () { requestAnimationFrame( render ); cube.rotation.x += 0.1; cube.rotation.y += 0.1; renderer.render( scene, camera ); }; render();

Scene Graph

Object3D

var group = new THREE.Group();
scene.add( group );

group.add( mesh1 );
group.add( mesh2 );

mesh2.visible = false;
group.remove( mesh2 );

group.children // mesh1
group.parent // scene

Object3D Transforms

mesh.position.x = 0
mesh.position.x = -100
mesh.scale.set(2,2,2)
mesh.rotation.y = Math.PI / 4
mesh.rotation.y = Math.PI * 5 / 4

Unit Circle

mesh.rotation.y = THREE.Math.degToRad(45);

Unit Circle

mesh.position.x = Math.cos( time );
mesh.position.y = Math.sin( time );

Cameras

cam = new THREE.PerspectiveCamera( fov, aspect, near, far )
cam = new THREE.PerspectiveCamera( fov, aspect, near, far )
cam = new THREE.PerspectiveCamera( fov, aspect, near, far )
camera.fov = 15
camera.fov = 60
camera.far = 1000
camera.far = 3000
camera = new THREE.OrthographicCamera( left, right, top, bottom, near, far );
camera = new THREE.OrthographicCamera( left, right, top, bottom, near, far );
camera = new THREE.OrthographicCamera( left, right, top, bottom, near, far );

Camera Controls

/three.js/examples/js/controls/OrbitControls.js

<script src="path/to/OrbitControls.js"></script>

controls = new THREE.OrbitControls( camera );

function render() {
  requestAnimationFrame( render );
  controls.update();
  renderer.render( scene, camera );
}
controls.enablePan = false;
controls.enableZoom = false;
controls.enableRotate = false;

controls.minDistance
controls.maxDistance

controls.minPolarAngle
controls.maxAzimuthAngle

Geometry

Geometry

var geo = new THREE.BoxGeometry( width, height, depth );
var geo = new THREE.SphereGeometry( 60, 24, 16 );
var geo = new THREE.CylinderGeometry( ... );
var geo = new THREE.TorusGeometry( ... );

Materials

Materials

var material = new THREE.MeshBasicMaterial({ ... });
var material = new THREE.MeshLambertMaterial({ ... });
var material = new THREE.MeshPhongMaterial({ ... });
var material = new THREE.MeshStandardMaterial({ ... });
var material = new THREE.MeshToonMaterial({ ... });
var material = new THREE.MeshNormalMaterial({ ... });
var material = new THREE.MeshNormalMaterial({ ... });

Material Properties

flatShading: false
flatShading: true
flatShading: true // face normals
flatShading: true // face normals
flatShading: false // vertex normals
color: 0xaaaaaa
color: 0x3794cf
shininess: 40
shininess: 80
wireframe: true
transparent: true, opacity: 0.5

UVs

Texture Mapping

var loader = new THREE.TextureLoader();
var texture = loader.load("color-map.jpg");
map: texture
normalMap: texture
specularMap: texture
map: colorMap, specularMap: specMap, normalMap: normalMap
var material = new THREE.MeshPhongMaterial({
  color: 0xaaaaaa,
  specular: 0x333333,
  shininess: 15,
  map: colorMap,
  specularMap: specMap,
  normalMap: normalMap
});

Color Methods

THREE.Color()
set or get: Hex, RGB, HSL, CSS Style

var material = new THREE.MeshPhongMaterial({ color: 0x0000ff });

material.color.setHex(0xff0000)
material.color.setRGB(1,0,0)
material.color.setStyle("rgb(255,0,0)")

material.color.r, material.color.g, material.color.b
material.color.getHexString()
material.color.getHSL()

Lights

Lights

light = new THREE.DirectionalLight( 0xdddddd, 0.8 );
light.position.set( -80, 80, 80 );
light.position.x = 80;
light.target.position = 160;
light.position.x = -80;
light = new THREE.DirectionalLight( 0xdddddd, 0.8 );
light = new THREE.DirectionalLight( 0xb4e7f2, 0.8 );
light = new THREE.DirectionalLight( 0xb4e7f2, 0.2 );
light = new THREE.DirectionalLight( 0xb4e7f2, 1.5 );
light = new THREE.DirectionalLight( 0xb4e7f2, 0.8 );
light = new THREE.PointLight( 0xb4e7f2, 0.8 );
light = new THREE.PointLight( 0xb4e7f2, 0.8 );
light = new THREE.SpotLight( 0xb4e7f2, 0.8 );
light.angle = Math.PI / 9;
light.angle = Math.PI / 5;
light.penumbra = 0.4;
light.penumbra = 0;
light.penumbra = 0.8;
light = new THREE.AmbientLight( 0x444444 );
light = new THREE.AmbientLight( 0x000000 );
light = new THREE.AmbientLight( 0x444444 );

Three Point Lighting

Key, Fill, Rim
Key, Fill, Rim
RGB

Sublime Auto Complete

/three.js/utils/editors/sublimetext2/threejs.sublime-completions
Copy to folder: Sublime Text 2/Packages/User

DCC Software

Digital Content Creation

Model Converter

OBJ to JSON converter Node tool
/three.js/utils/converters/obj2three.js

node obj2three.js teapot.obj

Model Loader

var loader = new THREE.ObjectLoader();

loader.load("teapot.json", function( group ) {
  mesh = group.children[0];
  mesh.material = new THREE.MeshPhongMaterial();
  scene.add( mesh );
});

Helpers

var wireframe = new THREE.WireframeGeometry( mesh.geometry, hex );
var line = new THREE.LineSegments( wireframe );
line.material.color.setHex( 0x333333 );
mesh.add( line );
var grid = new THREE.GridHelper( size, divisions );
scene.add( grid );
var lightHelper = new THREE.DirectionalLightHelper( light, size );
scene.add( lightHelper );
var axes = new THREE.AxesHelper( size );
object.add( axis );
var box = new THREE.BoxHelper( object );

Lines

var mat = new THREE.LineBasicMaterial({ color: 0x0000ff });

var geometry = new THREE.Geometry();

geometry.vertices.push(
  new THREE.Vector3( -10, 0, 0 ),
  new THREE.Vector3( 0, 10, 0 ),
  new THREE.Vector3( 10, 0, 0 )
);

var line = new THREE.Line( geometry, material );
scene.add( line );

Sprites

A plane that always faces towards the camera (aka Billboarding)

var loader = new THREE.TextureLoader();
var map = loader.load( "sprite.png" );

var material = new THREE.SpriteMaterial({ map: map,
color: 0xffffff, fog: true });

var sprite = new THREE.Sprite( material );
scene.add( sprite );

Points

var material = new THREE.PointsMaterial( parameters );
var geometry = new THREE.Geometry();

for ( i = 0; i < 20000; i ++ ) {
  var vertex = new THREE.Vector3();
  vertex.x = Math.random() * 2000 - 1000;
  vertex.y = Math.random() * 2000 - 1000;
  vertex.z = Math.random() * 2000 - 1000;
  geometry.vertices.push( vertex );
}

var particles = new THREE.Points( geometry, material );
scene.add( particles );
github.com/tweenjs/tween.js/examples/03_graphs.html

Tween.js

github.com/tweenjs/tween.js

var position = { y: 200 };
var target = { y: -120 };

var tween = new TWEEN.Tween(position).to(target, 1000)
  .easing(TWEEN.Easing.Bounce.Out)
  .onUpdate(function(){ mesh.position.y = position.y; })
  .start();

TWEEN.update(); // in render loop

Interaction

// normalized device coordinates
mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1;
mouse.y = - ( event.clientY / window.innerHeight ) * 2 + 1;

raycaster = new THREE.Raycaster();

raycaster.setFromCamera( mouse, camera );

var intersects = raycaster.intersectObjects( scene.children );

INTERSECTED = intersects[ 0 ].object;

Virtual Reality

WebVR

webvr.info

Documentation

/three.js/examples/js/vr/WebVR.js

/