Monday, August 8, 2011

WebGL Frameworks are awesome, here's why I don't use them.

Tonight I was posed a very interesting question by @HunterLoftis on twitter:

What's your opinion on three.js, glge, etc? I haven't seen anything in that camp half as performant as your quake 3 fullscreen demo

I answered him with my < 140 char assessment of the situation:

I think they're great frameworks, but I question if a high-performance WebGL app can afford the overhead.

I feel like this is a subject that could use a bit more explanation, though, because it's not at all black and white.

First off, it's worth looking at why these frameworks exist at all. After all, somebody thought they were worth building, right? Overwhelmingly, the big driving force behind any of the frameworks I have seen is simplifying your setup. I mean, there's a reason that some of these people have cool demos coming out their ears and I have, what, six? It takes a lot of work to set up that damn little WebGL canvas! Initializing the canvas is pretty easy, but in order to get anything to show you need to create your vertex buffer, fill it, bind it properly, write your shader, compile it, link it, bind it, and then dispatch the draw call. And that's only if you don't care about perspective and nothing moves! If you want anything beyond a simple triangle or quad you also need to create some matricies (something that there's no native library for, BTW!) run through the required maths, bind them to the appropriate shader slots, and then render. Oh, and if you want it to be interactive at all now you're doing input handling too. And by the way, where are your vertices coming from anyway? Anything more complex than a cube is impractical to code by hand, so you need a model format that you can export to and parse...

Tired yet?

That's a lot of pain and suffering to go through if all you really want to do is test your cool new shader. So a few industrious fellows such as the wonderful Mr. Doobhave put a good deal of time and effort into creating some nice libraries that hide away the worst of that crud behind a simple interface and let you get to the bits that you're really interested in working on, wether that be a shader, an animation technique, a physics simulation, etc. And for most purposes they will work beautifully! There's a lot to be said for skipping the "boring" bits and just making your app work. In fact, 99% of the time I would fully recommend using them. If you are questioning wether or not you should be using a framework, the answer is probably "Yes!"

There is really only one exception: If performance matters.

Now, hold up one second. You're a programmer, so your first thought is immediately: "Well, yeah! Performance ALWAYS matters!" And you're right, but there's a difference between wanting good performance and really needing top notch performance. Simple example: Google uses a framework for Google Body. Does your need really outstrip theirs? Probably not.

[UPDATE: So, apparently I chose a bad example for this one. @won3d mentioned in the comments that Google Body only uses TDL for some math and texturing convenience functions. So, how about a better example: ROME uses three.js, and they aren't really a slouch in the graphics department.]

A good counter example, though, would probably be realtime games. (Which always tend to be edge cases in any environment). If Google Body hitches for a second or so, nobody really cares, but if your Diablo clone stutters a few times you may have just killed your player, and they're not going to be happy at a loss that was clearly not their fault. So yeah, now performance matters quite a bit.

In a scenario such as that, suddenly a generalized framework makes a lot less sense. In fact, I would go so far as to say that even the WebGL-centric "Game Engines" are ill suited as well. The fact is, Javascript is a slow environment by most any measure. If you're really looking for raw speed, you don't want to be doing ANYTHING that doesn't directly serve your purpose. The only person who's going to know what you need, though, is you, and as such any framework you use is going to be doing things that you don't need or want, or at the very least doing them in a less optimal way. So there is a very tangible benefit to coding the ugly bits by hand.

Do you actually want to do that, though? It's worth considering that you really need to know what you're doing to get any benefit from coding at that "low level" (a phrase which strikes me as very amusing in browser land). And, yes, it will be painful. But if you really need that performance it will be worth it! If you're on the fence, though, crack open your framework of choice and give it a try there first. I'm guessing that whatever your project is it will probably do fine there. If you can prove to yourself that you need more control over the environment, though, then by all means go crazy!

So, the final question: Why don't I use any of the frameworks available out there? I have nothing against them, I promise, nor do I feel that I'm "above" the need for them. For me it comes down to two simple things: On the one hand Some of my demos (Quake/Rage) are built specifically to eek out every last drop of performance I can get, to really show what WebGL is capable of. Performance is the whole point of said demos, so it's worth it to be bare bones. Secondly, I personally enjoy the challenge! I've been coding OpenGL for a while, and it's fun for me to see how much I can optimize this scenario or that. But if I were to go back and do, say, my Spore or Hellknight demos again? Yeah, I'd be jumping on three.js in a heartbeat.

I'll leave you with one more thing to consider, however: Web browsers are evolving crazy fast. My advice about performance will probably hold true for the first generation of WebGL games, but check again a couple years down the line and it's entirely possible that the performance situation will have improved enough to render this whole discussion moot.