WebGL with THREE.js


Wednesday, December 12, 12
@antonnarusberg
                                 anton@cannedapps.com


                             Google Developers Group Tallinn
                                  http://bit.ly/gdgtallinn
                                     @GDGTallinn



Wednesday, December 12, 12
3D in Web Browsers




Wednesday, December 12, 12
3D in Web Browsers

   Full power of computer's GPU using only JS, web browser
              and standard web technology stack.


                             Old way - plugins, native applications

                                     New way - WebGL




Wednesday, December 12, 12
Browser compatibility




Wednesday, December 12, 12
So how do you use it?

                             WebGL is an API, accessed through
                             JavaScript programming interfaces.


                             Analogous to 2D drawing using the
                                  HTML5 Canvas element


                             Based on OpenGL ES 2.0 standard


Wednesday, December 12, 12
An (overly) simplified Example:
                    Cube with plain WebGL




Wednesday, December 12, 12
// get the WebGL context to access the API
               var canvas = document.getElementById("lesson04-canvas");
               gl = canvas.getContext("experimental-webgl");


               // Set up Shaders
               var fragmentShader = getShader(gl, "shader-fs");
               var vertexShader = getShader(gl, "shader-vs");

               shaderProgram = gl.createProgram();
               gl.attachShader(shaderProgram, vertexShader);
               gl.attachShader(shaderProgram, fragmentShader);
               gl.linkProgram(shaderProgram);

               gl.useProgram(shaderProgram);

               // ....




Wednesday, December 12, 12
<script id="shader-fs" type="x-shader/x-fragment">
                   precision mediump float;

                   varying vec4 vColor;

                   void main(void) {
                       gl_FragColor = vColor;
                   }
               </script>

               <script id="shader-vs" type="x-shader/x-vertex">
                   attribute vec3 aVertexPosition;
                   attribute vec4 aVertexColor;

                   uniform mat4 uMVMatrix;
                   uniform mat4 uPMatrix;

                   varying vec4 vColor;

                   void main(void) {
                       gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);
                       vColor = aVertexColor;
                   }
               </script>




Wednesday, December 12, 12
// A taste of creating the array of vertices for the cube
              cubeVertexPositionBuffer = gl.createBuffer();
              gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexPositionBuffer);

         vertices = [
              // Front face
              -1.0, -1.0, 1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, -1.0, 1.0, 1.0,
              // Back face
              -1.0, -1.0, -1.0, -1.0, 1.0, -1.0, 1.0, 1.0, -1.0, 1.0, -1.0, -1.0,
              // Top face
              -1.0, 1.0, -1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0,
              // Bottom face
              -1.0, -1.0, -1.0, 1.0, -1.0, -1.0, 1.0, -1.0, 1.0, -1.0, -1.0, 1.0,
              // Right face
               1.0, -1.0, -1.0, 1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, -1.0, 1.0,
              // Left face
              -1.0, -1.0, -1.0, -1.0, -1.0, 1.0, -1.0, 1.0, 1.0, -1.0, 1.0, -1.0
         ];

              gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);




Wednesday, December 12, 12
// Rotating the cube with Matrix computations
             function drawScene() {

                   mat4.translate(mvMatrix, [3.0, 0.0, 0.0]);
                   mat4.rotate(mvMatrix, degToRad(rCube), [1, 1, 1]);

                   gl.uniformMatrix4fv(shaderProgram.mvMatrixUniform, false, mvMatrix);

                   // ... Bind buffers etc.

                   gl.drawElements(gl.TRIANGLES, cubeVertexIndexBuffer.numItems,
                   gl.UNSIGNED_SHORT, 0);

                   // ...
             }

             function tick() {
                requestAnimFrame(tick);
                rCube += 1;
                drawScene();
             }




Wednesday, December 12, 12
Skills needed for plain WebGL

       * GLSL, the shading language used by OpenGL and
       WebGL

       * Lots of Math for Matrix computation to set up
       transformations

       * Creating Vertex buffers to hold data about vertex
       positions, normals, colors, and textures


Wednesday, December 12, 12
THREE.js to the rescue!




Wednesday, December 12, 12
THREE.js

       * Abstracts away all the painful overhead

       * Elegant API to create and manipulate Cameras,
       Objects, Lights, Materials etc.

       * THREE.js is Open Source




Wednesday, December 12, 12
A Cube example using THREE.js


       http://learningthreejs.com/data/
       lets_do_a_cube/docs/lets_do_a_cube.html

       Jerome Etienne - great tutorials on THREE.js




