Browser 3D Graphics with WebGL and Three.js

Mihail Sergeev

Chaos Group Ltd.

History of Browser 3D Graphics

  • VRML
  • X3D
  • Web3D

Virtual Reality Markup Language

  • Web3D Consortium standard
  • Version 1.0 defined in 1994
  • Version 2.0 defined in 1997
  • Poor adoption due to technological limitations
  • Still available as third-party browser addons: OpenVRML, Cortona3D, etc.

X3D

  • ISO Standard since 2004
  • VRML successor with vastly enriched feature set:
    • CAD, Geospatial, NURBS
    • Advanced shading, rendering and optimization techniques
    • DOM & XPath support
  • Multiple scene formats (XML, binary, OpenInventor)
  • Currently available as an HTML5/WebGL shim for X3DOM support

Web3D

  • Umbrella term for various technologies for displaying 3D content and Virtual Reality in the browser
  • Adobe Shockwave (plugin)
  • Java ecosystem: Java 3D, JavaFX, JOGL (plugin)
  • Unity (plugin/native)
  • Unreal Engine, asm.js (native)
  • Blender ecosystem: Burster, Blend4Web (plugin/native)
  • WebGL (native)

WebGL

  • Designed and maintained by Khronos Group
  • First standard released March 2011
  • Based on OpenGL ES 2.0
  • WebGL 2 in progress as we speak

WebGL (contd.)

  • GPU processing for the masses
  • Mix-n-match with other HTML elements
  • Exposed through HTML5 Canvas context
  • About 67% browser support (source: caniuse.com), including most of the mobile browsers
  • JavaScript control code + GLSL shaders
  • Usage-agnostic, complex API aimed at platform creators, see API reference card:
    http://www.khronos.org/files/webgl/webgl-reference-card-1_0.pdf
  • No built-in support for content formats

WebGL Rendering Pipeline

  • JavaScript code feeds geometry information and custom data buffers into the WebGL subsystem
  • GLSL shader programs execute on the GPU:
    • Vertex shader generates point screen coordinates for each geometry vertex and saves it in the gl_Position variable
    • Fragment shader generates a color for each of these points and saves it in the gl_FragColor variable
  • Variables (uniforms, attributes and varyings) store and transport data:
    • between JavaScript and shader programs
    • between vertex and fragment shaders
  • Frame buffers contain the final rendering result

WebGL Workflow

  1. Acquire & prepare rendering context:
    document.getElementById('canvas').getContext('webgl')
  2. Load shaders from <script> tags or external files
  3. Compile shaders:
    createShader, shaderSource, shaderCompile
  4. Setup shader program:
    createProgram, attachShader, linkProgram, useProgram
  5. Setup shader variables:
    getAttribLocation, enableVertexAttribArray, getUniformLocation
  6. Transfer vertex data (Vertex Buffer Objects):
    createBuffer, bindBuffer, bufferData/bufferSubData
  7. Setup textures:
    createTexture, bindTexture, texImage2D, texParameteri
  8. Draw!
    drawArrays, drawElements

Sample Shaders

attribute vec3 aVertexPosition;
attribute vec4 aVertexColor;

// model-view matrix
uniform mat4 uMVMatrix;
// projection matrix
uniform mat4 uPMatrix;

varying vec4 vColor;

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

Vertex Shader

Fragment Shader

varying vec4 vColor;

void main(void) {
    gl_FragColor = vColor;
}

Higher-level Frameworks

  • WebGL by itself is quite cumbersome and unstructured for usage in complex projects
  • It provides too little in terms of:
    • scene organization
    • transformations
    • 3D content support
    • advanced shading and effects
    • animation
    • physics
  • Frameworks to the rescue: Three.js, Babylon.js, etc.

Three.js

  • Open-source, started in 2009 as an ActionScript framework
  • Modular architecture, supports Canvas2D and SVG rendering modes alongside WebGL
     
  • Provides scene graph, object hierarchy and transformations and content loaders for multiple 3D file formats
  • Provides camera, projections and raycasting utilities
  • Provides a lot of built-in geometry types as well as a high-performance raw buffer geometry
  • Provides particle systems
  • Provides shading models called "materials" and implements a few of the popular ones
  • Support for animation, post-processing filters, custom shaders, advanced rendering modes and a lot more
     
  • Will revisit later in detail + demo

