KEMBAR78
Introduction to WebGL and Three.js
Introduction to WebGL and Three.js

James Williams

James.L.Williams@gmail.com - Rearden Commerce
About Me
• Author of Learning HTML5
  Game Programming
• Google+: +JamesWilliams
• Twitter: @ecspike
• http://jameswilliams.be/blog


                                                         James Williams   2
                         James.L.Williams@gmail.com – Rearden Commerce
Agenda - WebGL
•   What are WebGL and Three.js?
•   Lighting, Shaders, and Materials
•   Creating Meshes
•   GLSL
•   Animation
•   Debugging
                                                           James Williams   3
                           James.L.Williams@gmail.com – Rearden Commerce
What is WebGL?
•   Low-level 3D graphics context
•   Hardware accelerated
•   Supported by most modern browsers
•   Syntax is based on OpenGL ES 2.0



                                                         James Williams   4
                         James.L.Williams@gmail.com – Rearden Commerce
Getting a WebGLContext
• Hook to draw on the canvas
 var canvas = document.getElementById(“c”);
 var ctx = c.getContext(“experimental-webgl”);




                                                          James Williams   5
                          James.L.Williams@gmail.com – Rearden Commerce
What is Three.js?
• Abstraction layer over WebGL
• 3D scenegraph library
• Capable of rendering to
  – Canvas2D, WebGL, or SVG
• Exporters for popular 3D formats
• http://github.com/mrdoob/three.js

                                                         James Williams   6
                         James.L.Williams@gmail.com – Rearden Commerce
Initializing Three.js
function init() {
    var HEIGHT = 480, WIDTH = 640;
    // create a renderer, camera, and scene
     renderer = new THREE.WebGLRenderer();
     renderer.setSize (WIDTH, HEIGHT);
     camera = /* truncated */
     // create scene
     scene = new THREE.Scene();
     // add objects to scene
    elem.appendChild(render.domElement);
}
                                                                  James Williams   7
                                  James.L.Williams@gmail.com – Rearden Commerce
Camera
•   Eye point
•   Field of vision
•   Near / Far planes
•   Target(LookAt) point
•   Up vector
•   Advanced Camera types
                                                        James Williams   8
                        James.L.Williams@gmail.com – Rearden Commerce
Creating Meshes
• Geometry vs Mesh
• Built-in geometries
• Vertex
 new THREE.Vertex(
    new Three.Vector3(0.0, 1.0, 0.0)
 );
• Face
 new THREE.Face3(0,1,2);

                                                           James Williams   9
                           James.L.Williams@gmail.com – Rearden Commerce
Creating Meshes
geometry = new THREE.Geometry();
geometry.vertices.push(vertex1);
geometry.vertices.push(vertex2);
geometry.vertices.push(vertex3);
geometry.faces.push(face1);
var triangle = new THREE.Mesh(geometry,
     new THREE.MeshBasicMaterial( {
      color: 0x00ff00 }
   )
);


                                                               James Williams   10
                               James.L.Williams@gmail.com – Rearden Commerce
Creating Meshes
plane = new THREE.Mesh(
   new THREE.PlaneGeometry( 200, 200 ),
   new THREE.MeshBasicMaterial( { color:
     0xe0e0e0 }
   )
);
scene.add( plane );
scene.add(triangle);




                                                               James Williams   11
                               James.L.Williams@gmail.com – Rearden Commerce
Demo




                                  James Williams   12
  James.L.Williams@gmail.com – Rearden Commerce
Lighting
•   Ambient
•   Point
•   Directional
•   SpotLight
    new THREE.AmbientLight(hexColor);
    new THREE.PointLight(hexColor, [intensity], [distance]);




                                                                   James Williams   13
                                   James.L.Williams@gmail.com – Rearden Commerce
Shading
•   Flat
•   Lambertian
•   Gouraud
•   Phong



                                                     James Williams   14
                     James.L.Williams@gmail.com – Rearden Commerce
Materials
•   MeshBasicMaterial
•   MeshLambertMaterial
•   MeshPhongMaterial
•   MeshShaderMaterial



                                                          James Williams   15
                          James.L.Williams@gmail.com – Rearden Commerce
Demo




                                  James Williams   16
  James.L.Williams@gmail.com – Rearden Commerce
Texturing
• Can load from images or use canvas data
• Basic shapes precalculate texture coordinates




                                                         James Williams   17
                         James.L.Williams@gmail.com – Rearden Commerce
