Three.js

A WebGL Framework

Created by Kai Lawonn

WebGL

  • WebGL is a JavaScript API
  • Rendering interactive 3D and 2D graphics
  • Compatible with any web browser
  • No plug-ins

Three.js

  • JavaScript library
  • Easy to use
  • Under active development

Why should you listen to me?

Teaching

Teaching

Teaching

Data Visualization

Data Visualization

Physics

Medical Visualization

Medical Visualization

Shaders

... and cool games (of course)

OK OK

Cool games

Raytracing

Let's start...

... with the skeleton.

Basic Skeleton


<!DOCTYPE html>
<html>
<head>
	<title>Basic Skeleton</title>
	<script src="libs/three.js"></script>
	<style>
		body {margin: 0; overflow: hidden;}
	</style>
</head>
<body>
<div id="WebGL-output"> </div>
	<script type="text/javascript">
		function init() {/*insert three.js stuff*/}
		window.onload = init;
	</script>
</body>
</html>
					

Scene, Camera, Renderer


// create a scene
var scene = new THREE.Scene();

// create a camera
var camera = new THREE.PerspectiveCamera(45, 
		window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.set(-10,10,10);

// create a render window
var renderer = new THREE.WebGLRenderer();
renderer.setClearColor(0xFFFFFF);
renderer.setSize(window.innerWidth, window.innerHeight);

// add the output of the renderer to the html element
document.getElementById("WebGL-output").appendChild(renderer.domElement);

// render the scene
renderer.render(scene, camera);
					

Adding a cube


// create a cube
var cubeGeometry = new THREE.BoxGeometry(4, 4, 4);
var cubeMaterial = new THREE.MeshBasicMaterial({color: 0xff0000});
var cube = new THREE.Mesh(cubeGeometry, cubeMaterial);

// position the cube
cube.position.set(-4,3,0);

// add the cube to the scene
scene.add(cube);

// look at the cube
camera.lookAt(cube.position);
					

VoilĂ 

Shading


// change material to Phong
var cubeMaterial = new THREE.MeshPhongMaterial({color: 0x7777ff});

// add a white spotlight
var spotLight = new THREE.SpotLight(0xffffff);
spotLight.position.set(-10, 20, 10);
scene.add(spotLight);
					

Even better

Some shadows


// renderer should know about shadows
renderer.shadowMapEnabled = true; 

// the cube can cast a shadow
cube.castShadow = true;

// the new plane should receive it
plane.receiveShadow = true;

// our spotlight should throw shadows
spotLight.castShadow = true;
					

Here, we go

Various geometries

... and of course

Simple animations


// before
renderer.render(scene, camera);

// after
var step=0;
renderScene();

function renderScene() {
	step+=0.01;
	spotLight.position.x=-40+50*Math.sin(step);
	spotLight.position.z=60+30*Math.sin(step);
	requestAnimationFrame(renderScene);
	renderer.render(scene, camera);
}
					

Here, we go

Normal Maps


// before
var cubeMaterial = new THREE.MeshPhongMaterial();
// new        
cubeMaterial.map =  THREE.ImageUtils.loadTexture("tex.jpg");
cubeMaterial.normalMap = THREE.ImageUtils.loadTexture("tex-normal.jpg");
					

Result

Interaction

Shaders


// create new shader material					
var shaderMaterial = new THREE.ShaderMaterial({
vertexShader:  document.getElementById('vertexshader'  ).textContent,
fragmentShader:document.getElementById('fragmentshader').textContent
});
		
// create a sphere
var sphereGeometry = new THREE.SphereGeometry(1, 50, 50);
var sphere = new THREE.Mesh(sphereGeometry, shaderMaterial);
					

Vertex shader



					

Fragment shader



					

First shader

Particles, particles, particles!!!

Initialize


var particles = 250000;
var geometry = new THREE.BufferGeometry();
var positions = new Float32Array( particles * 3 );
// particles spread in the cube
var n = 500, n2 = n / 2; 
for ( var i = 0; i < positions.length; i += 3 ) {
  positions[ i ]     = Math.random() * n - n2;
  positions[ i + 1 ] = Math.random() * n - n2;
  positions[ i + 2 ] = Math.random() * n - n2;
}
geometry.addAttribute('position',new THREE.BufferAttribute(positions,3));

particleSystem = new THREE.PointCloud( geometry, shaderMaterial );
scene.add( particleSystem );
				

Move it,...!


var pos = particleSystem.geometry.attributes.position.array;
for ( var i = 0; i < positions.length; i += 3 ) {
  var x=pos[ i ];
  var y=pos[ i+1 ];
  var z=pos[ i+2 ];
  
  var vx=-z;
  var vy=x;
  var vz=x;
  dist=Math.sqrt(x*x+y*y+z*z);
  
  if(dist>800){
    vx=-x;
    vy=-y;
    vz=-z;
  } 
  pos[ i ] = pos[ i ] + speed*0.0001*vx;
  pos[i+1] = pos[i+1] + speed*0.0001*vy;
  pos[i+2] = pos[i+2] + speed*0.0001*vz;
}
particleSystem.geometry.attributes.position.needsUpdate = true;
					

Oh yeah

Documentation

THE END