WebGL2Fundamentals.org and stuff

2016-09-28

I recently made webgl2fundamentals.org. WebGL2 is backward compatible with WebGL1 which means anything you learn about WebGL1 is applicable to WebGL2 but there's a few things that made it seem like it needed a new site.

The biggest were GLSL 3.00 ES which is an updated version of GLSL that's not available in WebGL1. It adds some great features but it's not backward compatible so it seemed like making all the samples use GLSL 3.00 es was better than leaving it as is.

Another big reason is WebGL2 has Vertex Array Object support. I had not used them much in WebGL1 because there were an optional feature. After using them though I feel like because it's possible to make a polyfill I should have always used them from day 1. Those machines that need the polyfill are also probably machines that don't run WebGL well in the first place. On the other hand I think people would be annoyed learning WebGL1 if they had to rely on a polyfill so as it is I'll leave the WebGL1 site not using Vertex Array Objects.

The second biggest reason is I got my math backward. Matrix multiplication is order dependent.  B != B  A I've used various 3d math libraries in the past and I personally never noticed a convention. I'd just try  B  C  D and if I didn't get the result I wanted I'd switch to  C  B  A. So, when I made the math library for WebGL1 I picked a convention based off matrix names. It's common to have names like viewProjection and worldViewProjection so it seemed like it would be easier to understand if

viewProjection = view * projection

and

worldViewProjection = world * view * projection

But, I've been convinced I was wrong. It's actually

viewProjection = projection * view

and

worldViewProjection = projection * view * world

I won't go into the details why but I switched all the math on webgl2fundamentals.org to use the second style.

Anyway, that's beside the point. The bigger issue is the pain of updating it all. There are currently over 132 samples. If I decide that all samples need to switch their math that's several days of work. Even if I decide something small like all samples should clear the screen or all samples should set the viewport it takes hours visit each and every one and update. Some have patterns I can search and replace for but they're often multi−line and a pain to regex. I wonder if there is some magic by which I could go edit git history to make each change back when I made the first sample and then see that get propagated up through all the samples. Sadly I don't think git knows which samples were based off others and even if it did I'm sure it would be even more confusing figuring out where it couldn't merge.

I'd hard to get everything right the first time, at least for me, and so as I create more and more samples and get more and more feedback I see places where I should probably have done something different right from the start.

For example my original goal in writing the first sample was to be as simple as possible. There's about 20 lines of boilerplate needed for any WebGL program. I originally left those out because it seemed like clutter. Who cares how a shader is compiled, all that matters is it's compiled and we can use it. But people complained. That's fine. I updated the sample to put those 20 lines in but removed them in the 2nd sample.

Another issue was I didn't use namespaces so there are functions like createProgramFromScripts instead of webglUtils.createProgramFromScripts. I'm guessing being global people were like "where is this from?". I switched them. I'm hoping the prefixes make it clear and they'll see the webgl-utils.js script tag at the top.

Similarly the first sample just makes 1 draw call on a fixed size 400x300 canvas. Again, to keep it as simple as possible a ton of stuff is kind of left out. For example setting uniforms once during initialization. If you're only going to draw once that seems natural but drawing only once is a huge exception so it ends up making the sample not representative of real WebGL code. Similarly because the canvas was a fixed size there no reason to set the viewport. But 99% of WebGL apps have a canvas that changes size so they need to set the viewport. Similarly because they resize they need to update the resolution of the canvas but I had left both of those steps out. Yet another was using only one shader program. A normal WebGL app will have several shader programs and therefore set which shader programs to use at render time but the samples were setting it at init time since there was only 1. The same for attributes, textures, global render states, etc.. All of these things are normally set at render time but most of the samples were setting them at init time.

Anyway, I updated almost all of that on webgl2fundamentals.org. Now I'm trying to decide how much time to spend backporting to the old site given it took easily 40−60 hours of work to make all the changes.

I recently added a code editor to the site so people can view the code easily. That's another one of those things where I guess having written JS related stuff for the last 8 years I know some of the tools. I know you can pick "view−source" and/or you can open the devtools in any browser and see all the code. I also know you can go to github which is linked on every page and see the source. That said I got several comments from people who got lost and didn't know how to do any of those. Should I put a link under every single sample "click here to learn how to view source" that leads to tutorials on view source, devtools, and github? How to get a copy locally. How to run a simple web server in a few seconds to run the tutorials locally. I suppose I should write another article on all that stuff.

Well, I added the code editor for now which I'm a tiny bit proud of. At least in chrome and firefox it seems to catch both JavaScript errors and WebGL errors and will put your cursor at the correct line in your source. It also displays the console messages. I got that inspiration from Stack Overflow's snippet editor but theirs gives the wrong line numbers. Unfortunately it's a pretty heavy editor but it does do intellisense like help. Hopefully it will be updated to handle JSDocs soon like it's big brother.

But, that brought up new issues which I'm not sure I should handle or not. The original samples had a fixed size. With the code editor though the size can change. I updated all the samples to handle that but it's not perfect. Most real WebGL apps handle this case. Should I clutter the code in all the samples to handle it? All the animated samples handle it but non animated samples don't. Some of those samples it would basically just be one line

window.addEventListener('resize', drawScene);

But of course it's not that simple. Many samples are only designed to draw once period and would have to be re−written to even have a drawScene function.

I'm not sure what my point was in writing this except to say that it's a new experience. Normally I work on 1 program for N months. If I decide I need to refactor it I refactor it. But for these tutorials I'm effectively working on 132+ tiny programs. If I decide I need to refactor I have to refactor all 132+ of them and all the articles that reference them.

Comments
Fun (or not so fun) Chrome ... Issue
Isolating Devices on a Home Network