These slides are at: http://bit.ly/third-dimension
Best viewed in Chrome Press up & down arrow keys to navigate
var canvas = document.getElementById('triangleCanvas'); // Get WebGL canvas context var gl = canvas.getContext('webgl') || canvas.getContext('experimental-webgl');
var vertexPosBuffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, vertexPosBuffer); var vertices = [ -0.5, -0.5, 0.5, -0.5, 0, 0.5 ]; gl.bufferData( gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW );
// Shader code (GLSL) var vertexShaderSource = 'attribute vec2 pos;' + 'void main() {' + ' gl_Position = vec4( pos, 0.0, 1.0 );' + // xyzw '}'; var fragmentShaderSource = 'precision mediump float;' + 'void main() {' + ' gl_FragColor = vec4( 0.0, 1.0, 0.0, 1.0 );' + // rgba '}';
// Create shaders var vertexShader = gl.createShader( gl.VERTEX_SHADER ); gl.shaderSource( vertexShader, vertexShaderSource ); gl.compileShader( vertexShader ); var fragmentShader = gl.createShader( gl.FRAGMENT_SHADER ); gl.shaderSource( fragmentShader, fragmentShaderSource ); gl.compileShader( fragmentShader );
// Create program var program = gl.createProgram(); gl.attachShader( program, vertexShader ); gl.attachShader( program, fragmentShader ); gl.linkProgram( program ); gl.useProgram( program );
// Hook up program input and buffer program.vertexPosAttrib = gl.getAttribLocation( program, 'pos' ); // Tell it to read buffer when we start drawing gl.enableVertexAttribArray( program.vertexPosAttrib ); // Specify how program should read data from buffer gl.vertexAttribPointer( program.vertexPosAttrib, 2, gl.FLOAT, false, 0, 0 ); // Draw! gl.drawArrays( gl.TRIANGLES, 0, 3 );
// Create a WebGL renderer var renderer = new THREE.WebGLRenderer(); renderer.setSize( width, height ); var container = document.getElementById( 'spinningCubeContainer'); // Add generated <canvas> to page container.appendChild( renderer.domElement );
// Make a scene var scene = new THREE.Scene(); // Create a camera var camera = new THREE.PerspectiveCamera( 45, // Field of View width/height, // Aspect ratio 1, // zNear 10000 // zFar ); camera.position.z = 300; // Add it to the scene scene.add( camera );
// Make a cube var cube = new THREE.Mesh( new THREE.CubeGeometry( 50, 50, 50 ), // w,h,d new THREE.MeshLambertMaterial( {color: 0xFF0000} )); // Add it to the scene scene.add( cube );
// Make it spin function animate() { // Angles are in radians cube.rotation.y += 0.1; // Render the scene from the camera renderer.render(scene, camera); // Call each time browser's ready for next frame requestAnimationFrame( animate ); } // Start animation going animate();
(But it's not red!)
// Ambient light var ambientLight = new THREE.AmbientLight( 0x333333 ); scene.add( ambientLight ); // Spotlight // color, intensity, distance... var spotLight = new THREE.SpotLight( 0xFFFFFF, 0.8, 300 ); spotLight.position.set( 50, 50, 300 ); // x, y, z spotLight.target.position.set( 0, 0, 0 ); scene.add( spotLight );
// Enable globally renderer.shadowMapEnabled = true; // Enable on the spotlight spotLight.castShadow = true; // Enable on objects cube.castShadow = true; anotherCube.receiveShadow = true;
var loader = new THREE.JSONLoader(); var mesh; loader.load('trex.js', function( geometry ) { mesh = new THREE.Mesh( geometry, new THREE.MeshFaceMaterial() ); scene.add( mesh ); animate(); });
var animate = function() { mesh.rotation.y += 0.05; renderer.render( scene, camera ); requestAnimationFrame( animate ); };
Dinosaur used with kind permission from DK
var controls = new THREE.FlyControls( camera ); controls.movementSpeed = 30; controls.rollSpeed = 0.1; controls.dragToLook = true;
var clock = new THREE.Clock(); var animate = function() { var delta = clock.getDelta(); controls.update(delta); ... }
Dinosaur used with kind permission from DK
Thanks to yomotsu for the image
Thanks to yomotsu for the image
var projector = new THREE.Projector(); function onMouseDown( event ) { var clickX = event.clientX - canvasOffsetLeft; var clickY = event.clientY - canvasOffsetTop; // Viewport coordinates range from -1 to +1 var vector = new THREE.Vector3( ( clickX / width ) *2 -1, -( clickY / height ) *2 +1, 0.5 ); // 'Unproject' from 2D to 3D projector.unprojectVector( vector, camera ); ...
... var ray = new THREE.Ray( camera.position, vector.subSelf( camera.position ).normalize() ); var intersects = ray.intersectObjects( [mesh] ); if ( intersects.length > 0 ) { // We only have 1 object - must've clicked dinosaur roar(); } } // End of onMouseDown
function roar() { roarSound.play(); speechBubble.className = ''; // show window.setTimeout(function() { speechBubble.className = 'hidden'; }, 1500); }
Dinosaur used with kind permission from DK
Please contact me if you're the rights holder of this model
loader.load( 'models/robot.dae', function( collada ) { var model = collada.scene; ... /* * IDs correspond to values in the XML-based Collada file, * e.g. <node id="ID93" name="leftLeg"> */ robot.key = model.getChildByName('ID65', true); robot.head = model.getChildByName('ID139', true); robot.leftLeg = model.getChildByName('ID93', true); robot.rightLeg = model.getChildByName('ID75', true);
var keyTurn = new TWEEN.Tween( robot.key.rotation ) .to( { x: robot.key.rotation.x - (Math.PI * 2) }, 3000) .onComplete(function() { robot.key.rotation.x = 0; }); keyTurn.chain( keyTurn ); keyTurn.start();
var rightLegForwards = new TWEEN.Tween( robot.rightLeg.rotation ) .to( { z: robot.rightLeg.rotation.z - (Math.PI / 9) }, 1000 ) .easing( TWEEN.Easing.Quadratic.InOut ); var rightLegBackwards = new TWEEN.Tween( robot.rightLeg.rotation ) .to( { z: robot.rightLeg.rotation.z + (Math.PI / 9) }, 1000 ) .easing( TWEEN.Easing.Quadratic.InOut ); rightLegForwards.chain( rightLegBackwards ); rightLegBackwards.chain( rightLegForwards ); rightLegForwards.start();
var animate = function() { TWEEN.update(); ... }
<style> #shaderDemo:hover { -webkit-filter: custom( url(shaders/sphere.vs) mix( url(shaders/sphere.fs) normal source-atop), 16 32, amount 1, sphereRadius 0.35, lightPosition 0.0 0.0 1.0 ); } </style>