<commit_before><!doctype html>
<html lang="en">

  <head>
    <meta charset="utf-8">

    <title>WebGL through Three JS</title>

    <meta name="apple-mobile-web-app-capable" content="yes" />
    <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />

    <link href='http://fonts.googleapis.com/css?family=Lato:400,700,400italic,700italic' rel='stylesheet' type='text/css'>

    <link rel="stylesheet" href="css/main.css">
    <link rel="stylesheet" href="css/theme/default.css">
    <link rel="stylesheet" href="css/custom.css">

    <!-- For syntax highlighting -->
    <link rel="stylesheet" href="lib/css/zenburn.css">

    <script>
      // If the query includes 'print-pdf' we'll use the PDF print sheet
      document.write( '<link rel="stylesheet" href="css/print/' + ( window.location.search.match( /print-pdf/gi ) ? 'pdf' : 'paper' ) + '.css" type="text/css" media="print">' );
    </script>

    <!--[if lt IE 9]>
    <script src="lib/js/html5shiv.js"></script>
    <![endif]-->
  </head>

  <body>

    <div class="reveal">

      <!-- Used to fade in a background when a specific slide state is reached -->
      <div class="state-background"></div>

      <!-- Any section element inside of this container is displayed as a slide -->
      <div class="slides">
        <section>
          <h1>WebGL with Three JS</h1>
          <h3>Real time rendering in javascript</h3>
          <canvas data-sample="spinning_wireframe_torus"></canvas>
        </section>

        <section>
          <h2>Rendering Techniques</h2>
          <ul>
            <li>
            Rasterization
            <blockquote style="width:90%">
              The task of taking an image described in a vector graphics format (shapes)
              and converting it into a raster image (pixels or dots)
            </blockquote>
            </li>
            <br/>
            <br/>
            <li>Ray Casting</li>
            <li>Ray Tracing</li>
          </ul>
        </section>

        <section>
          <h2>Realtime vs Prerendered</h2>
          <img class="float_left" src="http://origin.arstechnica.com/reviews/games/super-smash-bros-review.media/1.jpg">
          <div class="float_left" style="line-height: 8; padding: 20px">vs</div>
          <img class="float_left" style="width: 320px; " src="http://static.guim.co.uk/sys-images/Film/Pix/pictures/2009/11/13/1258137150094/Avatar-001.jpg">
        </section>

        <section>
          <section>
            <h3> How do we get from </h3>
            <img class="float_left" style="display:inline" src="images/Vertices.png">
            <div class="float_left" style="line-height: 8; padding: 20px">to</div>
            <canvas data-sample="spinning_wireframe_cube" class="float_left" style="display:inline"></canvas>
            <div class="float_left" style="line-height: 5; padding: 20px">?</div>
          </section>

          <section>
            <h2>with Perspective Projection</h2>
            <img class="white_bg" src="http://upload.wikimedia.org/wikipedia/commons/thumb/4/48/Axonometric_projection.svg/467px-Axonometric_projection.svg.png">
          </section>

          <section>
            <h2>What is a vertex?</h2>
            <p>A vertex is a special kind of point that describes the corners or intersections of geometric shapes</p>
            <img class="white_bg" src="http://obviam.net/wp-content/uploads/2011/01/Vertices.png">
          </section>

          <section>
            <h2>Model Space</h2>
            <img class="white_bg" src="http://upload.wikimedia.org/wikipedia/commons/thumb/6/69/Coord_system_CA_0.svg/620px-Coord_system_CA_0.svg.png">
            <!-- <img src="images/apache_model_space.png"> -->
          </section>

          <section>
            <h2>World Space</h2>
            <p>Where all objects are positioned. All objects placed in the actual representation of the world.</p>
            <img src="http://robertokoci.com/images/posts/graphics/game/programming/matrix-unveiled/ObjectWorldSpace.png">
            <!-- <img class="float_left" src="http://www.simulshop.com/product/nemethdesigns/ec135/tn_fsx2008-49-47.jpg" style="height: 70%"> -->
          </section>

          <section>
            <h2>View Space</h2>
            <img src="http://robertokoci.com/images/posts/graphics/game/programming/matrix-unveiled/WorldViewSpace.png">
          </section>

          <section>
            <h2>Projection Space</h2>
            <img src="http://robertokoci.com/images/posts/graphics/game/programming/matrix-unveiled/ProjectionMatrix.png">
          </section>

          <section>
            <h2>Rasterization: Shapes -> Pixels</h2>
            <img src="https://upload.wikimedia.org/wikipedia/commons/thumb/b/bc/Rasterisation-triangle_example.svg/450px-Rasterisation-triangle_example.svg.png">
          </section>

          <section>
            <h2>But how do we ...</h2>
            <br/>
            <br/>
            <h2>transform between spaces?</h2>
            <blockquote>Model -&gt; World -&gt; Screen Space</blockquote>
          </section>
        </section>

        <section>
          <section>
            <h1>Welcome to Linear Algebra</h1>
            <img class="fragment" src="http://cronwtf.github.com/images/wtf.jpg">
          </section>

          <section>
            <h2>Transporters will definitely use Linear Algebra</h2>
            <img src="http://storiesbywilliams.files.wordpress.com/2012/05/transport.jpg">
          </section>

          <section>
            <h3>2D Vector, meet Matrix!</h3>
            <p>Now multiply...</p>
            <img class="float_left" src="http://tutorial.math.lamar.edu/Classes/LinAlg/LinearTransformations_files/image002.gif">
            <br/>
            <ol>
              <li><img class="white_bg" src="images/matrix_multiplication_x_axis_start.png"></li>
              <li class="fragment">
                <img class="white_bg" src="images/matrix_multiplication_x_axis_x.png">
                ( 1 * x ) + ( 0 * y ) = x
              </li>
              <li class="fragment">
                <img class="white_bg" src="images/matrix_multiplication_x_axis_y.png">
                ( 0 * x ) + ( -1 * y ) = -y
              </li>
            </ol>
          </section>

          <section>
            <h3>Linear Transformations</h3>
            <br/>
            <img class="float_left" src="images/SRT_transformations.png">
            <ul style="width:100px;">
              <li>
                identity:<br/>
                <img class="white_bg" style="width: 200px" src="images/identity_matrix.png">
              </li>

              <li class="fragment">
                scaling:<br/>
                <img class="white_bg" style="width: 200px" src="http://upload.wikimedia.org/math/2/6/a/26a088adf02ba09dc958acba0e81a3c3.png">
                <br/>
              </li>

              <li class="fragment">
                rotation:<br/>
                <img class="white_bg" style="width: 200px" src="http://upload.wikimedia.org/math/4/b/d/4bd8fd7253c5bbd65c2e9f8fb7220b19.png">
                <br/>
              </li>

              <li class="fragment small">translation isn't a linear transformation!</li>
            </ul>
          </section>

          <section>
            <h3>Affine Transformtions</h3>
            <p>Adding translations</p>
            <img src="http://people.gnome.org/~mathieu/libart/art-affine-matrix.png">
          </section>

          <section>
            <h2>Projection Matrix</h2>
            <pre style="width: 50%" class="math float_left">
        [1, 0] [x]   [x]
        [0, 0] [y] = [0]
            </pre>
            <p>* We lost a dimension!</p>
            <img src="http://www.arcsynthesis.org/gltut/Positioning/Persp2DProjection.svg">
          </section>

          <section>
            <h3>3D Transformations</h3>
            <p>Just add a dimension!</p>
            <img class="white_bg float_left" src="http://www.riemers.net/images/ExtraReading/matrices1.jpg">
            <img src="http://www.codeguru.com/images/article/10123/3dproj01.gif">
          </section>

          <section>
            <h2>Rendering Demystified</h2>
            <img style="height: 40%" src="http://robertokoci.com/images/posts/graphics/game/programming/matrix-unveiled/ObjectWorldSpace.png">
            <img style="height: 40%" src="http://robertokoci.com/images/posts/graphics/game/programming/matrix-unveiled/WorldViewSpace.png">
            <img style="height: 40%" src="http://robertokoci.com/images/posts/graphics/game/programming/matrix-unveiled/ProjectionMatrix.png">
          </section>

          <section>
            <h2>Composite Transformation</h2>
            <p>Putting it all together</p>
            <img class="white_bg" src="http://upload.wikimedia.org/wikipedia/commons/thumb/4/48/Axonometric_projection.svg/467px-Axonometric_projection.svg.png">
            <blockquote>World_View_Projection_Matrix =<br/> World * View * Projection</blockquote>
          </section>

          <section>
            <h2>Rendering Demystified</h2>
            <img class="float_left" style="display:inline" src="images/Vertices.png">
            <div class="float_left" style="line-height: 8; padding: 20px">to</div>
            <canvas data-sample="spinning_wireframe_cube" style="display:inline"></canvas>
            <p class="medium">----------------------------------
            <br/>
            Model * World_View_Projection_Matrix</p>
          </section>
        </section>

        <section>
          <section>
            <h2>How do we get from</h2>
            <br/>
            <br/>
            <canvas data-sample="spinning_wireframe_cube" class="float_left"></canvas>
            <div class="float_left" style="line-height: 8; padding: 20px">to</div>
            <canvas data-sample="spinning_textured_cube" class="float_left"></canvas>
            <div class="float_left" style="line-height: 8; padding: 20px">?</div>
          </section>

          <section>
            <h2>
              Coloring the pixels:<br/>
              Texture and Lighting
            </h2>
            <img class="float_left" src="https://upload.wikimedia.org/wikipedia/commons/thumb/b/bc/Rasterisation-triangle_example.svg/450px-Rasterisation-triangle_example.svg.png">
            <canvas data-sample="spinning_wireframe_cube" class="float_left"></canvas>
            <canvas data-sample="spinning_textured_cube" class="float_left"></canvas>
          </section>

          <section>
            <h2>Texture: UV Mapping</h2>
            <p>Getting the value of the color...<p>
            <img src="http://www.bcu.ac.uk/_media/img/nti/gamer_camp/blog_postings/UvMapping.jpg">
          </section>

          <section>
            <h2>Texture: UV Mapping</h2>
            <img src="http://www.bcu.ac.uk/_media/img/nti/gamer_camp/blog_postings/PsxStyleSingleTextureMesh.jpg">
          </section>

          <section>
            <h2>Lighting</h2>
            <p>Getting the strength of the color...</p>
            <br/>
            <img src="http://lh5.ggpht.com/_QLwms0mVa4w/Sfn4HH_HGxI/AAAAAAAAAS4/ZpGr11BjJVk/component.jpg">
          </section>

          <section>
            <h2>Lighting: Ambient</h2>
            <canvas data-sample="spinning_textured_cube"></canvas>
          </section>

          <section>
            <h2>Lighting: Lambert</h2>
            <canvas data-sample="lighted_sphere"></canvas>
          </section>

          <section>
            <h2>But how do we ...</h2>
            <h2>get the amount of color?</h2>
            <blockquote>Putting the rgba in a pixel's RGBA</blockquote>
            <canvas data-sample="lighted_sphere"></canvas>
          </section>
        </section>

        <section>
          <section>
            <h1>Welcome BACK to Linear Algebra</h1>
            <img src="http://cronwtf.github.com/images/wtf.jpg">
          </section>

          <section>
            <h2>The Normal</h2>
            <img class="white_bg" src="https://encrypted-tbn3.google.com/images?q=tbn:ANd9GcSQyYxnsLVkIT5QpVBGJ00IDOcIrLPMPUXIyabQYuXZQxOuIGKN">
          </section>

          <section>
            <h2>Lighting</h2>
            <img class="float_left" style="width: 30%"
            src="https://upload.wikimedia.org/wikipedia/commons/thumb/b/bc/Rasterisation-triangle_example.svg/450px-Rasterisation-triangle_example.svg.png">
            <img src="images/shader_vectors.gif">
          </section>

          <section>
            <h2>The Dot Product</h2>
            <img class="white_bg" src="http://upload.wikimedia.org/wikipedia/commons/thumb/3/3e/Dot_Product.svg/300px-Dot_Product.svg.png">
          </section>

          <section>
            <h2>Lighting</h2>
            <img class="float_left" style="width: 25%"
            src="https://upload.wikimedia.org/wikipedia/commons/thumb/b/bc/Rasterisation-triangle_example.svg/450px-Rasterisation-triangle_example.svg.png">
            <img style="width: 70%" src="images/reflection_vector.gif">
          </section>

          <section>
            <h2>Per Pixel Lighting</h2>
            <canvas data-sample="normal_mapped_plane"></canvas>
          </section>
        </section>

        <section>
          <section>
            <h2>Graphic Pipelines: How it started</h2>
            <h3>Software Rendering</h3>
            <img style="width: 480px;" src="http://1.bp.blogspot.com/-tQMjfiveb88/T5HvOfXc63I/AAAAAAAAB38/P_Nmtyw7-v8/s1600/prince-of-persia.gif">
            <ul>
              <li>Entirely done on CPU</li>
              <li>Unaided by graphics hardware</li>
              <li>Ultimate flexibility</li>
            </ul>
          </section>

          <section>
            <h3>How it was: Fixed Function Pipeline</h3>
            <img src="http://www.many-core.group.cam.ac.uk/platforms/pipeline_big.png">
            <ul>
              <li>Introduction of GPU hardware support</li>
              <li>Sacrificed flexibility for speed</li>
            </ul>
          </section>

          <section>
            <h3>How it was: Fixed Function Pipeline</h3>
            <img src="http://cdn.steampowered.com/v/gfx/apps/2310/0000002448.600x338.jpg?t=1343157013">
            <img src="http://www.techspot.com/reviews/hardware/voodoo3-3000/box_p.jpg">
            <small style="font-size: 10px; display: block;">I couldn't find an image of a voodoo 1 card</small>
          </section>

          <section>
            <h2>The Graphics Card</h2>
            <img class="white_bg" src="http://www.sjbaker.org/wiki/images/thumb/3/31/Graphics_pipeline.png/800px-Graphics_pipeline.png">
          </section>

          <section>
            <h3>How it is: Programmable Graphics Pipeline</h3>
            <!-- <img src="http://chrisingradschool.files.wordpress.com/2010/03/screen-shot-2010-03-09-at-2-13-26-pm.png?w=600&h=279"> -->
            <img src="http://www.many-core.group.cam.ac.uk/platforms/pipeline_big.png">
          </section>

          <section>
            <h3>How it is: Programmable Graphics Pipeline</h3>
            <img src="http://chrisingradschool.files.wordpress.com/2010/03/screen-shot-2010-03-09-at-2-13-26-pm.png?w=600&h=279">
          </section>

          <section>
            <h3>How it is: Programmable Graphics Pipeline</h3>
            <img src="http://4.bp.blogspot.com/-2YJsDFkdVqM/Tx_J4bw8HnI/AAAAAAAAATk/Y1RN1finStI/s1600/Call-of-Duty-Modern-Warfare-3-Gameplay-Reveal-Trailer_3.jpg">
            <p>Best of both worlds (almost)</p>
          </section>
        </section>

        <section>
          <section>
            <h1>What is WebGL?</h1>
            <p>OpenGL ES2.0 port built into the &lt;canvas&gt; DOM element</p>
          </section>

          <section>
            <h3> How do we get from </h3>
            <img class="float_left" style="display:inline" src="images/Vertices.png">
            <div class="float_left" style="line-height: 8; padding: 20px">to</div>
            <canvas data-sample="webgl_spinning_colored_cube" id="example" class="float_left" style="display:inline"></canvas>
            <div class="float_left" style="line-height: 5; padding: 20px">?</div>
          </section>

          <section>
          <h3>wtf</h3>
            <pre class="supersmall float_left" style="width:50%"><code>
