WebGL Insights
Home Cover Table of Contents Tips Contributors Reviews BibTeX Errata Code Blog Buy


WebGL Insights includes short tips that were assembled by the contributors.

  • WebGL Report is a great way to get WebGL implementation details for the current browser, especially when debugging browser- or device-specific problems.
  • For performance, avoid object allocation in the render loop. Reuse objects and arrays where possible, and avoid built-in array methods such as map and filter. Each new object creates more work for the Garbage Collector, and in some cases, GC pauses can freeze an application for multiple frames every few seconds.
  • Save memory and improve performance by ensuring that contexts are created with the alpha, depth, stencil, antialias, and preserveDrawingBuffer options set to false, unless otherwise needed. Note that alpha, depth, and antialias are enabled by default and must be explicitly disabled.
  • For performance, query attribute and uniform locations only at initialization.
  • Int precision default qualifiers aren't the same between vertex and fragment shaders. This can lead to surprising visual differences when moving computation between each.
  • For portability, keep space requirements of varyings and uniforms within the limits of the GLSL ES spec. Consider using vec4 variables instead of float arrays, as they potentially allow for tighter packing. See A.7 in the GLSL ES spec.
  • Non-power-of-two textures require linear or nearest filtering, and clamp-to-border or clamp-to-edge wrapping. Mipmap filtering and repeat wrapping are not supported.
  • When we are using more than one draw buffer with the WEBGL_draw_buffers extension and we don't want to write to a given draw buffer, pass gl.NONE to the draw buffers parameter list.
  • We must always provide all color attachments that our framebuffer has. Always enable strict mode via the "use strict" directive. It slightly alters JavaScript semantics so that many silent errors turn into runtime exceptions and can even help the browser better optimize our code.
  • Code linters such as JSHint are an invaluable tool for keeping JavaScript code clean and error free.
  • Create new textures, rather than changing the dimensions or format of old ones. - Chapter 1
  • Avoid use of gl.TRIANGLE_FAN, as it may be emulated in software. - Chapter 1
  • Flag buffer usage as gl.STATIC_DRAW where appropriate, to allow browsers and drivers to make use of optimizations for static data. - Chapter 1
  • Make sure that one of the array attributes is bound (using gl.bindAttribLocation) to location 0. Otherwise, high overhead should be expected when running on non-ES OpenGL platforms such as Mac OS X and desktop Linux. - Chapter 2
  • Pass data back and forth from Web Workers using transferable objects whenever possible. - Chapters 4 and 21
  • Although typed arrays have performance advantages, using JS arrays in teaching allows students to write clearer JS code with the use of array methods. - Chapter 7
  • Using mediump precision in fragment shaders provides the widest device compatibility, but risks corrupted rendering if the shaders are not properly tested. - Chapter 8
  • Using only highp precision prevents corrupted rendering at the cost of losing some efficiency and device compatibility. Prefer highp, especially in vertex shaders. - Chapter 8
  • To test device compatibility of shaders that use mediump or lowp precision, it is possible to use software emulation of lower precision. Use the—emulate-shaderprecision flag in Chrome. - Chapter 8
  • When using an RGB framebuffer, always implement a fallback to RGBA for when RGB is not supported. Use gl.checkFramebufferStatus. - Chapter 8
  • To save a lot of API calls, use vertex array objects (VAOs) or interleave static vertex data. - Chapter 8
  • For performance, do not update a uniform each frame; instead update it only when it changes. - Chapters 8, 10, and 17
  • If shrinking the browser window results in massive speed gains, consider using a half-resolution framebuffer during mouse interaction. - Chapter 14
  • Load time can be improved by amortizing slow tasks across several frames. - Chapter 14
  • Be vigilant about using requestAnimationFrame — ensure that most, if not all, of your WebGL work lives inside it. - Chapter 14
  • The textureProj GLSL function, vec4 color = textureProj(sampler, uv.xyw);, can be simulated with vec4 color = texture(sampler, uv.xy/uv.w); - Chapter 17
  • Avoid using common text-based 3D data formats, such as Wavefront OBJ or COLLADA, for asset delivery. Instead, use formats optimized for the web, such as glTF or SRC. - Chapter 20
  • Use OES_element_index_uint to draw large indexed models with a single draw call. - Chapter 21
  • Smooth, cinematic camera transitions can be created by a cosine-based interpolation of the camera's position and orientation. Unlike nonlinear interpolation alternatives, the cosine interpolation is computationally cheap and easy to calculate. - Chapter 23