hacking with

THREE.js & WebGL




three.js

is awesome




... but has some pitfalls

BLOATED

  • 430kb minified
  • More features daily
  • Not very modular

“locked” to scene graph

  • Lots of stuff going on behind the scenes
    • sorting geometry
    • new shaders being created
    • shader uniform updates
    • CPU => GPU uploads

DYNAMIC RENDERING

  • Buffering geometry every frame
    • text effects on Jam3 site
    • complex 2D games
    • animated 2D shapes
    • complex GUIs, text

TEXT RENDERING

  • Only supports mesh-based text
  • Limited unicode sets, i.e. no icon fonts
  • Uses typeface.js - no kerning or glyph metrics
  • No control over triangulation
  • Triangulation errors e.g. Jam3 Site
  • Curves look segmented at large sizes
  • Large JS file for a font
  • Expensive to process and render
  • Overkill for simple 2D needs

TEXT ALTERNATIVES

fontpath

  • more control over triangulation
  • kerning, advanced glyph metrics
  • more focus on 2D and 3D effects
  • not tied to any particular renderer


performance optimizations

SNAPPY WEBGL apps

  • Single WebGL context/canvas
  • Load textures/geometry/etc once and re-use it
  • failIfMajorPerformanceCaveat
  • Don't abuse requestAnimationFrame
  • Keep an eye on memory in Chrome debugger
  • Debug GL state to see what textures and
    shaders are being created
  • Beware of "GPU sync" ...

GPU SYNC

Moving a texture from <img> into GPU memory

  • Synchronous, causes a pipeline stall
  • Upwards of a couple seconds
  • Makes CSS/DOM animations stutter
  • THREE.js gives us no control when it happens
  • Happens with buffers, too (i.e. models)

GENERAL WebGL OPTIMIZATIONS

  • batch everything
  • be careful with render-to-texture 
  • and FBO switches, e.g. post-processing
  • re-use shaders & merge shader code
  • use sprite sheets (for 2D games, PIXI, etc)
  • prefer vertex over fragment operations
  • simplify shaders: avoid "branching"
  • { alpha: false } 
  • { antialias: false }

example:
vertex animations

  • First thought: Modify vertex positions
  • This leads to re-uploading vertex buffers to GPU
  • Different meshes can no longer share 
    the same geometry
  • Solution: move the animation to the vertex shader
  • Custom vertex shader with THREE.js' default
    Lambert fragment shader:
    http://bit.ly/1oe42lZ

“KAMI”

DOWN TO THE METAL


  • Lightweight
  • Full control over GL state
  • Compressed textures
  • SpriteBatching
  • Good for learning what happens "under the hood"

gl-modules




cheers.


Hacking with THREE.js

By Matt DesLauriers

Hacking with THREE.js

  • 7,827