function init(scene) {
  // Initialize
  var gl = WebGLUtils.setupWebGL(scene.canvas);
  if (!gl) {
    return;
  }

  scene.program = simpleSetup(
    gl,
    // The ids of the vertex and fragment shaders
    "vshader", "fshader",
    // The vertex attribute names used by the shaders.
    // The order they appear here corresponds to their index
    // used later.
    [ "vNormal", "vColor", "vPosition"],
    // The clear color and depth values
    [ 0, 0, 0, 0 ], 10000);

  // Set up a uniform variable for the shaders
  gl.uniform3f(gl.getUniformLocation(scene.program, "lightDir"), 0, 0, 1);

  // Create a box. On return 'gl' contains a 'box' property with
  // the BufferObjects containing the arrays for vertices,
  // normals, texture coords, and indices.
  scene.box = makeBox(gl);

  // Set up the array of colors for the cube's faces
  var colors = new Uint8Array(
    [  0, 0, 1, 1,   0, 0, 1, 1,   0, 0, 1, 1,   0, 0, 1, 1,     // v0-v1-v2-v3 front
      1, 0, 0, 1,   1, 0, 0, 1,   1, 0, 0, 1,   1, 0, 0, 1,     // v0-v3-v4-v5 right
      0, 1, 0, 1,   0, 1, 0, 1,   0, 1, 0, 1,   0, 1, 0, 1,     // v0-v5-v6-v1 top
      1, 1, 0, 1,   1, 1, 0, 1,   1, 1, 0, 1,   1, 1, 0, 1,     // v1-v6-v7-v2 left
      1, 0, 1, 1,   1, 0, 1, 1,   1, 0, 1, 1,   1, 0, 1, 1,     // v7-v4-v3-v2 bottom
      0, 1, 1, 1,   0, 1, 1, 1,   0, 1, 1, 1,   0, 1, 1, 1 ]    // v4-v7-v6-v5 back
  );

  // Set up the vertex buffer for the colors
  scene.box.colorObject = gl.createBuffer();
  gl.bindBuffer(gl.ARRAY_BUFFER, scene.box.colorObject);
  gl.bufferData(gl.ARRAY_BUFFER, colors, gl.STATIC_DRAW);

  // Create some matrices to use later and save their locations in the shaders
  scene.mvMatrix = new J3DIMatrix4();
  scene.u_normalMatrixLoc = gl.getUniformLocation(scene.program, "u_normalMatrix");
  scene.normalMatrix = new J3DIMatrix4();
  scene.u_modelViewProjMatrixLoc =
    gl.getUniformLocation(scene.program, "u_modelViewProjMatrix");
  scene.mvpMatrix = new J3DIMatrix4();

  // Enable all of the vertex attribute arrays.
  gl.enableVertexAttribArray(0);
  gl.enableVertexAttribArray(1);
  gl.enableVertexAttribArray(2);

  // Set up all the vertex attributes for vertices, normals and colors
  gl.bindBuffer(gl.ARRAY_BUFFER, scene.box.vertexObject);
  gl.vertexAttribPointer(2, 3, gl.FLOAT, false, 0, 0);

  gl.bindBuffer(gl.ARRAY_BUFFER, scene.box.normalObject);
  gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0);

  gl.bindBuffer(gl.ARRAY_BUFFER, scene.box.colorObject);
  gl.vertexAttribPointer(1, 4, gl.UNSIGNED_BYTE, false, 0, 0);

  // Bind the index array
  gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, scene.box.indexObject);

  return gl;
}
            </code></pre>
            <pre class="supersmall float_left" style="width:50%"><code>
