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.

6 comments:

  1. This is why I like frameworks that are easy to 'outgrow' - you app logic starts small, most of the code running is in the framework but once you get bigger that ratio turns around and you might even end up dropping parts of the framework or rewriting them.

    I wouldn't ditch frameworks, just don't use them if they are hard to get rid of or modify to your need.

    ReplyDelete
  2. I agree with this post, lots. But a correction: we really didn't use TDL that much for Body. Some math stuff and some texture convenience stuff sure but all the rendering is done pretty close to the metal. I'm sorry that I wasn't able to get out all the hitches, but I could only really afford to spend a day on it.

    Anyway, to echo your statement: performance is a big reason to avoid the frameworks, but that assumes you know performance characteristics more than what the framework is already doing.

    sjmono hits on a crucially important point: he said that you should be able to "outgrow" the framework. Indeed, I dislike frameworks exactly because they make this difficult. Unlike normal libraries, frameworks tend to lock you into a particular idiom of programming and make it difficult to shift to a different style, or to replace certain parts without hacking up the framework. Open source is no excuse for library authors to not think very hard about interfaces.

    @won3d

    ReplyDelete
  3. Thanks for the clarification! Always nice to hear these things from the source. I'll update the post to prevent the spread of misinformation. :)

    Also, I didn't mean to imply that Google Body does not perform well. I've personally found it to be pretty fast. I was simply pointing out that for it (and many other applications) good performance is not really a critical feature. It's great when it's there, but it won't break the app if things stutter once in a while.

    ReplyDelete
  4. Well there's fast and there's fast without hitches! Maybe there's a "familiar breeding contempt" thing going on, but let's just say you're not the only one noticing how slow texture uploads are. If I had more time, I would have done something smarter to schedule their uploads to minimize user jankiness.

    I agree, for something more interactive/reactive like a game, hitch-free is a bigger issue, but I also have my pride to worry about. :)

    ReplyDelete
  5. Have you seen this?

    http://static.britzpetermann.com/experiments/akemi/

    That's pretty sexy and no slouch either. Guy was testing the capabilities of HaXe with WebGL.


    Then, there's this guy, who claims to have gotten better FPS using HaXe than by his own strictly JS coding. Not sure how much I trust a guy who was calling a drawscene function after every particle before realizing his flaw much later though.... (i think he mentioned that in a related link)
    http://mikecann.co.uk/personal-project/more-html5-haxe-speed-tests/



    I have a decent background in OpenGL, but I'm very new to this WebGL scene, I'm trying to establish the best route to go (at this point) for speed, versatility, and reliability. I want the ability to have realtime compile errors. Really, really, want that.

    I also looked a bit into gwtGL (a Java wrapper into JS that 'claims' to be incredibly efficient), but I was mostly dissuaded by the necessary addition of the GWT to run the page and the all-together lack of implementation from all of the web.

    I guess my question is: have you looked into HaXe ?

    ReplyDelete
  6. This is a bit of a late reply, but as a follow-up to your claim of JS being slow, do you have any plans to mess with Native Client? Or does it have to prove to be cross-browser before you even consider that? I'm sure a WebGL-powered NaCl game would be the best solution as for speed *if* it ever becomes a cross-browser solution.

    ReplyDelete