Is there any reason, except performance, for using WebGL instead of 2D-Canvas for 2D games/apps?
In other word what 2D functionalities are offered by WebGL which are not possible to achieve easily with 2D-Canvas?
Is there any reason, except performance, for using WebGL instead of 2D-Canvas for 2D games/apps?
In other word what 2D functionalities are offered by WebGL which are not possible to achieve easily with 2D-Canvas?
Looking at this question from another side:
How does a developer choose one technology over another?
So I'll discuss the differences between canvas and webGL APIs regarding these qualities.
Both canvas and webGL are JavaScript APIs. They are pretty much the same regarding integration (binding). They are both supported by a number of libraries that could speed up your coding. Different libraries give you different ways to organize your code, so library choice dictates how your drawing APIs are structured, but it's still pretty much the same thing (how the rest of the code binds together with it). If you use library, the ease of writing code depends on the library itself.
If you write code from zero, the canvas API is much easier to learn and understand. It requires minimal math knowledge, and development is fast and straightforward.
Working with the WebGL API requires strong math skills and a full understanding of the rendering pipeline. People with these skills are harder to find, production is slower (due to the size and complexity of such a code base), and therefore it costs more.
WebGL is faster and it has more capabilities. No doubt about that. It's a native 3D API that gives you full access to the rendering pipeline, code and effects are executed faster and are more 'tweakable'. With webGL there really is no limit.
Both canvas and webGL are html5 goodies. Usually the devices that support one will support and the other.
So, to sum up:
P. S. Open for discussion.
The biggest advantage is the programmability of the pipeline, and the performance. For example, say you are drawing 2 boxes one above other and one is hidden, some GL implementations have scope for discarding the hidden box.
Comparison table below. Added Three.js for completeness only.
Canvas API | WebGL Equivalent | Three.js Framework Equivalent |
---|---|---|
scale | texImage2D + modify vertices | Camera |
rotate | texImage2D + modify vertices | Camera |
translate | texImage2D + modify vertices | Camera |
transform | texImage2D + modify vertices | Camera |
clearRect | clear + viewport, or texImage2d | Textures |
fillRect | clear + viewport, or texImage2d | Textures |
strokeRect | texImage2d | Textures |
path | texImage2d + stencil+ vertex paths | Camera + objects |
fillText | texImage2d + stencil+ vertex paths | Camera + objects + textures |
strokeText | texImage2d + stencil+ vertex paths | Camera + objects + textures |
drawImage | texImage2d | Textures |
createImageData | fill buffer of texImage2d in CPU application | CPU application code |
getImageData | readpixels | readpixels |
putImageData | fill buffer of texImage2d in CPU application | fill buffer of texImage2d in CPU application |
+ programmable shaders (vertex,fragment) | ||
+ offscreen buffers | ||
+ efficient 3D representation of depth | ||
+ efficient points (and other primitive) rendering | ||
+ Convenience methods - Materials (sprite ..) | ||
+ Convenience methods - Lights | ||
+ Convenience methods - Scenes |
Speaking from experience on my own applications, graphics shaders have been the one and only reason I've required support for WebGL. Ease of use has little bearing for me since both frameworks can be abstracted away with three.js. Assuming I don't need shaders, I allow use of either framework to maximize browser/machine support.
What 2D capability does WebGL offer that 2D canvas does not? The biggest one IMHO is the programmable fragment shaders on the graphics hardware. For example, in WebGL, one can implement Conway's Game of Life in a shader on your 3D hardware:
http://glslsandbox.com/e#207.3
This kind of 2D display would only run on the CPU, not the GPU, with a 2D canvas. All of the computations would be implemented in JavaScript, and would not be as parallel as the GPU even with the help of web workers. This is just one example of course, all kinds of interesting 2D effects can be implemented with shaders.
Well, performance would be the one of the biggest reasons because when you are coding a game, it has to be fast. But there are a couple of other reasons for which you might want to choose WebGL over canvas. It offers the possibility to coding shaders, lighting and zooming, which is important if you are doing a commercial game app. Also canvas gets laggy after 50 sprites or so.
There's nothing you can do with Canvas that you can't also do with WebGL: the canvas lets you crush the bytes with get/putImageData, and you can draw lines, circles, ... programmatically with WebGL.
If you're seeking to do intensive drawing, such as complex effects at 60 fps, the performance gap is high. Things that are really slow with 2D Canvas will run fine in WebGL. Performance is WebGL's basic feature.
Yet WebGL is quite complicated to program. See if canvas is good enough for you, or seek a library that will ease the pain.
Another drawback to WebGL: it doesn't work on IE (but what does?), and on some mobile platforms. See here for compatibility: https://caniuse.com/webgl
As you specifically want some classic 2d things that don't work well with canvas:
... but of course you have pixel access, so you can do really anything, including the above, manually. But that can be really, really slow. You could emscripten Mesa openGl to render to canvas in theory.
Another big reason to use webGL would be that the result is very easy to port to anywhere else. Which also makes the skill more valuable.
Reasons to use canvas are that it is still better supported and if you learn doing things pixel by pixel that is also a very valuable lesson.
WebGL is unusable without a GPU.
This hardware dependency is not a big problem because most systems have GPUs, but if GPU or CPU architectures ever evolve, preserving webgl content by emulation may be challenging. Running it on old (virtualized) computers is problematic.
But "Canvas vs WebGL" does not have to be a binary choice. I actually prefer using webgl for effects, but doing the rest in canvas. When I run it in a VM, it still works nicely and fast, just without the effects.
Update: Unfortunatelly some browsers (Chrome on Windows, Everything on Linux, others?) implement well-meant emulation layers that make detection of poor/no GPUs hard. In these cases either the game or the user has to disable WebGL manually to get the actual performance benefits... ...or degradation, when the 2D is implemented poorly. Allegedly that can happen too. [Thanks gman]
As WebGL is particularly new technology and HTML5 canvas is more established what you want to use depends on your users. If you think that your users will use mobile devices then I would suggest HTML5 canvas but if you want better 2D rendering I would use WebGL. So what you could do is if the use is on mobile render with HTML5 else if they are on a platform that supports WebGL.
For example:
if (window.WebGLRenderingContext) {
webGLcanvasApp()
} else if( /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent) ) {
html5CanvasAppFMobile()
} else {
html5CanvasApp()
}
Sources:
Proper way to detect WebGL support?
What is the best way to detect a mobile device in jQuery?