function reshape(scene, gl) {
  var canvas = scene.canvas;

  // Set the viewport and projection matrix for the scene
  gl.viewport(0, 0, canvas.width, canvas.height);
  scene.perspectiveMatrix = new J3DIMatrix4();
  scene.perspectiveMatrix.perspective(30, canvas.width/canvas.height, 1, 10000);
  scene.perspectiveMatrix.lookat(0, 0, 7, 0, 0, 0, 0, 1, 0);
}

function drawPicture(scene, gl) {
  // Make sure the canvas is sized correctly.
  reshape(scene, gl);

  // Clear the canvas
  gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);

  // Make a model/view matrix.
  scene.mvMatrix.makeIdentity();
  scene.mvMatrix.rotate(20, 1,0,0);
  scene.mvMatrix.rotate(scene.currentAngle, 0,1,0);

  // Construct the normal matrix from the model-view matrix and pass it in
  scene.normalMatrix.load(scene.mvMatrix);
  scene.normalMatrix.invert();
  scene.normalMatrix.transpose();
  scene.normalMatrix.setUniform(gl, scene.u_normalMatrixLoc, false);

  // Construct the model-view * projection matrix and pass it in
  scene.mvpMatrix.load(scene.perspectiveMatrix);
  scene.mvpMatrix.multiply(scene.mvMatrix);
  scene.mvpMatrix.setUniform(gl, scene.u_modelViewProjMatrixLoc, false);

  // Draw the cube
  gl.drawElements(gl.TRIANGLES, scene.box.numIndices, gl.UNSIGNED_BYTE, 0);

  scene.currentAngle += scene.incAngle;
  if (scene.currentAngle > 360)
    scene.currentAngle -= 360;
}

window.samples.webgl_spinning_cube = {

  initialize: function(canvas) {
    var scene = { canvas: canvas };

    canvas.addEventListener('webglcontextlost', handleContextLost, false);
    canvas.addEventListener('webglcontextrestored', handleContextRestored, false);

    canvas.width = sample_defaults.width;
    canvas.height = sample_defaults.height;

    var gl = init(scene);
    if (!gl) {
      return;
    }

    scene.currentAngle = 0;
    scene.incAngle = 0.5;

    var requestId;
    function animate() {
      drawPicture(scene, gl);
      requestId = window.requestAnimFrame(animate, canvas);
    }

    animate();

    function handleContextLost(e) {
      e.preventDefault();
      if (requestId !== undefined) {
        window.cancelAnimFrame(requestId);
        requestId = undefined;
      }
    }

    function handleContextRestored() {
      init(scene);
      animate();
    }
  }
            </code></pre>
          </section>

          <section>
            <h2>What we care about</h2>
            <pre class="code"><code class="javascript">
function drawPicture(scene, gl) {
  // Clear the canvas
  gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);

  // Set the viewport and projection matrix for the scene
  gl.viewport(0, 0, canvas.width, canvas.height);
  scene.perspectiveMatrix = new J3DIMatrix4();
  scene.perspectiveMatrix.perspective(30, canvas.width/canvas.height, 1, 10000);
  scene.perspectiveMatrix.lookat(0, 0, 7, 0, 0, 0, 0, 1, 0);

  // Make a model/view matrix.
  scene.mvMatrix.makeIdentity();
  scene.mvMatrix.rotate(20, 1,0,0);
  scene.mvMatrix.rotate(scene.currentAngle, 0,1,0);

  // Construct the model-view * projection matrix and pass it in
  scene.mvpMatrix.load(scene.perspectiveMatrix);
  scene.mvpMatrix.multiply(scene.mvMatrix);

  // Pass it in to the Vertex Shader
  scene.mvpMatrix.setUniform(gl, scene.u_modelViewProjMatrixLoc, false);

  // Draw the cube
  gl.drawElements(gl.TRIANGLES, scene.box.numIndices, gl.UNSIGNED_BYTE, 0);
}
            </code></pre>
          </section>

          <section>
            <h2>Vertex Shader</h2>
            <pre style="font-size:18px; line-height: 24px;" class="code"><code class="javascript">
    uniform mat4 u_modelViewProjMatrix; // Passed in from CPU

    attribute vec4 vPosition; // Information from vertex

    void main()
    {
        gl_Position = u_modelViewProjMatrix * vPosition;
    }
            </code></pre>
            <img class="float_left" style="width: 30%"
            src="https://upload.wikimedia.org/wikipedia/commons/thumb/b/bc/Rasterisation-triangle_example.svg/450px-Rasterisation-triangle_example.svg.png">
            <canvas data-sample="webgl_spinning_wireframe_cube" style="display:inline"></canvas>
          </section>

          <section>
            <h3>Fragment Shader</h3>
            <p>Per Vertex Lighting. Not per pixel lighting.</p>
            <pre style="font-size:18px; line-height: 24px;" class="code"><code class="javascript">
    void main()
    {
        gl_FragColor = vec4(1, 1, 1, 1); // RGBA
    }
            </code></pre>
            <img class="float_left" style="width: 30%"
            src="https://upload.wikimedia.org/wikipedia/commons/thumb/b/bc/Rasterisation-triangle_example.svg/450px-Rasterisation-triangle_example.svg.png">
            <canvas data-sample="webgl_spinning_bland_cube" style="display:inline"></canvas>
          </section>

          <section>
            <h2>Single Instruction, Multiple Data (SIMD)</h2>
            <br/>
            <br/>
            <p>GPUs are often wide SIMD implementations, capable of branches, loads, and stores on 128 or 256 bits at a time.</p>
          </section>

          <section>
            <h2>Vertex Shader</h2>
            <pre style="font-size:18px; line-height: 24px;" class="code"><code class="cpp">
    uniform mat4 u_modelViewProjMatrix; // Passed in from CPU
    uniform mat4 u_normalMatrix;
    uniform vec3 lightDir;

    attribute vec3 vNormal; // Received from Vertex
    attribute vec4 vColor;
    attribute vec4 vPosition;

    varying float v_Dot; // Variables passed to Fragment Shader
    varying vec4 v_Color;

    void main()
    {
        gl_Position = u_modelViewProjMatrix * vPosition;
        v_Color = vColor;
        vec4 transNormal = u_normalMatrix * vec4(vNormal, 1);
        v_Dot = max(dot(transNormal.xyz, lightDir), 0.0);
    }
            </code></pre>
          </section>

          <section>
            <h3>Fragment Shader</h3>
            <p>Per Vertex Lighting. Not per pixel lighting.</p>
            <pre style="font-size:18px; line-height: 24px;" class="code"><code class="cpp">
    precision mediump float;

    varying float v_Dot; // Passed in from Vertex Shader
    varying vec4 v_Color;

    void main()
    {
        gl_FragColor = vec4(v_Color.xyz * v_Dot, v_Color.a);
    }
            </code></pre>
            <canvas data-sample="webgl_spinning_colored_cube" style="display:inline"></canvas>
          </section>

        </section>

        <section>
          <section>
            <h1>What is ThreeJS?</h1>
            <blockquote class="medium" style="margin-top: 80px; width: 100%">
              The aim of the project is to create a lightweight 3D library with a very low level of complexity — in other words, for dummies.
              <br/>
              <br/>
              The library provides &lt;canvas&gt;, &lt;svg&gt; and WebGL renderers.
            </blockquote>
          </section>

          <section>
            <h3> How do we get from </h3>
            <img class="float_left" style="display:inline" src="images/Vertices.png">
            <div class="float_left" style="line-height: 8; padding: 20px">to</div>
            <canvas data-sample="spinning_cube" class="float_left" style="display:inline"></canvas>
            <div class="float_left" style="line-height: 5; padding: 20px">?</div>
          </section>

          <section>
            <h3>Intro to ThreeJS: Spinning Cube</h3>
            <pre class="code"><code>