Wednesday, December 12, 12
// Set up a Camera
             camera = new THREE.Camera(70, window.innerWidth / window.innerHeight, 1,
             1000);
             camera.position.y = 150;
             camera.position.z = 350;
             camera.target.position.y = 150;

             // Create a Scene
             scene = new THREE.Scene();

             // Create a Cube
             material = new THREE.MeshNormalMaterial();
             cube = new THREE.Mesh( new THREE.CubeGeometry( 200, 200, 200 ), material);
             cube.position.y = 150;


             // Add the Cube to the Scene
             scene.addObject( cube );


             // Boilerplate
             renderer = new THREE.WebGLRenderer();
             renderer.setSize( window.innerWidth, window.innerHeight );
             $(“#container”).appendChild( renderer.domElement );




Wednesday, December 12, 12
function animate() {
             	 render();


                   // Loop
             	     requestAnimationFrame( animate );
             }

             function render() {
                   // Rotate
             	     cube.rotation.x += 0.02;
             	     cube.rotation.y += 0.0225;
             	     cube.rotation.z += 0.0175;


                   // Bounce
                   var dtime	= Date.now() - startTime;
             	     cube.scale.x	 = 1.0 + 0.3*Math.sin(dtime/300);
             	     cube.scale.y	 = 1.0 + 0.3*Math.sin(dtime/300);
             	     cube.scale.z	 = 1.0 + 0.3*Math.sin(dtime/300);

             	     renderer.render( scene, camera );
             }




Wednesday, December 12, 12
It’s alive!




Wednesday, December 12, 12
More Features
       Renderers
       WebGL, <canvas>, <svg>

       Cameras
       Perspective and orthographic; controllers: trackball, FPS, path and more

       Lights
       Ambient, direction, point, spot and hemisphere lights. Cast and receive shadows

       Materials
       Lambert, Phong and more - with textures, smooth-shading

       Shaders
       Access to full WebGL capabilities like lens flare, depth pass and an extensive post-processing library

       Objects
       meshes, particles, sprites, lines, ribbons, ...

       Geometry
       plane, cube, sphere, torus, 3D text and more

       Export/Import
       utilities to create Three.js-compatible JSON files from: Blender, CTM, FBX, 3D Max, and OBJ



Wednesday, December 12, 12
http://threejs.org/

           https://github.com/mrdoob/three.js

                             http://learningthreejs.com


Wednesday, December 12, 12
Thank you!




Wednesday, December 12, 12

WebGL and three.js

  • 1.
  • 2.
    @antonnarusberg anton@cannedapps.com Google Developers Group Tallinn http://bit.ly/gdgtallinn @GDGTallinn Wednesday, December 12, 12
  • 3.
    3D in WebBrowsers Wednesday, December 12, 12
  • 4.
    3D in WebBrowsers Full power of computer's GPU using only JS, web browser and standard web technology stack. Old way - plugins, native applications New way - WebGL Wednesday, December 12, 12
  • 5.
  • 6.
    So how doyou use it? WebGL is an API, accessed through JavaScript programming interfaces. Analogous to 2D drawing using the HTML5 Canvas element Based on OpenGL ES 2.0 standard Wednesday, December 12, 12
  • 7.
    An (overly) simplifiedExample: Cube with plain WebGL Wednesday, December 12, 12
  • 8.
    // get theWebGL context to access the API var canvas = document.getElementById("lesson04-canvas"); gl = canvas.getContext("experimental-webgl"); // Set up Shaders var fragmentShader = getShader(gl, "shader-fs"); var vertexShader = getShader(gl, "shader-vs"); shaderProgram = gl.createProgram(); gl.attachShader(shaderProgram, vertexShader); gl.attachShader(shaderProgram, fragmentShader); gl.linkProgram(shaderProgram); gl.useProgram(shaderProgram); // .... Wednesday, December 12, 12
  • 9.
    <script id="shader-fs" type="x-shader/x-fragment">     precision mediump float;     varying vec4 vColor;     void main(void) {         gl_FragColor = vColor;     } </script> <script id="shader-vs" type="x-shader/x-vertex">     attribute vec3 aVertexPosition;     attribute vec4 aVertexColor;     uniform mat4 uMVMatrix;     uniform mat4 uPMatrix;     varying vec4 vColor;     void main(void) {         gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);         vColor = aVertexColor;     } </script> Wednesday, December 12, 12
  • 10.
    // A tasteof creating the array of vertices for the cube cubeVertexPositionBuffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexPositionBuffer); vertices = [             // Front face             -1.0, -1.0, 1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, -1.0, 1.0, 1.0,             // Back face             -1.0, -1.0, -1.0, -1.0, 1.0, -1.0, 1.0, 1.0, -1.0, 1.0, -1.0, -1.0,             // Top face             -1.0, 1.0, -1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0,             // Bottom face             -1.0, -1.0, -1.0, 1.0, -1.0, -1.0, 1.0, -1.0, 1.0, -1.0, -1.0, 1.0,             // Right face              1.0, -1.0, -1.0, 1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, -1.0, 1.0,             // Left face             -1.0, -1.0, -1.0, -1.0, -1.0, 1.0, -1.0, 1.0, 1.0, -1.0, 1.0, -1.0        ]; gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW); Wednesday, December 12, 12
  • 11.
    // Rotating thecube with Matrix computations function drawScene() { mat4.translate(mvMatrix, [3.0, 0.0, 0.0]); mat4.rotate(mvMatrix, degToRad(rCube), [1, 1, 1]); gl.uniformMatrix4fv(shaderProgram.mvMatrixUniform, false, mvMatrix); // ... Bind buffers etc. gl.drawElements(gl.TRIANGLES, cubeVertexIndexBuffer.numItems, gl.UNSIGNED_SHORT, 0); // ... } function tick() { requestAnimFrame(tick); rCube += 1; drawScene(); } Wednesday, December 12, 12
  • 12.
    Skills needed forplain WebGL * GLSL, the shading language used by OpenGL and WebGL * Lots of Math for Matrix computation to set up transformations * Creating Vertex buffers to hold data about vertex positions, normals, colors, and textures Wednesday, December 12, 12
  • 13.
    THREE.js to therescue! Wednesday, December 12, 12
  • 14.
    THREE.js * Abstracts away all the painful overhead * Elegant API to create and manipulate Cameras, Objects, Lights, Materials etc. * THREE.js is Open Source Wednesday, December 12, 12
  • 15.
    A Cube exampleusing THREE.js http://learningthreejs.com/data/ lets_do_a_cube/docs/lets_do_a_cube.html Jerome Etienne - great tutorials on THREE.js Wednesday, December 12, 12
  • 16.
    // Set upa Camera camera = new THREE.Camera(70, window.innerWidth / window.innerHeight, 1, 1000); camera.position.y = 150; camera.position.z = 350; camera.target.position.y = 150; // Create a Scene scene = new THREE.Scene(); // Create a Cube material = new THREE.MeshNormalMaterial(); cube = new THREE.Mesh( new THREE.CubeGeometry( 200, 200, 200 ), material); cube.position.y = 150; // Add the Cube to the Scene scene.addObject( cube ); // Boilerplate renderer = new THREE.WebGLRenderer(); renderer.setSize( window.innerWidth, window.innerHeight ); $(“#container”).appendChild( renderer.domElement ); Wednesday, December 12, 12
  • 17.
    function animate() { render(); // Loop requestAnimationFrame( animate ); } function render() { // Rotate cube.rotation.x += 0.02; cube.rotation.y += 0.0225; cube.rotation.z += 0.0175; // Bounce var dtime = Date.now() - startTime; cube.scale.x = 1.0 + 0.3*Math.sin(dtime/300); cube.scale.y = 1.0 + 0.3*Math.sin(dtime/300); cube.scale.z = 1.0 + 0.3*Math.sin(dtime/300); renderer.render( scene, camera ); } Wednesday, December 12, 12
  • 18.
  • 19.
    More Features Renderers WebGL, <canvas>, <svg> Cameras Perspective and orthographic; controllers: trackball, FPS, path and more Lights Ambient, direction, point, spot and hemisphere lights. Cast and receive shadows Materials Lambert, Phong and more - with textures, smooth-shading Shaders Access to full WebGL capabilities like lens flare, depth pass and an extensive post-processing library Objects meshes, particles, sprites, lines, ribbons, ... Geometry plane, cube, sphere, torus, 3D text and more Export/Import utilities to create Three.js-compatible JSON files from: Blender, CTM, FBX, 3D Max, and OBJ Wednesday, December 12, 12
  • 20.
    http://threejs.org/ https://github.com/mrdoob/three.js http://learningthreejs.com Wednesday, December 12, 12
  • 21.