Babylon.js

  • Open-source, built by Microsoft in 2013 to showcase IE11 WebGL support
  • Particular focus on game development
     
  • Provides scene graph, object hierarchy and transformations and content loaders for several 3D file formats
  • Provides camera, projections and user interaction controls
  • Provides sprites and particle systems
  • Provides physics and collision detection
  • Very good performance through various optimizations
  • Unified material model with multiple shading features
  • Support for animation, post-processing filters, custom shaders, advanced rendering modes and a lot more

Other WebGL Frameworks

  • Turbulenz: open-source/commercial 2D & 3D game engine with frontend and backend API for advanced rendering, physics, networking, sound, input, game components, etc.
  • Pixi.js: open-source 2D rendering engine with Canvas2D fallback, scene graph & asset loader, handles input and animation, very simple API
  • CopperLicht: free 3D rendering engine, has built-in world editor (CopperCube), supports multiple 3D file formats, lots of advanced rendering features, handles input, animation and simple physics
  • GLGE: open-source 3D rendering engine, has some advanced rendering features, supports animation & COLLADA file format
  • MathBox: math diagramming with WebGL
  • Unreal Engine, Unity, Blend4Web, Processing.js, Kuda, O3D, SpiderGL, PhiloGL, etc. - possibilities are endless... Yay WebGL!

Three.js demo

Renderer, Camera & Render Loop

  • creating and configuring THREE.WebGLRenderer
  • creating and configuring THREE.PerspectiveCamera
  • creating a THREE.Scene
  • setting up a render loop and animation
    • animate camera movement
    • animate snow accumulation (revisit after particle system)
  • handling resize and full-screen rendering

All of the above provided by the excellent ThreeStrap library.

 

Manually setting up "sky", shadow map and fog.

Lights

  • AmbientLight for atmosphere
    • low intensity, otherwise scene will be drowned in light
    • works well with fog in this scene
  • SpotLight to simulate (weak) sunlight
    • must configure shadow map settings to cast shadows

Geometry

  • Procedurally generated terrain
    • using Diamond-Square algorithm
    • based on a PlaneGeometry
    • recompute normals for correct shading

Materials & Shaders

  • Ground material
    • simple texture map (repeated)
  • Snow material
    • texture map based on Canvas (cool, eh?)
    • bump map
    • transparency
  • Ray material
    • very simple custom shader material
    • shaders defined in <script> tag
    • passing time and texture as uniforms

Meshes & Particle Systems

  • Ground and snow share the same geometry
    • but use different materials
    • cast shadow, receive shadow
  • Falling snow uses a particle system
    • recently renamed to PointCloud
    • positions generated at random
    • using a simple snowflake texture
    • adding vertex colors for some variability

Interaction

  • Handle mouse events in the standard JavaScript/DOM way
  • Use mouse coordinates to intersect with terrain
  • Draw on texture canvas using intersection coordinates

DEMO

Tips & Tricks

  • Use ThreeStrap, dat.gui, stat.js
  • Use BufferGeometry for large geometries
  • Use WebGLDeferredRenderer for large number of lights
  • A lot of useful stuff in three.js extras and examples:
    • many interesting shaders and effects
    • camera controls
    • complex geometries and modifiers
    • loaders for a number of file formats

Conclusion

  • WebGL is pretty cool and powerful
  • Three.js and other frameworks make it easy to create interactive 3D apps and games for the web
  • It has never been easier - start coding now!

 

TODO tasks hidden in github code ;)

Thank you!

Time for Q&A

cg2.chaosgroup.com
www.chaosgroup.com
cg2@chaosgroup.com

Contacts

Browser 3D Graphics with WebGL and Three.js

By Mihail Sergeev

Browser 3D Graphics with WebGL and Three.js

  • 3,031