function init(canvas) {
  var scene = new THREE.Scene();

  var camera = new THREE.PerspectiveCamera( 75, 320/240, 1, 1000 );
  camera.position.z = 100;

  var geometry = new THREE.CubeGeometry( 70, 70, 70 );
  var material = new THREE.MeshBasicMaterial( { color: 0xdddddd } );

  var mesh = new THREE.Mesh( geometry, material );
  scene.add( mesh );

  var renderer = new THREE.WebGLRenderer({canvas: canvas});
  renderer.setSize( 320, 240 );

  function animate() {
    // note: three.js includes requestAnimationFrame shim
    requestAnimationFrame( animate );

    mesh.rotation.x += 0.01;
    mesh.rotation.y += 0.02;
    renderer.render( scene, camera );
  }
  animate();
}
            </code></pre>
            <p class="supersmall">16 lines of code</p>
          </section>

          <section>
            <h3>Scene</h3>
            <pre class="medium"><code>
function init(canvas) {
  var scene = new THREE.Scene();
            </code></pre>
            <br/>
            <p>Encapsulates everything with regard to this rendering!</p>
            <ul>
              <li>All global matrices</li>
              <li>Models</li>
              <li>Camera</li>
            </ul>
          </section>

          <section>
            <h3>Camera</h3>
            <pre class="medium"><code>
var camera = new THREE.PerspectiveCamera(75, 320/240, 1, 1000);
camera.position.z = 100;
            </code></pre>
            <div style="width:120%">
              <img style="height: 50%" class="float_left" src="http://robertokoci.com/images/posts/graphics/game/programming/matrix-unveiled/WorldViewSpace.png">
              <img style="height: 50%" src="http://robertokoci.com/images/posts/graphics/game/programming/matrix-unveiled/ProjectionMatrix.png">
            </div>
          </section>

          <section>
            <h3>Geometry</h3>
            <pre class="medium"><code>
  var geometry = new THREE.CubeGeometry( 70, 70, 70 );
            </code></pre>
            <img class="white_bg" src="http://obviam.net/wp-content/uploads/2011/01/Vertices.png">
          </section>

          <section>
            <h3>Materials</h3>
            <pre class="medium"><code>
var material = new THREE.MeshLambertMaterial({ color: 0xdddddd });
            </code></pre>
            <p>Actually an OpenGL concept. Encapsulates:</p>
            <ul>
              <li>Texture</li>
              <li>Lighting</li>
              <li>Fragment Shader</li>
            </p>
          </section>

          <section>
            <h3>Mesh</h3>
            <pre class="medium"><code>
  var mesh = new THREE.Mesh( geometry, material );
  scene.add( mesh );
            </code></pre>
            <br/>
            <p>Associate geometry with a material to make a mesh.</p>
            <p>Also creates a world matrix for the mesh, defaulting it to the identity</p>
          </section>

          <section>
            <h3>Renderer</h3>
            <pre class="medium"><code>
  var renderer = new THREE.WebGLRenderer({canvas: canvas});
  renderer.setSize( 320, 240 );
            </code></pre>
            <br/>
            <p>The moment you add lighting, the WebGLRenderer's performance tanks.</p>
          </section>

          <section>
            <h3>requestAnimationFrame?</h3>
            <p>Welcome to the Render Loop</p>
            <pre class="medium"><code>
  function animate() {
    // note: three.js includes requestAnimationFrame shim
    requestAnimationFrame( animate );

    mesh.rotation.x += 0.01;
    mesh.rotation.y += 0.02;
    renderer.render( scene, camera );
  }
  animate();
            </code></pre>
          </section>

          <section data-state="boom">
            <h1>BOOM!</h1>
            <canvas data-sample="spinning_cube"></canvas>
          </section>
        </section>

        <section>
          <section>
            <h2>ThreeJS: Loading Meshes</h2>
            <br/>
            <ul>
              <li>Leverage CAD design tools to create models</li>
              <li>Grab models from <a href="http://www.blendswap.com/blends/vehicles/star-trek-collection/">Blendswap: Startrek Collection</a></li>
            </ul>
          </section>

          <section>
            <h2>Blender and ThreeJS</h2>
            <br/>
            <ul>
              <li>Can export to the Three js file format</li>
              <li><a href="js/meshes/Startrek_Enterprise.js">Startrek Enterprise Mesh</a></li>
              <li><p>Credit for model goes to <a href="http://www.blendswap.com/?author=3134"><NAME></a></p></li>
            </ul>
          </section>

          <section>
            <h2>ThreeJS: Importing Mesh</h2>
            <br/>
            <pre class="medium"><code>
// REMOVED
// var geometry = new THREE.CubeGeometry( 70, 70, 70 );
// var material = new THREE.MeshLambertMaterial({color: 0xdddddd});

var loader = new THREE.JSONLoader();
loader.load("js/meshes/Startrek_Enterprise.js", function(geometry) {

  mesh = new THREE.Mesh( geometry, geometry.materials[0] );
  scene.add( mesh );
  ...
            </code></pre>
          </section>

          <section data-state="loaded_enterprise">
            <h2>BOOM!</h2>
            <canvas data-sample="load_startrek_enterprise"></canvas>
          </section>

          <section data-state="loaded_apache">
            <h2>with Textures</h2>
            <a href="images/FinalApacheTexture.png">Apache Texture File</a>
            <canvas data-sample="load_apache"></canvas>
          </section>
        </section>

        <section>
          <section>
            <h2>ThreeJS: Particles</h2>
            <img style="width:850px;" src="http://3dgep.com/wp-content/uploads/2011/02/OpenGL-Primitives.png">
          </section>

          <section>
            <h2>ThreeJS: Particles</h2>
            <canvas data-sample="particles"></canvas>
          </section>

          <section>
            <h2>ThreeJS: Particles</h2>
            <pre class="code medium"><code class="cpp">
    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 );
    }
    ...
            </code></pre>
            <br/>
            <pre class="code medium"><code class="cpp">
    particles = new THREE.ParticleSystem( geometry, materials[i] );

    scene.add( particles );
            </code></pre>
          </section>

          <section>
            <h2>Rendering a Million: Batch your draw calls</h2>
            <ul>
              <li><a href="http://www.html5rocks.com/en/tutorials/webgl/million_letters/million_letters.html">A Million Letters</a></li>
            </ul>
          </section>

          <section>
            <h2>How do we animate a million particles?</h2>
            <img class="white_bg" src="http://www.sjbaker.org/wiki/images/thumb/3/31/Graphics_pipeline.png/800px-Graphics_pipeline.png">
          </section>

          <section>
            <h3>ThreeJS: Vertex Textures</h3>
            <p>Using the RGB for your XYZ</p>
            <img class="float_left" src="http://upload.wikimedia.org/wikipedia/commons/5/57/Heightmap.png">
            <img class="float_left" src="http://upload.wikimedia.org/wikipedia/commons/2/2f/Heightmap_rendered.png">
          </section>

          <section>
            <h3>Showcase: A Million Particles</h3>
            <ul>
              <li><a href="http://mrdoob.com/lab/javascript/webgl/particles/magicdust.html">Magic Dust Particles</a></li>
            </ul>
          </section>
        </section>

        <section>
          <section>
            <h2>Fragment Shaders: Normal Mapping</h2>
            <p>Using the RGB for your <b><u>normal's</u></b> XYZ</p>
            <img src="http://img.photobucket.com/albums/v348/spartan_mortis/chiefnoshader.jpg">
          </section>

          <section>
            <h2>Normal Mapping: Per Pixel Lighting</h2>
            <img class="float_left" style="width: 25%"
            src="https://upload.wikimedia.org/wikipedia/commons/thumb/b/bc/Rasterisation-triangle_example.svg/450px-Rasterisation-triangle_example.svg.png">
            <img style="width: 70%" src="images/reflection_vector.gif">
          </section>

          <section>
            <h2>Normal Map</h2>
            <img src="images/normal_map_tile.jpg">
          </section>

          <section>
            <h2>Normal Map</h2>
            <canvas data-sample="normal_mapped_plane" class="float_left" style="display:inline"></canvas>
            <canvas data-sample="wireframe_plane" class="float_left" style="display:inline"></canvas>
            <img src="images/normal_map_tile.jpg" class="float_left normal_map" style="width:200px">
          </section>

          <section>
            <h2>ThreeJS: Custom Shaders</h2>
              <pre class="code medium"><code class="javascript">
  var vertexShader = $('#normal_map_vs').text();
  var fragmentShader = $('#normal_map_fs').text();

  var parameters = {
    fragmentShader: fragmentShader,
    vertexShader: vertexShader,
    uniforms: uniforms,
    attributes: attributes,
    side: THREE.DoubleSide
  };

  var normal_material = new THREE.ShaderMaterial( parameters );
  var mesh = new THREE.Mesh( geometry, normal_material );
  scene.add( mesh );
              </code></pre>
          </section>

          <section>
            <h2>Showcase: Skin Material</h2>
            <a href="http://mrdoob.github.com/three.js/examples/webgl_materials_bumpmap_skin.html">WebGL Skin Material</a>
          </section>
        </section>

        <section>
          <section>
            <h2>Post-Processing: Blur</h2>
            <canvas class="float_left" data-sample="spinning_textured_cube"></canvas><commit_msg>Remove unnecessary slides and images<commit_after><!doctype html>
<html lang="en">

  <head>
    <meta charset="utf-8">

    <title>WebGL through Three JS</title>

    <meta name="apple-mobile-web-app-capable" content="yes" />
    <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />

    <link href='http://fonts.googleapis.com/css?family=Lato:400,700,400italic,700italic' rel='stylesheet' type='text/css'>

    <link rel="stylesheet" href="css/main.css">
    <link rel="stylesheet" href="css/theme/default.css">
    <link rel="stylesheet" href="css/custom.css">

    <!-- For syntax highlighting -->
    <link rel="stylesheet" href="lib/css/zenburn.css">

    <script>
      // If the query includes 'print-pdf' we'll use the PDF print sheet
      document.write( '<link rel="stylesheet" href="css/print/' + ( window.location.search.match( /print-pdf/gi ) ? 'pdf' : 'paper' ) + '.css" type="text/css" media="print">' );
    </script>

    <!--[if lt IE 9]>
    <script src="lib/js/html5shiv.js"></script>
    <![endif]-->
  </head>

  <body>

    <div class="reveal">

      <!-- Used to fade in a background when a specific slide state is reached -->
      <div class="state-background"></div>

      <!-- Any section element inside of this container is displayed as a slide -->
      <div class="slides">
        <section>
          <h1>WebGL with Three JS</h1>
          <h3>Real time rendering in javascript</h3>
          <canvas data-sample="spinning_wireframe_torus"></canvas>
        </section>

        <section>
          <h2>Rendering Techniques</h2>
          <ul>
            <li>
            Rasterization
            <blockquote style="width:90%">
              The task of taking an image described in a vector graphics format (shapes)
              and converting it into a raster image (pixels or dots)
            </blockquote>
            </li>
            <br/>
            <br/>
            <li>Ray Casting</li>
            <li>Ray Tracing</li>
          </ul>
        </section>

        <section>
          <h2>Realtime vs Prerendered</h2>
          <img class="float_left" src="http://origin.arstechnica.com/reviews/games/super-smash-bros-review.media/1.jpg">
          <div class="float_left" style="line-height: 8; padding: 20px">vs</div>
          <img class="float_left" style="width: 320px; " src="http://static.guim.co.uk/sys-images/Film/Pix/pictures/2009/11/13/1258137150094/Avatar-001.jpg">
        </section>

        <section>
          <section>
            <h3> How do we get from </h3>
            <img class="float_left" style="display:inline" src="images/Vertices.png">
            <div class="float_left" style="line-height: 8; padding: 20px">to</div>
            <canvas data-sample="spinning_wireframe_cube" class="float_left" style="display:inline"></canvas>
            <div class="float_left" style="line-height: 5; padding: 20px">?</div>
          </section>

          <section>
            <h2>What is a vertex?</h2>
            <p>A vertex is a special kind of point that describes the corners or intersections of geometric shapes</p>
            <img class="white_bg" src="http://obviam.net/wp-content/uploads/2011/01/Vertices.png">
          </section>

          <section>
            <h2>World Space</h2>
            <p>Where all objects are positioned. All objects placed in the actual representation of the world.</p>
            <img src="http://robertokoci.com/images/posts/graphics/game/programming/matrix-unveiled/ObjectWorldSpace.png">
            <!-- <img class="float_left" src="http://www.simulshop.com/product/nemethdesigns/ec135/tn_fsx2008-49-47.jpg" style="height: 70%"> -->
          </section>

          <section>
            <h2>View Space</h2>
            <img src="http://robertokoci.com/images/posts/graphics/game/programming/matrix-unveiled/WorldViewSpace.png">
          </section>

          <section>
            <h2>Projection Space</h2>
            <img src="http://robertokoci.com/images/posts/graphics/game/programming/matrix-unveiled/ProjectionMatrix.png">
          </section>

          <section>
            <h2>Rasterization: Shapes -> Pixels</h2>
            <img src="https://upload.wikimedia.org/wikipedia/commons/thumb/b/bc/Rasterisation-triangle_example.svg/450px-Rasterisation-triangle_example.svg.png">
          </section>

          <section>
            <h2>But how do we ...</h2>
            <br/>
            <br/>
            <h2>transform between spaces?</h2>
            <blockquote>Model -&gt; World -&gt; Screen Space</blockquote>
          </section>
        </section>

        <section>
          <section>
            <h1>Welcome to Linear Algebra</h1>
            <img class="fragment" src="http://cronwtf.github.com/images/wtf.jpg">
          </section>

          <section>
            <h2>Transporters will definitely use Linear Algebra</h2>
            <img src="http://storiesbywilliams.files.wordpress.com/2012/05/transport.jpg">
          </section>

          <section>
            <h3>2D Vector, meet Matrix!</h3>
            <p>Now multiply...</p>
            <img class="float_left" src="http://tutorial.math.lamar.edu/Classes/LinAlg/LinearTransformations_files/image002.gif">
            <br/>
            <ol>
              <li><img class="white_bg" src="images/matrix_multiplication_x_axis_start.png"></li>
              <li class="fragment">
                <img class="white_bg" src="images/matrix_multiplication_x_axis_x.png">
                ( 1 * x ) + ( 0 * y ) = x
              </li>
              <li class="fragment">
                <img class="white_bg" src="images/matrix_multiplication_x_axis_y.png">
                ( 0 * x ) + ( -1 * y ) = -y
              </li>
            </ol>
          </section>

          <section>
            <h3>Transformations</h3>
            <br/>
            <img class="float_left" src="images/SRT_transformations.png">
            <img src="http://people.gnome.org/~mathieu/libart/art-affine-matrix.png">
            <ul style="width:100px;">
              <li>
                identity:<br/>
                <img class="white_bg" style="width: 200px" src="images/identity_matrix.png">
              </li>

              <li class="fragment">
                scaling:<br/>
                <img class="white_bg" style="width: 200px" src="http://upload.wikimedia.org/math/2/6/a/26a088adf02ba09dc958acba0e81a3c3.png">
                <br/>
              </li>

              <li class="fragment">
                rotation:<br/>
                <img class="white_bg" style="width: 200px" src="http://upload.wikimedia.org/math/4/b/d/4bd8fd7253c5bbd65c2e9f8fb7220b19.png">
                <br/>
              </li>

              <li class="fragment small">translation isn't a linear transformation!</li>
            </ul>
          </section>

          <section>
            <h2>Projection Matrix</h2>
            <pre style="width: 50%" class="math float_left">
        [1, 0] [x]   [x]
        [0, 0] [y] = [0]
            </pre>
            <p>* We lost a dimension!</p>
            <img src="http://www.arcsynthesis.org/gltut/Positioning/Persp2DProjection.svg">
          </section>

          <section>
            <h2>Rendering Demystified</h2>
            <img style="height: 40%" src="http://robertokoci.com/images/posts/graphics/game/programming/matrix-unveiled/ObjectWorldSpace.png">
            <img style="height: 40%" src="http://robertokoci.com/images/posts/graphics/game/programming/matrix-unveiled/WorldViewSpace.png">
            <img style="height: 40%" src="http://robertokoci.com/images/posts/graphics/game/programming/matrix-unveiled/ProjectionMatrix.png">
          </section>

          <section>
            <h2>Composite Transformation</h2>
            <p>Putting it all together</p>
            <img class="white_bg" src="http://upload.wikimedia.org/wikipedia/commons/thumb/4/48/Axonometric_projection.svg/467px-Axonometric_projection.svg.png">
            <blockquote>World_View_Projection_Matrix =<br/> World * View * Projection</blockquote>
          </section>

          <section>
            <h3>3D Transformations</h3>
            <p>Just add a dimension!</p>
            <img class="white_bg float_left" src="http://www.riemers.net/images/ExtraReading/matrices1.jpg">
            <img src="http://www.codeguru.com/images/article/10123/3dproj01.gif">
          </section>

          <section>
            <h2>Rendering Demystified</h2>
            <img class="float_left" style="display:inline" src="images/Vertices.png">
            <div class="float_left" style="line-height: 8; padding: 20px">to</div>
            <canvas data-sample="spinning_wireframe_cube" style="display:inline"></canvas>
            <p class="medium">----------------------------------
            <br/>
            Model * World_View_Projection_Matrix</p>
          </section>
        </section>

        <section>
          <section>
            <h2>How do we get from</h2>
            <br/>
            <br/>
            <canvas data-sample="spinning_wireframe_cube" class="float_left"></canvas>
            <div class="float_left" style="line-height: 8; padding: 20px">to</div>
            <canvas data-sample="spinning_textured_cube" class="float_left"></canvas>
            <div class="float_left" style="line-height: 8; padding: 20px">?</div>
          </section>

          <section>
            <h2>
              Coloring the pixels:<br/>
              Texture and Lighting
            </h2>
            <img class="float_left" src="https://upload.wikimedia.org/wikipedia/commons/thumb/b/bc/Rasterisation-triangle_example.svg/450px-Rasterisation-triangle_example.svg.png">
            <canvas data-sample="spinning_wireframe_cube" class="float_left"></canvas>
            <canvas data-sample="spinning_textured_cube" class="float_left"></canvas>
          </section>

          <section>
            <h2>Texture: UV Mapping</h2>
            <p>Getting the value of the color...<p>
            <img src="http://www.bcu.ac.uk/_media/img/nti/gamer_camp/blog_postings/UvMapping.jpg">
          </section>

          <section>
            <h2>Lighting</h2>
            <p>Getting the strength of the color...</p>
            <br/>
            <img src="http://lh5.ggpht.com/_QLwms0mVa4w/Sfn4HH_HGxI/AAAAAAAAAS4/ZpGr11BjJVk/component.jpg">
          </section>

          <section>
            <h2>Lighting: Ambient, Diffuse, Specular</h2>
            <canvas data-sample="lighted_sphere"></canvas>
          </section>

          <section>
            <h2>Materials</h2>
            <canvas data-sample="spinning_cube"></canvas>
            <p>Combine texture and lighting</p>
          </section>

          <section>
            <h2>But how do we ...</h2>
            <h2>get the amount of color?</h2>
            <blockquote>Putting the rgba in a pixel's RGBA</blockquote>
            <canvas data-sample="lighted_sphere"></canvas>
          </section>
        </section>

        <section>
          <section>
            <h1>Welcome BACK to Linear Algebra</h1>
            <img src="http://cronwtf.github.com/images/wtf.jpg">
          </section>

          <section>
            <h2>The Normal</h2>
            <img class="white_bg" src="https://encrypted-tbn3.google.com/images?q=tbn:ANd9GcSQyYxnsLVkIT5QpVBGJ00IDOcIrLPMPUXIyabQYuXZQxOuIGKN">
          </section>

          <section>
            <h2>Lighting</h2>
            <img src="images/shader_vectors.gif">
          </section>

          <section>
            <h2>The Dot Product</h2>
            <img class="white_bg" src="http://upload.wikimedia.org/wikipedia/commons/thumb/3/3e/Dot_Product.svg/300px-Dot_Product.svg.png">
          </section>

          <section>
            <h2>Lighting</h2>
            <img style="width: 70%" src="images/reflection_vector.gif">
          </section>

          <section>
            <h2>Per Pixel Lighting</h2>
            <canvas data-sample="normal_mapped_plane"></canvas>
          </section>
        </section>

        <section>
          <section>
            <h2>Graphic Pipelines: How it started</h2>
            <h3>Software Rendering</h3>
            <img style="width: 480px;" src="http://1.bp.blogspot.com/-tQMjfiveb88/T5HvOfXc63I/AAAAAAAAB38/P_Nmtyw7-v8/s1600/prince-of-persia.gif">
            <ul>
              <li>Entirely done on CPU</li>
              <li>Unaided by graphics hardware</li>
              <li>Ultimate flexibility</li>
            </ul>
          </section>

          <section>
            <h3>How it was: Fixed Function Pipeline</h3>
            <img src="http://www.many-core.group.cam.ac.uk/platforms/pipeline_big.png">
            <ul>
              <li>Introduction of GPU hardware support</li>
              <li>Sacrificed flexibility for speed</li>
            </ul>
          </section>

          <section>
            <h3>How it was: Fixed Function Pipeline</h3>
            <img src="http://cdn.steampowered.com/v/gfx/apps/2310/0000002448.600x338.jpg?t=1343157013">
            <img src="http://www.techspot.com/reviews/hardware/voodoo3-3000/box_p.jpg">
            <small style="font-size: 10px; display: block;">I couldn't find an image of a voodoo 1 card</small>
          </section>

          <section>
            <h2>The Graphics Card</h2>
            <img class="white_bg" src="http://www.sjbaker.org/wiki/images/thumb/3/31/Graphics_pipeline.png/800px-Graphics_pipeline.png">
          </section>

          <section>
            <h3>How it is: Programmable Graphics Pipeline</h3>
            <!-- <img src="http://chrisingradschool.files.wordpress.com/2010/03/screen-shot-2010-03-09-at-2-13-26-pm.png?w=600&h=279"> -->
            <img src="http://www.many-core.group.cam.ac.uk/platforms/pipeline_big.png">
          </section>

          <section>
            <h3>How it is: Programmable Graphics Pipeline</h3>
            <img src="http://chrisingradschool.files.wordpress.com/2010/03/screen-shot-2010-03-09-at-2-13-26-pm.png?w=600&h=279">
          </section>

          <section>
            <h3>How it is: Programmable Graphics Pipeline</h3>
            <img src="http://4.bp.blogspot.com/-2YJsDFkdVqM/Tx_J4bw8HnI/AAAAAAAAATk/Y1RN1finStI/s1600/Call-of-Duty-Modern-Warfare-3-Gameplay-Reveal-Trailer_3.jpg">
            <p>Best of both worlds (almost)</p>
          </section>
        </section>

        <section>
          <section>
            <h1>What is WebGL?</h1>
            <p>OpenGL ES2.0 port built into the &lt;canvas&gt; DOM element</p>
            <canvas data-sample="webgl_spinning_colored_cube" style="display:inline"></canvas>
          </section>

          <section>
          <h3>wtf</h3>
            <pre class="supersmall float_left" style="width:50%"><code>
function init(scene) {
  // Initialize
  var gl = WebGLUtils.setupWebGL(scene.canvas);
  if (!gl) {
    return;
  }

  scene.program = simpleSetup(
    gl,
    // The ids of the vertex and fragment shaders
    "vshader", "fshader",
    // The vertex attribute names used by the shaders.
    // The order they appear here corresponds to their index
    // used later.
    [ "vNormal", "vColor", "vPosition"],
    // The clear color and depth values
    [ 0, 0, 0, 0 ], 10000);

  // Set up a uniform variable for the shaders
  gl.uniform3f(gl.getUniformLocation(scene.program, "lightDir"), 0, 0, 1);

  // Create a box. On return 'gl' contains a 'box' property with
  // the BufferObjects containing the arrays for vertices,
  // normals, texture coords, and indices.
  scene.box = makeBox(gl);

  // Set up the array of colors for the cube's faces
  var colors = new Uint8Array(
    [  0, 0, 1, 1,   0, 0, 1, 1,   0, 0, 1, 1,   0, 0, 1, 1,     // v0-v1-v2-v3 front
      1, 0, 0, 1,   1, 0, 0, 1,   1, 0, 0, 1,   1, 0, 0, 1,     // v0-v3-v4-v5 right
      0, 1, 0, 1,   0, 1, 0, 1,   0, 1, 0, 1,   0, 1, 0, 1,     // v0-v5-v6-v1 top
      1, 1, 0, 1,   1, 1, 0, 1,   1, 1, 0, 1,   1, 1, 0, 1,     // v1-v6-v7-v2 left
      1, 0, 1, 1,   1, 0, 1, 1,   1, 0, 1, 1,   1, 0, 1, 1,     // v7-v4-v3-v2 bottom
      0, 1, 1, 1,   0, 1, 1, 1,   0, 1, 1, 1,   0, 1, 1, 1 ]    // v4-v7-v6-v5 back
  );

  // Set up the vertex buffer for the colors
  scene.box.colorObject = gl.createBuffer();
  gl.bindBuffer(gl.ARRAY_BUFFER, scene.box.colorObject);
  gl.bufferData(gl.ARRAY_BUFFER, colors, gl.STATIC_DRAW);

  // Create some matrices to use later and save their locations in the shaders
  scene.mvMatrix = new J3DIMatrix4();
  scene.u_normalMatrixLoc = gl.getUniformLocation(scene.program, "u_normalMatrix");
  scene.normalMatrix = new J3DIMatrix4();
  scene.u_modelViewProjMatrixLoc =
    gl.getUniformLocation(scene.program, "u_modelViewProjMatrix");
  scene.mvpMatrix = new J3DIMatrix4();

  // Enable all of the vertex attribute arrays.
  gl.enableVertexAttribArray(0);
  gl.enableVertexAttribArray(1);
  gl.enableVertexAttribArray(2);

  // Set up all the vertex attributes for vertices, normals and colors
  gl.bindBuffer(gl.ARRAY_BUFFER, scene.box.vertexObject);
  gl.vertexAttribPointer(2, 3, gl.FLOAT, false, 0, 0);

  gl.bindBuffer(gl.ARRAY_BUFFER, scene.box.normalObject);
  gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0);

  gl.bindBuffer(gl.ARRAY_BUFFER, scene.box.colorObject);
  gl.vertexAttribPointer(1, 4, gl.UNSIGNED_BYTE, false, 0, 0);

  // Bind the index array
  gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, scene.box.indexObject);

  return gl;
}
            </code></pre>
            <pre class="supersmall float_left" style="width:50%"><code>