2D Texture Coordinates
(0,0)                                                      (1,1)




(0,1)                                                      (1,0)
                                                   James Williams   18
                   James.L.Williams@gmail.com – Rearden Commerce
Texturing Example
var texture = THREE.ImageUtils.loadTexture(
   "200407-bluemarble.jpg" );
var material = new THREE.MeshBasicMaterial(
   { color: 0xFFFFFF,
     ambient: 0xFFFFFF, map:texture } );


sphere = new THREE.Mesh(
   new THREE.SphereGeometry(32, 32, 32), material
);


scene.add(sphere);
                                                               James Williams   19
                               James.L.Williams@gmail.com – Rearden Commerce
Demo




                                  James Williams   20
  James.L.Williams@gmail.com – Rearden Commerce
Loading Models
function drawCube() {
    var loader = new THREE.JSONLoader();
    loader.load( {model: "cube.js", callback: createScene1 });
}


function createScene1(obj) {
    obj.materials[0][0].shading = THREE.FlatShading;
    mesh = THREE.SceneUtils.addMesh( scene, obj, 250, 400, 0,
0, 0, 0, 0,obj.materials[0] );
}


                                                               James Williams   21
                               James.L.Williams@gmail.com – Rearden Commerce
Demo




                                  James Williams   22
  James.L.Williams@gmail.com – Rearden Commerce
What is GLSL?
• High-level language with C-like syntax
• Targets the GPU and graphics pipeline
• A GLSL program consists of
  – fragment shader
  – vertex shader
• Content of shaders passed around as strings
• Shaders can be generated at run-time
                                                         James Williams   23
                         James.L.Williams@gmail.com – Rearden Commerce
Vertex Shaders
• Run once per vertex in a mesh
• Can alter color, position, texels, etc at that
  vertex




                                                            James Williams   24
                            James.L.Williams@gmail.com – Rearden Commerce
Example Vertex Shader
<script id="shader-vs" type="x-shader/x-vertex">
    void main(void) {
       gl_Position = projectionMatrix *
       modelViewMatrix *
         vec4(position, 1.0);
    }
</script>




                                                               James Williams   25
                               James.L.Williams@gmail.com – Rearden Commerce
Fragment(Pixel) Shaders
• Run once per pixel in a mesh
• Can produce effects such as bump and env
  mapping




                                                       James Williams   26
                       James.L.Williams@gmail.com – Rearden Commerce
Example Fragment(Pixel) Shader
<script id="shader-vs" type="x-shader/x-fragment">
    void main(void) {
       gl_FragColor = vec4(
       0.0, 1.0, 0.0, 1.0
      );
    }
</script>




                                                               James Williams   27
                               James.L.Williams@gmail.com – Rearden Commerce
Shader Demo Code
 shaderMaterial = new
     THREE.MeshShaderMaterial({
     vertexShader: $('#v').get(0).innerHTML,
     fragmentShader:$('#f').get(0).innerHTML,
     vertexColors: true
 });
/* truncated */
var triangle = new THREE.Mesh(
   geometry, shaderMaterial
);



                                                                James Williams   28
                                James.L.Williams@gmail.com – Rearden Commerce
Shader Variables
•   uniform
•   varying
•   attribute
•   Types



                                                        James Williams   29
                        James.L.Williams@gmail.com – Rearden Commerce
Constructing New Shader Types
struct MyMaterial {
    vec4 ambient;
    vec4 diffuse;
     vec4 specular;
     float shininess;
};




                                                        James Williams   30
                        James.L.Williams@gmail.com – Rearden Commerce
Communicating with Shaders
var uniforms;
uniforms = {
    time: {type:"f", value:0.0}
}
shaderMaterial = new THREE.MeshShaderMaterial({
      uniforms: uniforms,
      vertexShader:$('#v').get(0).innerHTML,
      fragmentShader:$('#f').get(0).innerHTML,
});



                                                                  James Williams   31
                                  James.L.Williams@gmail.com – Rearden Commerce
Custom Shader
uniform float time;


void main(){
    float r = cos(time);
    float g = sin(time);
    float b = tan(time);


    gl_FragColor = vec4(r, 1.0 - g , b, 1.0);
}



                                                                 James Williams   32
                                 James.L.Williams@gmail.com – Rearden Commerce
Vertex Shader for 2D texturing
/* Vertex Shader */
attribute vec4 a_position;
attribute vec2 a_texCoord;
varying vec2 v_texCoord;


