Archive for June, 2011

WebGL performance

June 16, 2011

It turns out the performance problem I mentioned in Chrome is entirely down to Float32Array. Known problem, apparently. In particular it looks to me like garbage collection, as it only shows up every few dozen frames (few hundred in less geometry-intensive cases).


June 14, 2011

I’ve been learning about WebGL recently, not that I have any particular reason to use it. My first experiments, selected mostly because they look neat, are here:

  • A Julia setA Hopf fibration viewer. The Hopf fibration is interesting and important mathematically—it’s part of the reason homotopy theory turns out to be so much more complicated than homology, for example—but its real importance to me is that it makes for great pretty pictures.
  • AMandelbrot set “explorer.” That’s the first thing everyone does when they learn about shaders, right?
  • A Julia set explorer. It turned out far trippier than I had hoped for.

I’m comfortably certain these are not models of good WebGL practice. (Or good html/javascript practice, for that matter).

So what have I learned? For starters, half the people I’ve tried to show these things to can’t run them, for whatever old-browser and old-graphics card/driver reasons. How long will it be before you can reasonably assume any random user is likely to be able to use this stuff? I suppose it does make sense to learn it now so as to be ready in five years when it’s generally supported. Or maybe it’s that the primary audience is gamers, happy to have an excuse to buy a new graphics monstrocard every few months.

As for the thing itself, it’s interesting comparing it to what little I remember from the days when I knew OpenGL. From a high level it’s pretty much what you’d expect from a translation of OpenGL, or a stripped-down version of it, into javascript, the most obvious difference being that you have to provide your own shaders. I’m rather glad to have to reason to learn about shaders, really; they’re new since my day.

I haven’t figured out all the nuances of GLSL. As an example of the sort of thing I’ve run into, the Mandelbrot fragment shader has a big loop to count iterations. for-loops in GLSL must be of a form like

    for(int i=0; i<CONST; i++) {

where CONST is some actual constant—I assume, possibly wrongly, that that’s so loops can be implemented by unrolling. That I learned quickly enough. Where I ran into problems was figuring out what the CONST could be. Some machines, at least older ones, seem to have a cutoff of 255, and behave oddly (it doesn’t look like a simple mod, but I haven’t tried to figure it out) if the bound exceeds that. The GLSL spec (which appears to be somewhat out of sync with what WebGL as implemented uses; am I looking in the wrong place, or otherwise missing something?) wasn’t much help there.

Back to WebGL vs. OpenGL in general, the other immediate difference is that there’s no more glBegin/glEnd: you have to do everything with buffers. That seems to add to the boilerplate. And of course a lot of the familiar OpenGL and glu methods for things like matrix handling are missing, so you have to provide them yourself. Or find a library that does them all. I don’t think I particularly like either of the ones I’ve seen, but haven’t really thought about them much yet. I can see performance being an issue with getting libraries right.

And finally it’s a bit annoying that WebGL only knows from floats, not doubles. That rather surprises me, but I don’t know enough about this stuff to rant without making a fool of myself.

As long as I can stick to my machine, a relatively beefy Macbook Pro, I’m impressed by how well this stuff works, despite the whingeing above. I haven’t done any real stress tests, but what I have done seems to work well and quickly. As expected, both chrome and Firefox support it. Interestingly, the Firefox implementation seems to be noticably more performant than Chrome. During animations Chrome seems to seize up (garbage collecting?) every couple of seconds. Firefox is nice and smooth.