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
- Acquire & prepare rendering context:
document.getElementById('canvas').getContext('webgl') - Load shaders from <script> tags or external files
- Compile shaders:
createShader, shaderSource, shaderCompile - Setup shader program:
createProgram, attachShader, linkProgram, useProgram - Setup shader variables:
getAttribLocation, enableVertexAttribArray, getUniformLocation - Transfer vertex data (Vertex Buffer Objects):
createBuffer, bindBuffer, bufferData/bufferSubData - Setup textures:
createTexture, bindTexture, texImage2D, texParameteri - 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
- Lights
- Geometry
- Materials & Shaders
- Meshes & Particle Systems
- Interaction
- Live demo at:
https://weber.chaosgroup.com/threejs-webinar - Code available at:
https://github.com/olygofren/threejs-webinar - Tips & Tricks at the end
- Q&A at the very end



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