void main() {
    gl_Position = a_position;
    v_texCoord = a_texCoord;
}



                                                                James Williams   33
                                James.L.Williams@gmail.com – Rearden Commerce
Fragment Shader for 2D texturing
/* Fragment Shader */
precision mediump float;
varying vec2 v_texCoord;
uniform sampler2D s_texture;


void main() {
    gl_FragColor = texture2D(s_texture, v_texCoord);
}




                                                               James Williams   34
                               James.L.Williams@gmail.com – Rearden Commerce
Animation
  Armature - 3D representation of bones, ligaments, and
  tendons
• Forward kinematics
• Inverse kinematics
• Keyframes/Morph targets




                                                             James Williams   35
                             James.L.Williams@gmail.com – Rearden Commerce
MorphTargets
var time = new Date().getTime() % duration;
var keyframe = Math.floor(time / interpol )
  + offset;
if ( keyframe != currentKeyframe ) {
    mesh.morphTargetInfluences[lastFrame]=0;
    mesh.morphTargetInfluences[currentFrame]
      =1;
    mesh.morphTargetInfluences[keyframe]=0;
    lastFrame = currentFrame;
    currentFrame = keyframe;
}

                                                                 James Williams   36
                                 James.L.Williams@gmail.com – Rearden Commerce
MorphTargets
mesh.morphTargetInfluences[ keyframe ]
 = ( time % interpol ) / interpolation;

mesh.morphTargetInfluences[ lastFrame ]
= 1 - mesh.morphTargetInfluences[keyframe];




                                                               James Williams   37
                               James.L.Williams@gmail.com – Rearden Commerce
Demo




                                  James Williams   38
  James.L.Williams@gmail.com – Rearden Commerce
Debugging WebGL




                                       James Williams   39
       James.L.Williams@gmail.com – Rearden Commerce
Stats.js
• Measures:
   – FPS - frames per second
   – MS - millis to render frame
   – MB - allocated MB
• Github:https://github.com/mrdoob/stats.js


                                                                   James Williams   40
                                   James.L.Williams@gmail.com – Rearden Commerce
Stats.js code
   var stats = new Stats()
$("body").append(stats.domElement);

//... in your render function
stats.update();




                                                                 James Williams   41
                                 James.L.Williams@gmail.com – Rearden Commerce
WebGL Inspector
•   Allows you to step through rendering
•   View assets and programs
•   Capture individual frames
•   Github: http://benvanik.github.com/WebGL-Inspector



                                                                James Williams   42
                                James.L.Williams@gmail.com – Rearden Commerce
Questions?




                                     James Williams   43
     James.L.Williams@gmail.com – Rearden Commerce

