Friday, August 16, 2013

Holistic WebGL

ho·lis·tic  
Adjective
  1. Characterized by comprehension of the parts of something as intimately interconnected and explicable only by reference to the whole.
  2. Characterized by the treatment of the whole person, taking into account mental and social factors, rather than just the physical...
Definition from Google Search

As I've established way back on the very first post on this site, WebGL is awesome. So awesome that one might be tempted to start seeing opportunities everywhere around the web to throw some 3D goodness at it. After all: when your hammer is a 3D API, every problem looks like a vertex array... er, or something like that. Now never let it be said that I discouraged the use of WebGL, but as developers we should also be aware that every technology has a time and place.

What is holistic WebGL? It's application of the technology in a way that takes in to account the entire web experience, not just the content of your canvas tag. Holistic WebGL content is considerate about it's context and respectful of the user's time, attention, and battery life. In essence, it's the exact opposite of this:

Now I'm guessing that very few visitors to this site were actively working on "Punch the Polygonal Monkey" banner ads, but it's not hard to envision such a thing. After all, we all know that "eye catching" is an advertiser's friend. What's a poor ad designer to do now that their beloved Flash is being slowly smothered? Why, hellllooooo there HTML5! What lovely WebGL you have! And now we have pages where a deluge of banner ads all rendering beautifully shaded cars, watches, and pharmaceuticals makes your battery commit suicide, your fans squeal, and your page chug.


But wait! It doesn't have to be like that! WebGL can be used in a way that's both exciting and engaging while simultaneously being non-obtrusive and (crucially) non-rage-inducing. Much of it involves simply being aware of what place your WebGL content in the page as a whole.

Wednesday, July 3, 2013

WebGL instancing with ANGLE_instanced_arrays

And still no Shakespeare...
Ever find yourself in a position where you absolutely, positively have to get a ton of monkeys on screen with a single draw call?

Yeah, okay, me neither. (At least, not until I put together the demo for this post.)

But there's certainly occasions when it makes a lot of sense to redraw the same mesh many times with some minor tweak like position, orientation, color, etc. Simple examples of this are trees and other vegetation, streetlights,  boxes in a warehouse, soldiers in an army, and so on.

Traditionally with WebGL the optimal way to draw those repeated meshes, commonly referred to as instances, would be something like the following pseudocode:

bindMeshArrays(gl);
for (i = 0; i < meshInstances.length; i++) {
  var instance = meshInstances[i];
  gl.bindUniform3fv(meshPosition, instance.position);
  gl.bindUniform4fv(meshColor, instance.color);
  gl.drawElements(gl.TRIANGLES, indexCount, gl.UNSIGNED_SHORT, 0);
}

This is good, because we only set up the vertex attributes (implied to be in bindMeshArrays) once,  then make many draw calls in quick succession, only changing the properties that are different from instance to instance. In this case just position and color. This makes for a near minimal amount of overhead for each draw call, and in an environment like Javascript where each call is expensive that's important!

(This example is pretty simple, and in fact you can actually optimize it further by getting creative with how you provide the GPU with the data. Check out Gregg Tavares' wonderful Google I/O talk for more ideas about how to render lots of geometry very quickly.)

Even in this scenario, however, you have to make at least three WebGL calls for every instance of the mesh. That doesn't sound terrible but in the real world that would probably be quite a bit more, and the fact is that in Javascript every call into native code (Like the WebGL API) carries a certain expense. Thus while drawing repeated meshes in this way works, and generally works well, it could still be better.

And that's exactly why we have ANGLE_instanced_arrays.

Friday, June 14, 2013

No more Google+ comments

I tried out the new Blogger Google+ comments for a while, but after experiencing some weird behavior (like comments not displaying on mobile) and hearing from a couple of people that avoided leaving comments because they didn't want a Google+ account I've decided to turn them off. This may cause a couple of comments to disappear, and I apologize for the inconvenience, but I'd rather have a reliable commenting system.

A Tale of two Web Technologies

Let's play a quick game: I'm going to describe a relatively recently announced web technology, and I want you to guess what it is.
  • It was developed by a generally well respected company that focuses on moving the web forward.
  • It was started to enable the web to move beyond the inherent limitations of javascript.
  • It allows developers to run applications programmed in a language other than javascript.
  • The company behind it encouraged others to join in its development, and has actively been improving it themselves.
  • It was designed so that when run in a specialized VM it could run much faster than an equivalent Javascript app.
  • To preserve backwards compatibility, however, the code is cross-compiled into standard javascript, allowing it to run on most modern browsers.
So if I stop there, what's your guess? If you've been keeping up with these things I bet you're probably thinking asm.js, which is a good guess because it meets all the criteria up above. Let me add one more hint, though:
  • When announced this technology was regarded with skepticism and vocal opposition.
Ah, that makes a difference. What's your guess now?

"What is Dart, Alex?"

Bingo! We have a winner!

Wednesday, June 5, 2013

WebGL Draft Extensions in Chrome

I mentioned this was coming in my last post, but it's a significant enough change that it's worth addressing on it's own. New Chrome builds, starting with today's Canary build, will begin including a new option in about:flags called "Enable WebGL draft extensions"


(This can also be activated via the command line with the --enable-webgl-draft-extensions flag)

When you enable this it will allow WebGL to access extensions that Chrome has implemented but are still in draft status on the WebGL Extension Registry. Previously these extensions would have been exposed without the flag, but with a "WEBKIT_" prefix. That goes against Blink's policy of avoiding vendor prefixes wherever possible, however, hence the new flag.

The only extension this flag exposes currently is the newly implemented EXT_frag_depth, and any extensions that you previously queried using a prefix will continue to work just fine. 

So what does this mean for you, daring WebGL developers? 

Wednesday, May 29, 2013

How Blink has affected WebGL?

One of the topics that was suggested when I recently took a poll on Twitter/G+ of potential blogging topics was what kind of impact the switch to Blink has had on Chrome's WebGL implementation. I thought this would be a great area to talk about, because it allows me to dig into the guts of how WebGL works a bit more than most of you are used to.
If you're not familiar with the situation already, Chrome recently switched rendering engines from WebKit to Blink, which is based off the WebKit source. The fact that we're so early in the life of Blink means that the two rendering engines haven't diverged too much yet, aside from dead-code cleanup on both ends, but even this early there are a few changes in how Chrome handles WebGL.

Wednesday, May 22, 2013

How Microsoft could possibly, just maybe, become WebGL's biggest supporter

Ready to jump head-first into wild speculation land? Come on, it'll be fun!

It occurred to me today that there's a slim possibility that in the near future Microsoft may actually become the biggest driver of WebGL adoption in the industry. Yes, that's right, "WebGL considered harmful" Microsoft. Sounds crazy (probably is crazy) but I feel the possibility is definitely non-zero. Why? Let's string together a series of massive assumptions, shall we?