function reshape(scene, gl) {
  var canvas = scene.canvas;

  // Set the viewport and projection matrix for the scene
  gl.viewport(0, 0, canvas.width, canvas.height);
  scene.perspectiveMatrix = new J3DIMatrix4();
  scene.perspectiveMatrix.perspective(30, canvas.width/canvas.height, 1, 10000);
  scene.perspectiveMatrix.lookat(0, 0, 7, 0, 0, 0, 0, 1, 0);
}

function drawPicture(scene, gl) {
  // Make sure the canvas is sized correctly.
  reshape(scene, gl);

  // Clear the canvas
  gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);

  // Make a model/view matrix.
  scene.mvMatrix.makeIdentity();
  scene.mvMatrix.rotate(20, 1,0,0);
  scene.mvMatrix.rotate(scene.currentAngle, 0,1,0);

  // Construct the normal matrix from the model-view matrix and pass it in
  scene.normalMatrix.load(scene.mvMatrix);
  scene.normalMatrix.invert();
  scene.normalMatrix.transpose();
  scene.normalMatrix.setUniform(gl, scene.u_normalMatrixLoc, false);

  // Construct the model-view * projection matrix and pass it in
  scene.mvpMatrix.load(scene.perspectiveMatrix);
  scene.mvpMatrix.multiply(scene.mvMatrix);
  scene.mvpMatrix.setUniform(gl, scene.u_modelViewProjMatrixLoc, false);

  // Draw the cube
  gl.drawElements(gl.TRIANGLES, scene.box.numIndices, gl.UNSIGNED_BYTE, 0);

  scene.currentAngle += scene.incAngle;
  if (scene.currentAngle > 360)
    scene.currentAngle -= 360;
}

