With the release of Firefox 51, WebGL 2 support has landed! WebGL is a standard API to render 3D graphics in the Web. It is based on OpenGL ES, which is commonly used by mobile games.
To date, we have been able to use WebGL 1 (based on OpenGL ES 2) to render fancy graphics into a <canvas> element. WebGL 2, however, is based on the OpenGL ES 3.0 specification, which introduces new features – many of them aimed at increasing performance and visual fidelity.
Until today, WebGL 2 had been usable behind a flag or in the Developer Edition or Nightly, but with Firefox 51, it’s now unlocked for all users of Firefox on Windows, MacOS, and Linux.
Demo: “After the Flood” (PlayCanvas)
To give you a taste of the content WebGL 2 enables, we’re excited to highlight After the Flood, an interactive WebGL 2 demo by PlayCanvas. (Please note that this demo is currently desktop only, with mobile support coming soon.) Take a walk through the fantastical environment of water, glass, and steel running entirely within your web browser!
How to use WebGL 2
To request a WebGL 2 context, all we need to do is ask for one from a <canvas> element. The string we use to request WebGL 2 is “webgl2”.
let canvas = document.querySelector('canvas');
let ctx = canvas.getContext('webgl2');
WebGL 2 might not be present in all browsers, so you should include some fallback code:
let canvas = document.querySelector('canvas');
let ctx = canvas.getContext('webgl2');
let isWebGL2 = !!ctx;
if (!isWebGL2) { // try to fallback to webgl 1
ctx = canvas.getContext('webgl') ||
canvas.getContext('experimental-webgl');
}
if (!ctx) {
console.log('your browser does not support WebGL');
}
A word of caution…
Keep in mind that while WebGL 2 is based on OpenGL ES 3.0, it’s not identical. For instance, WebGL 2 does not support program binaries, and a number of optional restrictions in OpenGL are made mandatory for WebGL 2. The differences between the two are laid out in the WebGL 2 spec, so if you’re already familiar with OpenGL, you’ll be able to get up to speed with WebGL 2 quickly.
Another thing to note is that WebGL 2 is not strictly backwards compatible with WebGL 1, so there is the possibility that your WebGL 1 code will not work as expected when using a WebGL 2 context. That said, the differences are fairly minimal, and you should be able to port your code and shaders without too much hassle. You can read a backwards incompatibility list in the spec, as well as this quick guide from WebGL2 Fundamentals about migrating code from WebGL 1 to WebGL 2.
Keep in mind that while WebGL 2 will be bringing these new features to many of our users, we cannot offer WebGL 2 to users with old or outdated graphics cards and drivers.
Highlighted features
Updated shading language
WebGL 2 supports OpenGL ES Shading Language 3.0, which allows for much more capable and efficient shading programs. The new toys include:
- True integer types
- Uniform blocks
- Binding the location indices for shader inputs and outputs in the shader source
- Fragment discard
- Dynamic loops
- Sophisticated texture sampling built-ins
Multiple render targets (“MRTs”)
This allows you to render to several color buffers or textures in one pass, using multiple outputs from the fragment shader.
This feature was enabled in WebGL 1 via an extension, but now forms part of the core set of features of WebGL 2, so there’s no need to worry about a fallback path.
One of the main applications of MRTs is a technique called deferred shading – and we have already written about it in Hacks before. It’s a rendering technique that allows for a lot of dynamic lights in a scene, since the complexity on rendering doesn’t depend on the amount of lights, but on the actual number of pixels that are being lit.
Instanced geometry drawing
Instancing allows you to render multiple instances of a geometry with a single draw call, which reduces the burden on the CPU. Note that each instance can have its own attributes, like a transformation matrix, so you could use this to render a lot of similar objects, like particles, trees in a forest, people in a crowd, etc.
The following THREE.js demo uses instancing via an extension – which, remember, is no longer needed in WebGL 2.
New texture features
3D or volume textures are textures where we access the data using three coordinates instead of two (like in regular, 2D textures). These are most commonly used for tone mapping, but also can be helpful for rendering volumetric effects, like smoke, fog, and rays.
2D array textures hold a series of separate 2D layers, which a shader can index into in order to select just one of the contained 2D textures.
Sampler objects are new in WebGL 2. These decouple the way the texture is sampled from the texture selected for sampling, so a single texture can be sampled in several ways, and multiple textures can point to the same sampler object.
WebGL 2 also removes restrictions on non-power-of-two (NPOT) textures.
Transform feedback
Transform feedback captures the output of the vertex shader into a buffer object, often using this output as input to the next frame. This creates a loop that doesn’t leave the GPU, offloading the CPU of these computations. Particle systems often take advantage of transform feedback to iterate each particle’s position and move it in each frame without CPU interaction.
Transform feedback can also be combined with “rasterizer discard”, which allows running the vertex shader without the fragment shader. This allows for natural “map” GPGPU (general-purpose computing on graphics processing units) data processing flows.
And more!
There are many more features that have arrived in WebGL 2, including Vertex Array Objects, MSAA renderbuffers, and Uniform Buffer Blocks to name a few. For a full list of everything new in WebGL 2, you can have a look at the official spec, since it contains just the differences between WebGL 1 and 2.
A number of these features can be seen in relative isolation on the WebGL 2 samples page. These feature-specific demos serve to illustrate the effects possible with new features, as well as to provide example code for how to use them.
What’s next
We’re releasing the API for widespread use today, but there’s still more work to do. We’re looking forward to working on performance improvements, relaxing some restrictions, and improving general polish. We know performance in particular is on a lot of your minds, so we have some exciting work in store to provide applications with the performance they need to deliver even more sophisticated and impactful experiences.
In addition to seeing apps add WebGL 2 support, we look forward to seeing WebGL 2 integration into existing WebGL frameworks and engines. PlayCanvas is supporting WebGL 2, as shown off in our highlight of After the Flood. Three.js also has support for utilizing WebGL 2. Keep an eye out for other engines receiving WebGL 2 support later this year!
Running into an issue? Please file a bug on our Bugzilla. (Remember: GitHub logins work too!)
About Jeff Gilbert
Jeff leads Firefox WebGL development and is co-editor of the WebGL specs.
More articles by Jeff Gilbert…
About Belén Albeza
Belén is an engineer and game developer working at Mozilla Developer Relations. She cares about web standards, high-quality code, accesibility and game development.
24 comments