Things I hate about WebGL

Inspired by this post from Rich Geldreich, and after coding in WebGL for more than two years, I want to make a list of all the things I hate about WebGL graphics programming. Which doesnt mean I dont like WebGL, just that there are many fields to improve that should be addressed.

Thinking of WebGL as OpenGL ES as if the context was the same

When you code OpenGL applications for the desktop using a native language like C++, you have a fast executing language accesing usually a fast GPU. So you have a complete freedom to do whatever you want.

When you code in OpenGL ES for mobiles, you have a fast executing language accesing usually a slow GPU (mobile GPUs are always some generations behind of desktop GPUs although the gap is shrinking faster every year). This means you try to balance the load of the GPU by doing some parts in the CPU (thanks to multicore mobile CPUs). So the OpenGL ES API was meant to be basic because of the nature of mobile GPUs.

But when you code in WebGL for desktop you have a slow executing language accessing a fast GPU, in that case you want the GPU to do as much as possible, so I dont have to rely on slow scripts to process the data. The common case is to apply a shader to a bunch of data and store the result in another buffer (precomputed skinning) or culling object by its bounding box.

But because WebGL comes from OpebGL ES it seems to imply that WebGL was meant to work in mobile devices, but lets be fair, WebGL is far away from being used in mobile devices, maybe you can make a textured sphere spin on the screen, but beyond that you hardly can do a true 3D app in mobile with Javascript, it will have slow performance and consume all the battery.

So WebGL should be driven by the desktop, not mobile devices. And the API should grow so it allows more access to all those funcionalities in the OpenGL standard that let me move the intensive computations from the CPU (javascript) to the GPU (compute shaders).

Right now the only solution are the unofficial extensions added by Chrome or Firefox but I dont like to move further from the standard.

 

Not taking advantage of the async behaviour of Javascript

Because WebGL is a direct port of OpenGL ES, it seems to forget that it is an API made for Javascript, it should focus in a better integration with Javascript. Sometimes it seems that WebGL was meant to work with any language more or less like OpenGL ES.

Something as simple as using the glReadBuffer function associated with a callback would be great. Think about it, glReadBuffer is usually forbidden because it stalls the execution of the script till all the graphics calls in the queue are resolved. But because we are working in Javascript, it would be awesome that glReadBuffer throws an event after getting the buffer, so I dont have to wait. Javascript coders are used to use async functionalities.

Other cases could be compiling shaders (most of the work is done in the driver so why not allow to compile shaders asyncronously so I can send a bunch of them without affecting the fps?

I understand that due to the nature of threads and the JS VM this are not easy to do, but I dont see people working on this things in the spec.

Adapting to the hardware context

Another problem when working for the web is that you never know what the user computer is capable of. You can query for certain extensions but besides that you dont know if the user has a high-end GPU from NVidia or just some crappy integrated card from Intel.

In desktop we can query to know more about the model of the GPU but in the Web this is considered forbidden because people could use that info to track users. I’m totally aware of the risks of letting website track the users but come on, having something like a browser agent for GPUs would be more than enough, and it is not like having the serial number of the card.

Desktop games can do a little benchmark the first time you execute them to check how many fps you can get and adapt the settings of the render engine according to that, but the nature of websites dont allow you to do that, users dont want to open a website and have to wait.

So all my webgl apps rely on the user to choose which quality they want, and even though that is dangerous, which configuration do you use the first time? the low one? but then users will think your 3D just look ugly, or the high one? but maybe you are going to crash the desktop.

Just try to open shadertoy.com with a bad GPU, it totally destroy the GPU and there is nothing they can do to avoid it.

 

No shared resources among contexts

This is treated like an advanced feature but for me its mandatory. If you are rendering in a website you probably want to have several canvas in different DIVs, not only for multiple viewport but also to have a detached window with a preview, to use secondary screens, or to have a previsualization of some resources in a different container.

In the application I’m currently developing I’m doing lots of hacks just to be able to have diferent views of the same resources in my WebGL Context, which is slow and ugly (like passing the result as a canvas to another canvas).

At least this one seems to be being addressed.

 

Missing basic features from the spec

I can understand that being based in OpenGL ES we cant expect to have the whole set of functionalities that the GPUs behind my WebGL app have. Its kind of sad of having all the features partially exposed, but I get it. What it doesnt make sense is some of the stuff its been left out, here is a brief list.

  • texture2DLod is only accesible in vertex shaders, not in pixel shaders. I dont  understand why, I love to use that function to control the glossiness of the environment maps and now I cant.
  • some basic matrix operations in the shader. Maybe its me but I havent figure out if there is a function to transpose a matrix in GLSL from WebGL.
  • render to Vertex Buffer, although this will be arriving eventually with the 2.0 spec.
  • uploading uniform structs in one call
  • Chrome not allowing to set the lineWidth ¿??

 

 Conclusion

WebGL its a great push forward for the web, but unless it tryes to go faster than the OpenGL ES spec, most of the graphics programmer will get tired of using a subspec.

Leave a Reply


nine − = 7