window.samples.webgl_spinning_cube = {

  initialize: function(canvas) {
    var scene = { canvas: canvas };

    canvas.addEventListener('webglcontextlost', handleContextLost, false);
    canvas.addEventListener('webglcontextrestored', handleContextRestored, false);

    canvas.width = sample_defaults.width;
    canvas.height = sample_defaults.height;

    var gl = init(scene);
    if (!gl) {
      return;
    }

    scene.currentAngle = 0;
    scene.incAngle = 0.5;

    var requestId;
    function animate() {
      drawPicture(scene, gl);
      requestId = window.requestAnimFrame(animate, canvas);
    }

    animate();

    function handleContextLost(e) {
      e.preventDefault();
      if (requestId !== undefined) {
        window.cancelAnimFrame(requestId);
        requestId = undefined;
      }
    }

    function handleContextRestored() {
      init(scene);
      animate();
    }
  }
            </code></pre>
          </section>

          <section>
            <h2>What we care about</h2>
            <pre class="code"><code class="javascript">
function drawPicture(scene, gl) {
  // Clear the canvas
  gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);

  // Set the viewport and projection matrix for the scene
  gl.viewport(0, 0, canvas.width, canvas.height);
  scene.perspectiveMatrix = new J3DIMatrix4();
  scene.perspectiveMatrix.perspective(30, canvas.width/canvas.height, 1, 10000);
  scene.perspectiveMatrix.lookat(0, 0, 7, 0, 0, 0, 0, 1, 0);

  // Make a model/view matrix.
  scene.mvMatrix.makeIdentity();
  scene.mvMatrix.rotate(20, 1,0,0);
  scene.mvMatrix.rotate(scene.currentAngle, 0,1,0);

  // Construct the model-view * projection matrix and pass it in
  scene.mvpMatrix.load(scene.perspectiveMatrix);
  scene.mvpMatrix.multiply(scene.mvMatrix);

  // Pass it in to the Vertex Shader
  scene.mvpMatrix.setUniform(gl, scene.u_modelViewProjMatrixLoc, false);

  // Draw the cube
  gl.drawElements(gl.TRIANGLES, scene.box.numIndices, gl.UNSIGNED_BYTE, 0);
}
            </code></pre>
          </section>

          <section>
            <h2>Vertex Shader</h2>
            <pre style="font-size:18px; line-height: 24px;" class="code"><code class="javascript">
    uniform mat4 u_modelViewProjMatrix; // Passed in from CPU

    attribute vec4 vPosition; // Information from vertex

    void main()
    {
        gl_Position = u_modelViewProjMatrix * vPosition;
    }
            </code></pre>
            <img class="float_left" style="width: 30%"
            src="https://upload.wikimedia.org/wikipedia/commons/thumb/b/bc/Rasterisation-triangle_example.svg/450px-Rasterisation-triangle_example.svg.png">
            <canvas data-sample="webgl_spinning_wireframe_cube" style="display:inline"></canvas>
          </section>

          <section>
            <h3>Fragment Shader</h3>
            <p>Per Vertex Lighting. Not per pixel lighting.</p>
            <pre style="font-size:18px; line-height: 24px;" class="code"><code class="javascript">
    void main()
    {
        gl_FragColor = vec4(1, 1, 1, 1); // RGBA
    }
            </code></pre>
            <img class="float_left" style="width: 30%"
            src="https://upload.wikimedia.org/wikipedia/commons/thumb/b/bc/Rasterisation-triangle_example.svg/450px-Rasterisation-triangle_example.svg.png">
            <canvas data-sample="webgl_spinning_bland_cube" style="display:inline"></canvas>
          </section>

          <section>
            <h2>Single Instruction, Multiple Data (SIMD)</h2>
            <br/>
            <br/>
            <p>GPUs are often wide SIMD implementations, capable of branches, loads, and stores on 128 or 256 bits at a time.</p>
          </section>

          <section>
            <h2>Vertex Shader</h2>
            <pre style="font-size:18px; line-height: 24px;" class="code"><code class="cpp">
    uniform mat4 u_modelViewProjMatrix; // Passed in from CPU
    uniform mat4 u_normalMatrix;
    uniform vec3 lightDir;

    attribute vec3 vNormal; // Received from Vertex
    attribute vec4 vColor;
    attribute vec4 vPosition;

    varying float v_Dot; // Variables passed to Fragment Shader
    varying vec4 v_Color;

    void main()
    {
        gl_Position = u_modelViewProjMatrix * vPosition;
        v_Color = vColor;
        vec4 transNormal = u_normalMatrix * vec4(vNormal, 1);
        v_Dot = max(dot(transNormal.xyz, lightDir), 0.0);
    }
            </code></pre>
          </section>

          <section>
            <h3>Fragment Shader</h3>
            <p>Per Vertex Lighting. Not per pixel lighting.</p>
            <pre style="font-size:18px; line-height: 24px;" class="code"><code class="cpp">
    precision mediump float;

    varying float v_Dot; // Passed in from Vertex Shader
    varying vec4 v_Color;

    void main()
    {
        gl_FragColor = vec4(v_Color.xyz * v_Dot, v_Color.a);
    }
            </code></pre>
            <canvas data-sample="webgl_spinning_colored_cube" style="display:inline"></canvas>
          </section>

        </section>

        <section>
          <section>
            <h1>What is ThreeJS?</h1>
            <blockquote class="medium" style="margin-top: 80px; width: 100%">
              The aim of the project is to create a lightweight 3D library with a very low level of complexity — in other words, for dummies.
              <br/>
              The library provides &lt;canvas&gt;, &lt;svg&gt; and WebGL renderers.
            </blockquote>
            <canvas data-sample="spinning_cube"></canvas>
          </section>

          <section>
            <h3>Intro to ThreeJS: Spinning Cube</h3>
            <pre class="code"><code>