Introduction to WebGL and Three.js

  • 1.
    Introduction to WebGLand Three.js James Williams James.L.Williams@gmail.com - Rearden Commerce
  • 2.
    About Me • Authorof Learning HTML5 Game Programming • Google+: +JamesWilliams • Twitter: @ecspike • http://jameswilliams.be/blog James Williams 2 James.L.Williams@gmail.com – Rearden Commerce
  • 3.
    Agenda - WebGL • What are WebGL and Three.js? • Lighting, Shaders, and Materials • Creating Meshes • GLSL • Animation • Debugging James Williams 3 James.L.Williams@gmail.com – Rearden Commerce
  • 4.
    What is WebGL? • Low-level 3D graphics context • Hardware accelerated • Supported by most modern browsers • Syntax is based on OpenGL ES 2.0 James Williams 4 James.L.Williams@gmail.com – Rearden Commerce
  • 5.
    Getting a WebGLContext •Hook to draw on the canvas var canvas = document.getElementById(“c”); var ctx = c.getContext(“experimental-webgl”); James Williams 5 James.L.Williams@gmail.com – Rearden Commerce
  • 6.
    What is Three.js? •Abstraction layer over WebGL • 3D scenegraph library • Capable of rendering to – Canvas2D, WebGL, or SVG • Exporters for popular 3D formats • http://github.com/mrdoob/three.js James Williams 6 James.L.Williams@gmail.com – Rearden Commerce
  • 7.
    Initializing Three.js function init(){ var HEIGHT = 480, WIDTH = 640; // create a renderer, camera, and scene renderer = new THREE.WebGLRenderer(); renderer.setSize (WIDTH, HEIGHT); camera = /* truncated */ // create scene scene = new THREE.Scene(); // add objects to scene elem.appendChild(render.domElement); } James Williams 7 James.L.Williams@gmail.com – Rearden Commerce
  • 8.
    Camera • Eye point • Field of vision • Near / Far planes • Target(LookAt) point • Up vector • Advanced Camera types James Williams 8 James.L.Williams@gmail.com – Rearden Commerce
  • 9.
    Creating Meshes • Geometryvs Mesh • Built-in geometries • Vertex new THREE.Vertex( new Three.Vector3(0.0, 1.0, 0.0) ); • Face new THREE.Face3(0,1,2); James Williams 9 James.L.Williams@gmail.com – Rearden Commerce
  • 10.
    Creating Meshes geometry =new THREE.Geometry(); geometry.vertices.push(vertex1); geometry.vertices.push(vertex2); geometry.vertices.push(vertex3); geometry.faces.push(face1); var triangle = new THREE.Mesh(geometry, new THREE.MeshBasicMaterial( { color: 0x00ff00 } ) ); James Williams 10 James.L.Williams@gmail.com – Rearden Commerce
  • 11.
    Creating Meshes plane =new THREE.Mesh( new THREE.PlaneGeometry( 200, 200 ), new THREE.MeshBasicMaterial( { color: 0xe0e0e0 } ) ); scene.add( plane ); scene.add(triangle); James Williams 11 James.L.Williams@gmail.com – Rearden Commerce
  • 12.
    Demo James Williams 12 James.L.Williams@gmail.com – Rearden Commerce
  • 13.
    Lighting • Ambient • Point • Directional • SpotLight new THREE.AmbientLight(hexColor); new THREE.PointLight(hexColor, [intensity], [distance]); James Williams 13 James.L.Williams@gmail.com – Rearden Commerce
  • 14.
    Shading • Flat • Lambertian • Gouraud • Phong James Williams 14 James.L.Williams@gmail.com – Rearden Commerce
  • 15.
    Materials • MeshBasicMaterial • MeshLambertMaterial • MeshPhongMaterial • MeshShaderMaterial James Williams 15 James.L.Williams@gmail.com – Rearden Commerce
  • 16.
    Demo James Williams 16 James.L.Williams@gmail.com – Rearden Commerce
  • 17.
    Texturing • Can loadfrom images or use canvas data • Basic shapes precalculate texture coordinates James Williams 17 James.L.Williams@gmail.com – Rearden Commerce
  • 18.
    2D Texture Coordinates (0,0) (1,1) (0,1) (1,0) James Williams 18 James.L.Williams@gmail.com – Rearden Commerce
  • 19.
    Texturing Example var texture= THREE.ImageUtils.loadTexture( "200407-bluemarble.jpg" ); var material = new THREE.MeshBasicMaterial( { color: 0xFFFFFF, ambient: 0xFFFFFF, map:texture } ); sphere = new THREE.Mesh( new THREE.SphereGeometry(32, 32, 32), material ); scene.add(sphere); James Williams 19 James.L.Williams@gmail.com – Rearden Commerce
  • 20.
    Demo James Williams 20 James.L.Williams@gmail.com – Rearden Commerce
  • 21.
    Loading Models function drawCube(){ var loader = new THREE.JSONLoader(); loader.load( {model: "cube.js", callback: createScene1 }); } function createScene1(obj) { obj.materials[0][0].shading = THREE.FlatShading; mesh = THREE.SceneUtils.addMesh( scene, obj, 250, 400, 0, 0, 0, 0, 0,obj.materials[0] ); } James Williams 21 James.L.Williams@gmail.com – Rearden Commerce
  • 22.
    Demo James Williams 22 James.L.Williams@gmail.com – Rearden Commerce
  • 23.
    What is GLSL? •High-level language with C-like syntax • Targets the GPU and graphics pipeline • A GLSL program consists of – fragment shader – vertex shader • Content of shaders passed around as strings • Shaders can be generated at run-time James Williams 23 James.L.Williams@gmail.com – Rearden Commerce
  • 24.
    Vertex Shaders • Runonce per vertex in a mesh • Can alter color, position, texels, etc at that vertex James Williams 24 James.L.Williams@gmail.com – Rearden Commerce
  • 25.
    Example Vertex Shader <scriptid="shader-vs" type="x-shader/x-vertex"> void main(void) { gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); } </script> James Williams 25 James.L.Williams@gmail.com – Rearden Commerce
  • 26.
    Fragment(Pixel) Shaders • Runonce per pixel in a mesh • Can produce effects such as bump and env mapping James Williams 26 James.L.Williams@gmail.com – Rearden Commerce
  • 27.
    Example Fragment(Pixel) Shader <scriptid="shader-vs" type="x-shader/x-fragment"> void main(void) { gl_FragColor = vec4( 0.0, 1.0, 0.0, 1.0 ); } </script> James Williams 27 James.L.Williams@gmail.com – Rearden Commerce
  • 28.
    Shader Demo Code shaderMaterial = new THREE.MeshShaderMaterial({ vertexShader: $('#v').get(0).innerHTML, fragmentShader:$('#f').get(0).innerHTML, vertexColors: true }); /* truncated */ var triangle = new THREE.Mesh( geometry, shaderMaterial ); James Williams 28 James.L.Williams@gmail.com – Rearden Commerce
  • 29.
    Shader Variables • uniform • varying • attribute • Types James Williams 29 James.L.Williams@gmail.com – Rearden Commerce
  • 30.
    Constructing New ShaderTypes struct MyMaterial { vec4 ambient; vec4 diffuse; vec4 specular; float shininess; }; James Williams 30 James.L.Williams@gmail.com – Rearden Commerce
  • 31.
    Communicating with Shaders varuniforms; uniforms = { time: {type:"f", value:0.0} } shaderMaterial = new THREE.MeshShaderMaterial({ uniforms: uniforms, vertexShader:$('#v').get(0).innerHTML, fragmentShader:$('#f').get(0).innerHTML, }); James Williams 31 James.L.Williams@gmail.com – Rearden Commerce
  • 32.
    Custom Shader uniform floattime; void main(){ float r = cos(time); float g = sin(time); float b = tan(time); gl_FragColor = vec4(r, 1.0 - g , b, 1.0); } James Williams 32 James.L.Williams@gmail.com – Rearden Commerce
  • 33.
    Vertex Shader for2D texturing /* Vertex Shader */ attribute vec4 a_position; attribute vec2 a_texCoord; varying vec2 v_texCoord; void main() { gl_Position = a_position; v_texCoord = a_texCoord; } James Williams 33 James.L.Williams@gmail.com – Rearden Commerce
  • 34.
    Fragment Shader for2D texturing /* Fragment Shader */ precision mediump float; varying vec2 v_texCoord; uniform sampler2D s_texture; void main() { gl_FragColor = texture2D(s_texture, v_texCoord); } James Williams 34 James.L.Williams@gmail.com – Rearden Commerce
  • 35.
    Animation Armature- 3D representation of bones, ligaments, and tendons • Forward kinematics • Inverse kinematics • Keyframes/Morph targets James Williams 35 James.L.Williams@gmail.com – Rearden Commerce
  • 36.
    MorphTargets var time =new Date().getTime() % duration; var keyframe = Math.floor(time / interpol ) + offset; if ( keyframe != currentKeyframe ) { mesh.morphTargetInfluences[lastFrame]=0; mesh.morphTargetInfluences[currentFrame] =1; mesh.morphTargetInfluences[keyframe]=0; lastFrame = currentFrame; currentFrame = keyframe; } James Williams 36 James.L.Williams@gmail.com – Rearden Commerce
  • 37.
    MorphTargets mesh.morphTargetInfluences[ keyframe ] = ( time % interpol ) / interpolation; mesh.morphTargetInfluences[ lastFrame ] = 1 - mesh.morphTargetInfluences[keyframe]; James Williams 37 James.L.Williams@gmail.com – Rearden Commerce
  • 38.
    Demo James Williams 38 James.L.Williams@gmail.com – Rearden Commerce
  • 39.
    Debugging WebGL James Williams 39 James.L.Williams@gmail.com – Rearden Commerce
  • 40.
    Stats.js • Measures: – FPS - frames per second – MS - millis to render frame – MB - allocated MB • Github:https://github.com/mrdoob/stats.js James Williams 40 James.L.Williams@gmail.com – Rearden Commerce
  • 41.
    Stats.js code var stats = new Stats() $("body").append(stats.domElement); //... in your render function stats.update(); James Williams 41 James.L.Williams@gmail.com – Rearden Commerce
  • 42.
    WebGL Inspector • Allows you to step through rendering • View assets and programs • Capture individual frames • Github: http://benvanik.github.com/WebGL-Inspector James Williams 42 James.L.Williams@gmail.com – Rearden Commerce
  • 43.
    Questions? James Williams 43 James.L.Williams@gmail.com – Rearden Commerce