function init(canvas) {
  var scene = new THREE.Scene();

  var camera = new THREE.PerspectiveCamera( 75, 320/240, 1, 1000 );
  camera.position.z = 100;

  var geometry = new THREE.CubeGeometry( 70, 70, 70 );
  var material = new THREE.MeshBasicMaterial( { color: 0xdddddd } );

  var mesh = new THREE.Mesh( geometry, material );
  scene.add( mesh );

  var renderer = new THREE.WebGLRenderer({canvas: canvas});
  renderer.setSize( 320, 240 );

  function animate() {
    // note: three.js includes requestAnimationFrame shim
    requestAnimationFrame( animate );

    mesh.rotation.x += 0.01;
    mesh.rotation.y += 0.02;
    renderer.render( scene, camera );
  }
  animate();
}
            </code></pre>
            <p class="supersmall">16 lines of code</p>
          </section>

          <section>
            <h3>Scene</h3>
            <pre class="medium"><code>
function init(canvas) {
  var scene = new THREE.Scene();
            </code></pre>
            <br/>
            <p>Encapsulates everything with regard to this rendering!</p>
            <ul>
              <li>All global matrices</li>
              <li>Models</li>
              <li>Camera</li>
            </ul>
          </section>

          <section>
            <h3>Camera</h3>
            <pre class="medium"><code>
var camera = new THREE.PerspectiveCamera(75, 320/240, 1, 1000);
camera.position.z = 100;
            </code></pre>
            <div style="width:120%">
              <img style="height: 50%" class="float_left" src="http://robertokoci.com/images/posts/graphics/game/programming/matrix-unveiled/WorldViewSpace.png">
              <img style="height: 50%" src="http://robertokoci.com/images/posts/graphics/game/programming/matrix-unveiled/ProjectionMatrix.png">
            </div>
          </section>

          <section>
            <h3>Geometry</h3>
            <pre class="medium"><code>
  var geometry = new THREE.CubeGeometry( 70, 70, 70 );
            </code></pre>
            <img class="white_bg" src="http://obviam.net/wp-content/uploads/2011/01/Vertices.png">
          </section>

          <section>
            <h3>Materials</h3>
            <pre class="medium"><code>
var material = new THREE.MeshLambertMaterial({ color: 0xdddddd });
            </code></pre>
            <p>Actually an OpenGL concept. Encapsulates:</p>
            <ul>
              <li>Texture</li>
              <li>Lighting</li>
              <li>Fragment Shader</li>
            </p>
          </section>

          <section>
            <h3>Mesh</h3>
            <pre class="medium"><code>
  var mesh = new THREE.Mesh( geometry, material );
  scene.add( mesh );
            </code></pre>
            <br/>
            <p>Associate geometry with a material to make a mesh.</p>
            <p>Also creates a world matrix for the mesh, defaulting it to the identity</p>
          </section>

          <section>
            <h3>Renderer</h3>
            <pre class="medium"><code>
  var renderer = new THREE.WebGLRenderer({canvas: canvas});
  renderer.setSize( 320, 240 );
            </code></pre>
            <br/>
            <p>The moment you add lighting, the WebGLRenderer's performance tanks.</p>
          </section>

          <section>
            <h3>requestAnimationFrame?</h3>
            <p>Welcome to the Render Loop</p>
            <pre class="medium"><code>
  function animate() {
    // note: three.js includes requestAnimationFrame shim
    requestAnimationFrame( animate );

    mesh.rotation.x += 0.01;
    mesh.rotation.y += 0.02;
    renderer.render( scene, camera );
  }
  animate();
            </code></pre>
          </section>

          <section data-state="boom">
            <h1>BOOM!</h1>
            <canvas data-sample="spinning_cube"></canvas>
          </section>
        </section>

        <section>
          <section>
            <h2>ThreeJS: Loading Meshes</h2>
            <canvas data-sample="load_startrek_enterprise"></canvas>
          </section>

          <section>
            <h2>Blender and ThreeJS</h2>
            <br/>
            <ul>
              <li>Leverage CAD design tools to create models</li>
              <li>Grab models from <a href="http://www.blendswap.com/blends/vehicles/star-trek-collection/">Blendswap: Startrek Collection</a></li>
              <li>Can export to the Three js file format</li>
              <li><a href="js/meshes/Startrek_Enterprise.js">Startrek Enterprise Mesh</a></li>
              <li><p>Credit for model goes to <a href="http://www.blendswap.com/?author=3134"><NAME></a></p></li>
            </ul>
          </section>

          <section>
            <h2>ThreeJS: Importing Mesh</h2>
            <br/>
            <pre class="medium"><code>
// REMOVED
// var geometry = new THREE.CubeGeometry( 70, 70, 70 );
// var material = new THREE.MeshLambertMaterial({color: 0xdddddd});

var loader = new THREE.JSONLoader();
loader.load("js/meshes/Startrek_Enterprise.js", function(geometry) {

  mesh = new THREE.Mesh( geometry, geometry.materials[0] );
  scene.add( mesh );
  ...
            </code></pre>
          </section>

          <section data-state="loaded_apache">
            <h2>with Textures</h2>
            <a href="images/FinalApacheTexture.png">Apache Texture File</a>
            <canvas data-sample="load_apache"></canvas>
          </section>
        </section>

        <section>
          <section>
            <h2>ThreeJS: Particles</h2>
            <canvas data-sample="particles"></canvas>
          </section>

          <section>
            <h2>ThreeJS: Particles</h2>
            <img style="width:850px;" src="http://3dgep.com/wp-content/uploads/2011/02/OpenGL-Primitives.png">
          </section>

          <section>
            <h2>ThreeJS: Particles</h2>
            <pre class="code medium"><code class="cpp">
    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 );
    }
    ...
            </code></pre>
            <br/>
            <pre class="code medium"><code class="cpp">
    particles = new THREE.ParticleSystem( geometry, materials[i] );

    scene.add( particles );
            </code></pre>
          </section>

          <section>
            <h2>Rendering a Million: Batch your draw calls</h2>
            <ul>
              <li><a href="http://www.html5rocks.com/en/tutorials/webgl/million_letters/million_letters.html">A Million Letters</a></li>
            </ul>
          </section>

          <section>
            <h2>How do we animate a million particles?</h2>
            <img class="white_bg" src="http://www.sjbaker.org/wiki/images/thumb/3/31/Graphics_pipeline.png/800px-Graphics_pipeline.png">
          </section>

          <section>
            <h3>ThreeJS: Vertex Textures</h3>
            <p>Using the RGB for your XYZ</p>
            <img class="float_left" src="http://upload.wikimedia.org/wikipedia/commons/5/57/Heightmap.png">
            <img class="float_left" src="http://upload.wikimedia.org/wikipedia/commons/2/2f/Heightmap_rendered.png">
          </section>

          <section>
            <h3>Showcase: A Million Particles</h3>
            <ul>
              <li><a href="http://mrdoob.com/lab/javascript/webgl/particles/magicdust.html">Magic Dust Particles</a></li>
            </ul>
          </section>
        </section>

        <section>
          <section>
            <h2>Fragment Shaders: Normal Mapping</h2>
            <p>Using the RGB for your <b><u>normal's</u></b> XYZ</p>
            <canvas data-sample="normal_mapped_plane" class="float_left" style="display:inline"></canvas>
            <canvas data-sample="wireframe_plane" class="float_left" style="display:inline"></canvas>
            <img src="images/normal_map_tile.jpg" class="float_left normal_map" style="width:200px">
          </section>

          <section>
            <h2>Normal Mapping: Per Pixel Lighting</h2>
            <img class="float_left" style="width: 25%"
            src="https://upload.wikimedia.org/wikipedia/commons/thumb/b/bc/Rasterisation-triangle_example.svg/450px-Rasterisation-triangle_example.svg.png">
            <img style="width: 70%" src="images/reflection_vector.gif">
          </section>

          <section>
            <h2>Normal Map</h2>
            <img src="images/normal_map_tile.jpg">
          </section>

          <section>
            <h2>Normal Map</h2>
            <canvas data-sample="normal_mapped_plane" class="float_left" style="display:inline"></canvas>
            <canvas data-sample="wireframe_plane" class="float_left" style="display:inline"></canvas>
            <img src="images/normal_map_tile.jpg" class="float_left normal_map" style="width:200px">
          </section>

          <section>
            <img src="http://img.photobucket.com/albums/v348/spartan_mortis/chiefnoshader.jpg">
          </section>

          <section>
            <h2>ThreeJS: Custom Shaders</h2>
              <pre class="code medium"><code class="javascript">
  var vertexShader = $('#normal_map_vs').text(); // Where's this shader?
  var fragmentShader = $('#normal_map_fs').text();

  var parameters = {
    fragmentShader: fragmentShader,
    vertexShader: vertexShader,
    uniforms: uniforms,
    attributes: attributes,
    side: THREE.DoubleSide
  };

  var normal_material = new THREE.ShaderMaterial( parameters );
  var mesh = new THREE.Mesh( geometry, normal_material );
  scene.add( mesh );
              </code></pre>
          </section>

          <section>
            <h2>Showcase: Skin Material</h2>
            <a href="http://mrdoob.github.com/three.js/examples/webgl_materials_bumpmap_skin.html">WebGL Skin Material</a>
          </section>
        </section>

        <section>
          <section>
            <h2>Post-Processing: Blur</h2>
            <canvas class="float_left" data-sample="spinning_textured_cube"></canvas>
{'fraction_non_alphanumeric': 0.14364095403320215, 'fraction_numerical': 0.027094881451078294, 'mean_word_length': 2.1766656212195885, 'pattern_counts': {'":': 0, '<': 1539, '<?xml version=': 0, '>': 1541, 'https://': 14, 'lorem ipsum': 0, 'www.': 27, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 6, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4383411', 'n_tokens_mistral': 23923, 'n_tokens_neox': 22188, 'n_words': 4519}