Monday, December 20, 2010

Tron: Legacy (super short!) review-ish

Just got back from Tron: Legacy. It was, well, Tron. Very pretty with a very silly back story. I enjoyed it, but more for geek factor than anything else.

There was one MAJOR letdown though, and that's that the film makers had the chance to include the most epic XKCD inside joke EVER and they totally blew it! Shame on you!

Wednesday, November 17, 2010

I'm not dead yet!

Just wanted to drop in and leave a quick note to say that I haven't abandoned the blog, and I actually have a fun little project under way! Unfortunately I don't want to talk about it much at the moment, since I feel like this is something that could actually be marketable (probably via the Apple App store/Android Market). I'm also considering submitting it in it's web-based form to the Mozilla Game On competition. But that depends on how quickly and how well I can polish it up.

In any case, it is a game and I'm developing/prototyping it using HTML 5 tech like Canvas (no WebGL this time around, sorry!), Audio tags, and WebSockets. Great fodder for blog posts, but once again I would very much like to have a more complete version before I go chatting it up. Expect some updates in the next few weeks though! Even if I'm not talking about the game itself I'll probably want to talk about my experiences with the HTML 5 stuff. (I feel a rage post about the Audio tag brewing as we speak...)

Till then!

Tuesday, October 19, 2010

"The Social Network" Review-ish

So I had a chance to see "The Social Network" the other day. I'll admit that it wasn't a movie that I was really intent on seeing but a Hollywood blockbuster about (of all things) a programmer/website struck me as an odd little beast, so I was somewhat intrigued.

Now that I've seen it I think that It's probably worth at least one viewing by every individual who has ever built a piece of software. That's not because I really liked the movie, though. True, I found it to be an entertaining (albeit highly fictionalized) tale, and the actors do an admirable job portraying their overblown characters. I wasn't a big fan of the way they tried to portray the whole thing as this wild "sex, drugs, and rock and roll" lifestyle, though. I'm sure that there are programmers out there who live like that, or at least want to, but that's a pretty big disconnect from most of the developers I know. To me that whole aspect of the movie felt heavy handed and overdone and as a result it was probably a one-time viewing for me. So while I thought it was a good flick it certainly wasn't my favorite. (I'd easily go see Inception 3 more times before before bothering with this one again).

Anyway, the thing that really struck me about the movie, the thing I think is important about it, is that it is the first movie that I have EVER seen that actually portrays programming/hacking/development almost completely accurately. There's a fascinating monolog at the beginning of the show in which Zuckerberg (the screen version, anyway) narrates some of the steps he's going through to collect pictures for a prank website that he's building. It's a fairly lengthy scene, and shockingly doesn't try to gloss over the technical bits. It's packed with terms like "apache server" and "wget" and "bash shell" and all sorts of authentication odds and ends, and every single one of them is used in the correct context! This type of portrayal continues throughout the movie: Every single computer screen displays real OSes, real sites, and real code running on real hardware (the OSes are even date-appropriate!) They talk about real languages and real algorithms and generally act like real programmers. What a concept!

Of course, a lot of this is just incidental stuff and most of it is done rapidly enough that audience members who don't know their Perl from their Python will simply pass it off as techno-babble and still be able to focus on the story. But for an industry that has long portrayed "hackers" as semi-mystical beings who mash random keys while staring at psychedelic screens and suddenly have access to anything the very grounded and realistic approach taken here is very surprising and refreshing. It's worth a viewing if only for that: to bear witness to the day that Hollywood recognized that programmers were real people.

One final recommendation for the show: The soundtrack is great, and makes for (ironically) great music to code by. But, hey! It's Trent Reznor! Would you honestly expect anything else?

Wednesday, September 29, 2010

Itty Bitty WebGL

File this one under "Cool but useless"

I stumbled across js1k.com yesterday and was quite amused by the concept: Use 1024 bytes or less of javascript in a minimalistic shell page to create a cool demo. The contest is over now, and browsing through the winning entries is surprising and somewhat awe inspiring. They managed to get a full Chess AI and graphics in 1k of javascript?!? Awesome! It also got me thinking: None of the demos used WebGL (primarily for compatibility reasons. The rules state that demos must work in Safari, Chrome, Firefox, and Opera), but were the standard further along, how much COULD you do with a 1k WebGL app? I decided to find out!

Friday, September 24, 2010

Raytracing in Javascript

So I've been pretty quiet lately, but not for lack of activity on my part. I'm in one of those funny stages right now where I've got about a thousand ideas I want to try and things I want to learn and not enough time to pull any of them off properly. So I experiment, whip up several dozen cool little proof-of-concept programs, and move on to the next idea. This kind of "brain dump into code" mode is pretty fun, but has the severe downside that none of your projects reach a point where their worth actually showing to anyone else. Recognizing that my blog has been sorely neglected as of late I determined that I would bring at least ONE of my playthings to a semi-showable state and post it, and it so happens that my raytracer was the closest to being presentable. :)


Yes, it's a browser demo (but not a WebGL one, sorry!) It's a Monte Carlo tracer, which means that the image starts out really ugly and gets better as more passes are applied. (Let it sit longer and it becomes prettier.) The image above is the result of letting it sit for 400 passes, and even then you can see a fair bit of noise. It's a very slow way of going about it, but it can produce spectacular results under the right conditions (and, you know, when you're not relying on Javascript to do it...)

Okay, so admittedly this is probably the least impressive demo I've done so far. It's your standard old boring Cornell box, and not even a really cool one at that because it lacks a refractive (glass) sphere. (More on that in a bit). There's a whole bunch of things "wrong" with it, and I may be tempted to come back and update it at some point, but the point of the thing was that I wanted to learn more about raytracing, and this little guy has served that purpose admirably.

A few fun "techy" notes: This started life as a Python port of smallpt, which I eventually gave up on when I realized that the GIL makes threading for this type of thing pretty useless. So I ported my port to Javascript (wait, aren't we moving backwards here?) mostly so I could use Web Workers, but it has a nice side effect of letting me demo it online. :)

The demo uses 4 web workers (though it's super easy to scale to more or less), each of which renders their own jittered version of the full scene. All passes are then send back to the main thread and composited into the final image. I'm actually passing the image data back and forth in an ImageData object, which means that some browsers may not support this yet. It also means that there's the potential for some pretty severe precision loss, since all of the color values are compressed into a 0-255 range, sent to the main thread, and blended with the main image, which does another 0-255 compression. It would be far better to store and composite all of the color components as floats (or doubles, but Javascript doesn't give you the option. It falls somewhere in between), and copy those values over to the image after compositing. I tried this at one point, but the Web Workers kept dying and spitting out a strange "Not enough arguments" message. This is apparently a Chrome bug, but I have no idea how to get around it.

I also eventually dropped the idea of having a refractive sphere, simply because after many MANY iterations I still end up with either a black ball or a clear ball with an ugly black ring around the edges. You can still see the material class for it in the worker script, and if anyone wants to point out where I'm being stupid be my guest!

Anyway, as unimpressive as it is I did have a lot of fun putting this together, and hopefully someone out there at least finds it mildly interesting! For now, though I'm moving on to my next project, which may or may not be any one of the following: (haven't decided yet)

  • A WebGL accelerated version of this demo, to compare speeds
  • A SketchUp to JSON exporter for quick prototyping of WebGL scenes
  • An OpenGL ES 2.0 demo on Android (very tempting)
  • A WebGL Material system
  • Or possible something completely different! I have a bit of an itch to do something non-graphical for a bit, just to shake things up.
I've also got a couple of blog entries I want to do about some subjects I've found interesting lately, so hopefully there won't be as long of a gap before my next post.

Sunday, August 29, 2010

Setting up an OpenGL ES 2.0 dev environment for Android (The horror!)

It is a well known phenomenon that if you give a software developer (a REAL developer) any device which contains a CPU (and even a great many that don't) you will also install in them a great and uncontrollable urge to put their own programs on the damn thing. This urge cannot be satisfied by any old "Hello World" app either, oh no. It has to be something significant. Something that uses the device in a non-trivial way. Something that makes your peers say "Woah!" (The "Woah" factor is incredibly important, ask anyone.)


As such, being a developer and recently coming to posses a shiny new smartphone I've been dying to do some code for it for a while now. Finishing up some of my WebGL stuff and keeping up with my normal work (you know, the one that actually pays me) has prevented me from acting on it so far, and I still may not get a chance to code for it for a little while, but I finally had enough time lately to sit down and actually set up the SDK and play with some of the examples.


Saturday, August 28, 2010

Communication across language barriers

Had a neat experience while out walking my dog today. We came across a very kindly and very lost elderly Hispanic gentleman that flagged us down to ask for help. Since the first thing out of his mouth was "I no speak-a English very good." I was concerned that I would be fairly useless with whatever problem he was having. (Two years of Jr. High Spanish and all I can say fluently is "I don't speak Spanish".) Luckily, however, he was able to point to an address scrawled on a bus schedule and indicate that he was trying to reach that location. I knew where the address was, and fortunately he wasn't more than a couple of blocks off, but I was somewhat at a loss for how to communicate directions to him outside of vague hand gestures.

Then, in a moment of fleeting intelligence, I recalled the trusty little Android phone in my pocket that I had been listening to music on. Pulling it out, in under a minute I was able to call up Google Maps, punch in the address, have it map out the directions, and show this gentleman the results. Even though the map was in English a big blue line guiding you from where you are now to where you want to be is pretty universal. After studying the map for a moment a look of understanding and relief swept over him. He thanked me several times, a sentiment that I had no problem understanding, and headed off to his destination no longer lost and much happier for it.

For my part I was left with a mix of the warm fuzzies you get from helping another human being and wonder that we live in a day and age where I can hold in my pocket a tool that can completely transcend language and cultural differences and allow me to help someone in need. I don't care who you are, that's just cool!

As a programmer it's very easy for me (and, I think, others of my profession) to loose sight of why we surround ourselves with all this technology. We can easily fall into the trap of pursuing technology for the sake of technology. (I'm certainly guilty of that.) It's worth reminding ourselves once in a while that all of these spectacular devices and innovations are really there to serve one singular purpose: To make our lives better in some little way. Whether it does that by making some task a little easier, bringing us the information we need, making us safer, or just providing a few moments of entertainment, it's all in the name of improving our day to day existence. If we keep that in mind, magical things can happen.

Thursday, August 26, 2010

Random WebGL related gunk

There's a few things I've come across in the last few days that I feel are worth pointing out to the WebGL community:

  • Newer builds of Firefox have started validating the textures passed to generateMipmaps according to the OpenGL ES 2.0 spec. This means that attempting to generate mipmaps with non-power-of-two textures will start failing on you very soon! Please update you code/resources accordingly. (This already bit me with my Quake demos, which have now been tweaked accordingly.)
  • WebGL___Array types are going, going, gone! Newer browser builds don't even have them defined, so make sure you are using the appropriate analogs from the Typed Arrays. Again, my demos have been updated to account for this.
  • In an odd twist, whereas Firefox has been speeding up lately apparently Chrome is cracking down on crazy fast loops now. With the latest dev releases (7.xx) I've noticed that my Quake 3 demo is basically locked at 30fps, regardless of whether or not you check "Cap FPS". Curiously, this does not seem to be the case for my Quake 2 demo, which means that Chrome is actually limiting the internal message pump. Granted, it's a very stable 30fps, and I'd rather have a lower but stable framerate than a high but erratic one, so I'm not complaining. It did strike me as an interesting change, though. A bit of background on this one: For the Quake 3 demo in order to get the best framerates possible I used a hack picked up from Vladimir Vukicevic that continually posts messages to the page as a signal to draw (demo), which attempts to avoid some of the resolution limitations of setTimeout/Interval. This apparently causes severe performance issues if allowed to run rampant, however (as commenters on this site have pointed out) and so it's possible that this apparent capping may be Google trying to prevent abuse of the system. (Which is probably a good thing!) I'd love to know a bit more about the actual changes that took place in this regard, but in the end it appears that the timer-based method is the better way to go.
  • Finally, in a bit of news that has nothing to do with WebGL whatsoever, I find this to be supremely amusing. Chrome envy, perhaps? :) It's especially funny in light of some Google-bashing that Microsoft did a few months back about how a single address/search bar was a bad thing for users privacy.

Tuesday, August 24, 2010

Firefox 4 beta 4 - Hardware Acceleration FTW!

I just wanted to jot down a quick note about something that made me VERY happy today! Firefox 4 beta 4 was released today, and one of the big features that it includes is (On Windows Vista/7 anyway) hardware acceleration via Direct2D. It's disabled by default, but doesn't take much to turn on (and certainly shouldn't be a problem for anyone who's been following WebGL).

First off, let me say that text rendering looks 1000% better when hardware acceleration is enabled. Seriously! I'm usually not one to care about aliasing in my text and whatnot but... WOW! The really exciting bit for me, though, was booting up my Quake 3 demo. With acceleration turned off I'm getting about 20-23 FPS (on par with previous betas), but with acceleration enabled I'm seeing 60-70 FPS! OMGWTFBBQ!?!

A 300% bump in render performance? That's insane! Awesome, but insane! Great work, Firefox crew! I can't wait to get this out of beta and into the average users hands.

(And now Chrome needs to get with the program! Seriously, looking at text in any other browser is gonna bug the crap out of me now!)

UPDATE: Ask and it shall be given, I suppose? I've turned the associated flag on, but can't see any difference in performance due to the apparent message pump cap I mentioned in a newer post. I'll see if I can find some better way of performance testing this later.

Spring (er.. late Summer?) Cleaning

As a heads up, some of my older demos (well, basically everything but the Quake 3 demo) are probably broken on newer browser builds at this point due to changes in the WebGL's API. (Hey, that's what you get for developing against experimental libraries!) Over the next couple of days I'm going to go back and fix them up (may even try to optimize the code a bit), so hopefully everything should be working again soon.

Until then, sorry for any broken code you may stumble across!

Update: So I've got all of the demos to stop throwing errors, but the Spore and Hellknight demo's aren't showing anything, even though they appear to load correctly. I'll continue looking into it, but in the meantime at least the Quake 2 and 3 demo's are running fine.

Saturday, August 21, 2010

Droid X Android 2.2 (FroYo) Micro-review

So anyone patiently waiting for Motorola to release Android 2.2 for the Droid X has probably heard by now that an official build of it was leaked and can be installed on any X, rooter or otherwise. I was personally quite excited by this news, since I had been looking forward to the new release to see if it addressed some of the software shortcomings that I had found in the phone. As such, it took me all of about half an hour after I found out about the leak before I was running 2.2! (Disclamer.... voided warranty... not supported... blah blah blah...)

Now, before I continue I should note that there is a chance that this is not the final update that will be released OTA. That said, I doubt that Motorola is planning on making any major changes if they still intend to hit an early September release.

If you want to skip my earlier review essentially I think that the X is a beautiful piece of hardware that is badly hampered by Motorola's terrible software. (MotoBlur, uninstallable services, etc.) So as much as I doubted it I kept a little spark of hope alive deep down in my heart that Motorola would hear the impassioned cries of their faithful userbase and use the 2.2 update as an opportunity to strip away the bloatware that we all hate so much (or at least give power users a way to do so).

Saturday, August 14, 2010

Rendering Quake 3 maps with WebGL: Tech talk

So, I promised I would talk more about the the development side of the Quake 3 demo and I'm here to deliver. Warning! This is going to be somewhat long and technical, so steer clear if you're just here for the shiny graphics!


So first off, why Quake 3? After all, CopperLicht has already been there and done that, and I think many people won't recognize this as much of a step up from the Quake 2 demo I already did. Not to mention that along with my Doom 3 model loader this is my 3rd id-related demo in a row, which may seem a bit boring to some people.


For me it mostly comes down to what I wanted to achieve personally. Thus far each of my demos have had been the result of a specific goal on my part: My Spore demo was just to familiarize myself with WebGL. The Hellknight model was to toy around with animation and game-oriented file formats. The Quake 2 demo was a (somewhat failed) stab at large scenes that the user could navigate. I had intended next to move on to some special effects (I still want to try Megatexture-style streaming, for example), but the problems with the Quake 2 demo left me itching for some closure. So I redirected my efforts and decided that I wanted to do a project that created a "real world" game environment in WebGL. Something that looked and acted like an actual game, running at framerates that would actually be considered playable, without "dumbing it down" for the browser. Partially for the challenge, and partially to demonstrate that yes, WebGL is (or at least will be when released fully) a viable platform for game development.



Monday, August 9, 2010

Rendering Quake 3 maps with WebGL: Demo

So, after a good long delay it's finally WebGL demo time again! This one is pretty elaborate, but I feel like it was worth the effort:

WebGL Quake 3 - Q3TOURNEY2

A quick note: I've heard reports that Chrome 5 has trouble with the demo because I'm using the newer texImage2d signature. Your mileage may vary, but if you're having trouble give it a try with the Chrome dev channel.

Now, there are SOOO many things to talk about in regards to this demo: Optimizations, remaining issues, changes made to resources for web use, etc. Unfortunately I don't have the time to elaborate on them right now but I wanted to get the demo out there ASAP to get some feedback on it. Expect another post (or maybe an addendum to this one) within the next couple of days about my thoughts on Quake 3 bsp maps under WebGL.

(UPDATE: My ramblings about the demo are online now)

Have fun!

EDIT: Quick update. I've tweaked the code a little bit to reflect gero3's suggestion of combining the multiple event loops into one. It worked pretty well, and the movement in particular feels better for it (well, not the mouselook. Not much I can do there though). Not to mention the code now reflects a "traditional" game loop much more.

Wednesday, August 4, 2010

Droid X: First Week Impressions

Things have been a bit quiet on the blog lately, but not for lack of activity on my part! I've been working on a fairly involved WebGL demo that I'm hoping to post soon (I'd like to get it out by Aug. 12...) that I feel is pretty dang awesome. Hopefully the rest of the interwebs will feel the same. :)

For the moment, though, I want to talk about something non-WebGL. I bought a new phone last week after my EnV Touch started randomly powering off... again. (For the record in the last two years I have cycled through 6 EnV phones: 3 EnV 2s and 3 EnV Touches. ALL of them had power issues within about 4 months or so of receiving a replacement phone. Don't get phones from the EnV line. Ever.) This time I decided to make the jump to smartphone land, and since Apple has yet to dump AT&T (and since I like to, you know, HOLD my phone) I went with the Android powered Droid X. I will admit that it was a close race between that and the HTC Incredible, though. Better battery life on the X won me over in the end.

Well, I've had it for about a week now and thought I would do a brain dump of my initial impressions of the device. Please keep in mind that this is the first Android device that I've owned or even used extensively, and as such I'm not 100% certain of where the line is between stock Android and the Droid X's software.


Thursday, July 15, 2010

More pardonings of continued dust, if you please...

I'm going to be doing some more server shuffling over the next day or so, so I apologize if things are a bit up and down again. I'm working on it!


EDIT: Sorry for the downtime. I'm having some annoying issues getting my DNS entries sorted. In the meantime I've got tojicode.com redirecting to my blogspot address so everyone should at least be able to continue seeing the blog while I try and get a more elegant solution going.


EDITING THE EDIT: Alright, so it looks like the current configuration is stable so I'm sticking to it. blog.tojicode.com is going to be the official address, and for the time being tojicode.com will redirect to it. 

Wednesday, July 14, 2010

Obsolete texImage2D... Wha?

I've seen a couple of people around the web mention that with newer versions of WebKit they have begun getting the following warning in their console when running WebGL apps:

Calling obsolete texImage2D(GLenum target, GLint level, HTMLImageElement image)

Calling obsolete texImage2D(GLenum target, GLint level, HTMLImageElement image, GLboolean flipY, GLboolean premultiplyAlpha)



Things still work this way but obviously having the browser barf out a bunch of warnings is less than desirable. Fortunately a bright guy at http://darkhorse2.0spec.com/ (site is in Japanese) did some digging through Webkit's code and found the "right" definitions, which he lists. For me, I was able to get the errors to go away by changing my code from:


gl.texImage2D(gl.TEXTURE_2D, 0, image, true);

to:

gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image);


And yes, that works with Minefield too. (Well, technically Firefox 4 beta 1) Of course, this probably only works for me because I happen to know that all the images I'm loading are 32bit PNG's. I imagine that telling it the image is RGBA if you were using a JPEG may not work so well (I'll have to try that sometime soon), so your mileage may vary.

Wednesday, July 7, 2010

Why is there bacon in the soap!?

Just need to vent for 2 seconds: Can someone out there explain to me the logic behind not allowing Float32Arrays (or any other Typed Arrays for that matter) in Web Workers? Seriously?!? (And no, I'm not trying to fill GL buffers in a worker, I'm using them for binary file parsing.) Please at least tell me that this is in the works!

Sunday, July 4, 2010

WebGL's greatest challenge as a gaming platform

[UPDATE: I noticed this post still gets a decent amount of traffic, so I figured it's worth pointing out that it's hopelessly out of date at this point. Microsoft supports WebGL now (mostly), JS is faster all the time and we have asm.js now to boot, and browser have largely embraced fullscreen, pointer lock, gamepad, and camera APIs. So, yeah... don't reference this post for anything. Ever.

Post is preserved here simply for the sake of mocking my (lack of) predictive powers.] 

This may come as a surprise to some of you, but I'm rather fond of WebGL. :) And if you've been following some of my demos you'll probably notice that they tend to have a somewhat game-oriented tilt to them. This is fairly natural for me, since I'm both a gamer and a programmer. It's two passions in one sweet package, kinda like a Reeses Peanut Butter cup.

Anyway, I'm a firm believer that as it matures WebGL will play a big part in game development, just as the web has already altered the game industry. I doubt that we'll ever reach a point that browser based games take over entirely, but they're going to keep getting bigger and better and the lines between desktop and browser games are going to blur. Some people will embrace this, some will fight it, and if nothing else it will be an interesting ride for everyone involved.

There are some key limitations, however, that need to be overcome before WebGL (and the browser as a whole) can really truly be considered a full fledged, general purpose gaming platform. And those issues are going to be hard to solve. Incredibly hard, for both technical and theological reasons. So hard, in fact, I'm not sure that the minds behind the web today are able to fix them, or even that they want to. In fact, I'm not convinced that they should.

Friday, July 2, 2010

glMatrix 0.9.4 (1.0 RC1) Released

I've just finished posting a new version of glMatrix (you know, that really fast javascript matrix library?) to Google code. The release number is 0.9.4 but I would like to treat it as a Release Candidate for 1.0.

I get the impression that some people may be disappointed by this release since for me it was more about house cleaning and documentation than any big new features or optimizations. A good deal of the issues I'm getting back for the library now are stylistic preferences, though, that involve restructuring or renaming the functions of the library to work or read a certain way. Some of these items I think are valid and some I feel are more a matter of personal preference, but in all cases I've decided that I would rather:

A) Get the library to a stable state
B) Get unit tests (a personal requirement before I can call the lib version 1.0) and better documentation in place
C) Get the library out to a wider range of developers and gather more feedback

before I make any big structural changes. Please don't consider this to be a rejection of any specific ideas that have been posted, I simply feel that the library structure is "good enough" for the time being and would like to let it mature a bit before shaking things up in a version 2.0.

That said I'd love to get any and all feedback on the library in it's current state so I can officially move it to a 1.0!

Finally, a Big Huge Thank You to everyone who has pitched in so far! Specifically:

jeroom832, Daniel Heres, Julian Walker, Denis Rangel, Aaku Kokko, and Drew Whitehouse

(And I'm terribly sorry if I missed anyone or misspelled any names!)

Friday, June 25, 2010

Quake 2 BSP - Quite possibly the worst format for WebGL ever

So, as hinted at by my last post lately I've been working on a Quake 2 map viewer for WebGL. I'm not as far along with it as I would have liked, but I've decided to stop developing it and move on to other formats/pursuits for various reasons that I'll get into in a bit. I'm sure the majority of you are here just to see the pretty demo, though, so without further ado:

Quake 2 BSP WebGL Demo

(Linkified because trying to scrunch the viewport into the blog would make it difficult to use.)

It's certainly not perfect, but hopefully you guys like it. I would be thrilled to see someone expand on what I've done here... oh wait.

So, let's talk about why I've decided to move on from this project. This bit is gonna get rather long and technical so feel free to ignore it if subjects like binary parsing and lightmap calculations make your eyes glaze over.

Sunday, June 20, 2010

Coming up...

So I've been a bit quiet on the blog lately, primarily because my next WebGL plaything is a bigger project than the others I've taken on so far and has undergone a couple of false starts. Just to prove I'm still working on something, though, here's a teaser:




Not sure when I'll be at a point where I want to post the live version. It's pretty sloppy at the moment. Should be a pretty cool demo when it's done, though!

In other news, I've noticed lately that my Spore and MD5 demo's don't seem to be rendering correctly for me when I view them on this site. It seems as though the normal maps aren't being applied (makes it look like the light is always behind the model). I'm not sure what that is, but I suspect that it's been a change in Chrome recently. Is anyone else seeing this?

Saturday, June 12, 2010

glMatrix 0.9.2 Released

glMatrix 0.9.2 has just been released. Included are even more optimizations, some new functions (like mat3.toMat4 and mat4.toMat3), and a smattering of quaternion code to boot! (Developed for use in my md5 loader).

If you've been using the library, or simply want stupidly fast javascript matrices, be sure to grab the latest version!

Friday, June 11, 2010

It's Alive!!! idTech4 models with skinning.

So, not content to just show a static Spore creature I decided that my next project in WebGL was going to be something a bit more dynamic. After a little bit of toying around, I decided to give the MD5 mesh format (Doom 3, Quake 4, etc.) a try. I think it turned out pretty well...

Click here to run

(I hope Mr. Carmack and company don't mind me using one of their models to demo with. If anyone should take issue with it I'll remove that model and swap it out for another, but you've got to admit that seeing a Hellknight chilling out in a browser is pretty cool!)

[EDIT: Interleaved arrays have been fixed in the latest Minefield releases, which allows the demo to run correctly.]
As of right now I've confirmed that the above demo runs with Chrome, but not Minefield. I'm pretty certain it's because I'm using interleaved arrays, which is still horribly broken in Mozillas implementation last I heard. Your mileage may vary, and in any case I should have a more compatible version up in the next day or so.

I've worked with the format before, so I knew how it was laid out reasonably well and (crucially) I knew that the format was plain text. One of the biggest drawbacks to WebGL (and web development in general) is a near complete lack of ways to efficiently work with binary data outside of a select few media types. I must say, though, even given that the files were text based the actual parsing was far easier and faster than I expected. Certainly the file size and loading speed blows COLLADA out of the water. Guess that just a happy side effect of using a format intended for realtime rendering!

Of course, there are a few things that I know could be done better/faster that I might want to tackle in the future (and would love to hear about if anyone else improves on my methods!):

  • Material loading is a huge, ugly hack right now. Problem is that I can't figure out a happy method of loading the actual material definitions used by the game in a web-friendly way. So for the time being the loader simply looks for 'shader-name.png', 'shader-name_s.png', and 'shader-name_local.png' for the diffuse, specular, and normal maps respectively. It also ignores any special effects (hence the odd looking drool)
  • Skinning is done on the CPU right now, but I would like to try GPU skinning and see if there are any performance gains. In all honesty, though, the format isn't intended for GPU skinning and I'm quite pleased with the speed of the javascript based animations, so I'm not sure how necessary that is.
  • I'm not interpolating between frames at the moment. Playback is at 24 FPS, defined by the animation file. Certainly it would be nice to smooth that out a bit but I'm worried that the extra overhead would murder the framerates. It's worth playing with though.
  • I'm not 100% confident in my skinning methods of the normals and tangents. The results look correct enough, but may fall apart with more extreme movement. Also, I'm not taking mirrored uv's into account when calculating tangents (I think the models are built to account for this, but I could be wrong) and I'm ignoring texture seams when calculating the normals which leads to some sharper-than-I-would-like normal differences.
  • I'm hauling around a lot of unnecessary information after the initial load, and as such memory use could be much better.
  • Animating two independent instances of a mesh would require some changes as well, but wouldn't be too difficult.
Aside from those complaints, though, the library is reasonably fast and robust and should work with most of the MD5 meshes out there (something that certainly cannot be said about my COLLADA loader). It requires my glMatrix library, but is otherwise standalone.

I'd love to hear any comments or suggestions for improvement, and if anyone else builds something cool on top of the loader please let me know!

Pardon our dust...

I'm in the process of shuffling servers and changing domain names right now, so I apologize if anything weird happens over the next day or so. Everything should be fine soon, though!

Wednesday, June 2, 2010

Stupidly fast WebGL Matrices

I've made a matrix library for WebGL. It's fast. Really fast. It's linked right here: glMatrix
[EDIT: And just been updated! Now even faster!]

And, lest some scoff at my claims of fastness, I've also made a benchmark: glMatrix Benchmark

Don't bother with that last link if you're browser doesn't have WebGL enabled. None of the comparison libraries really work without it. (Though glMatrix will function with any javascript sequence.)

Okay, so let's get a little more serious. Why in the world would I want to make yet another matrix library when there are already a good selection of them?  That's a tough one, especially because I'm a very firm believer in not reinventing any wheels. What it really comes down to is this: I tried all the other matrix libraries I could find and didn't feel like any of them were meeting my needs.
  • Sylvester is a very nice and robust library that I've seen some people using with WebGL, and I can't really blame them. It's probably the most complete one that I've seen, and is aimed at people doing heavy duty math in their browser. The biggest problem with it is simply that Sylvester was built for robustness, not speed, and as such is ill suited for realtime graphics.
  • Khronos recommends using CanvasMatrix in their introductory tutorial. It's apparently from Apple (according to the comment at the top), and has a nice interface, but once again isn't really built with an eye towards performance.
  • mjs was built to be far more speed conscious, and it shows. Done by the guy who did the original Spore WebGL demo, it's a nice little library and it's what I've been using so far. I only have a few complaints with it: I'm not a huge fan of the syntax ('M4X4' is awkward to type over and over again), and you end up creating a lot of temporary matrices to store intermediate values in (passing a single matrix as both the source and result matrix can corrupt the value). There's also some odd bits of missing functionality (like a full, generic inverse) that may or may not be a problem. Still, it's very workable.
  • EWGL Matrices appear to be the latest of the bunch, and the idea behind them was very specifically to be extremely fast. To that end they did a great job, but there were still a couple of things that I was annoyed by. All operations take place on the source matrix, which can lead to some unnecessary duplications in certain scenarios. (Basically the inverse of mjs's problem) And it's object oriented nature tends to force you to use, for example, their vector types when passing translation or axis data, which I find somewhat cumbersome.
Now, all of these complaints are, in reality, quite petty. If that were the extent of it I'd just use one of the latter two and be done with it. But there was one feature that was missing from all of them (except Sylvester, which doesn't count for speed reasons) that killed it for me: none of them had facilities to multiply a vector by a matrix! To me that seems like a rather obvious one, because while certainly in an environment like WebGL we want to let the GPU do as much work as possible there's some times where you simply want to rotate a point in memory.

So, of course, noticing a small deficiency in the existing options I did what any normal programmer would do: Wrote my own. :) 

There were a few key things I was aiming for when I wrote it:
  • The interface needed to be clean and consistent
  • Operations needed to be able to happen in-place OR written out to a destination array, leaving the original untouched.
  • The library should not lock you into using a certain type or set of classes. (ie: It should work just as easily with Arrays as WebGLFloatArrays)
  • And for crying out loud it needs to be able to transform vectors!
Believe it or not, speed was a completely secondary concern while building it. Once I got all my desired functionality in there and started doing some benchmarks, however, I realized that I wasn't too far off from the faster existing libraries. So I spent another evening optimizing the crap out of it to make my little matrix library "stupidly fast". A few key optimizations were:
  • Unroll EVERYTHING. There's not a single loop in the code.
  • Take advantage of javascript's variable caching. If a matrix element was read more than once in any function it was stored in a local variable first. I was honestly surprised at just how much of a difference this one made!
  • Inline anything that made sense. ie: Although I have a vector normalize function, I did an inlined version in the matrix inverse to cut down on call overhead and additional variable creation.
  • Take shortcuts when possible! If the source and destination matrix for a transpose are the same, we don't need to alter the elements on the diagonal. Or when rotating if we notice that it's along the X, Y, or Z axis we can cut out a lot of calculations that would just end up as 0 anyway.
And the end result is that glMatrix outperforms even EWGL in every scenario I've tested! No small feat!

Of course, "stupidly fast" is probably pushing it. After all, this is Javascript we're talking about. Even the most naive of C matrix libs would run circles around the best javascript libs. But when it comes to WebGL we really don't have much of a choice now do we? At the very least I feel confident in saying that this library is one of the fastest (if not THE fastest) javascript matrix libs available today.

This being a first release, I fully expect a few bugs here and there and welcome any feedback on how to improve things. But hopefully it can serve as a meaningful contribution to the WebGL development scene.

Happy coding!

Sunday, May 30, 2010

Gish is open sourced

The greatest performance improvement of all is when a system goes from not-working to working.
-- John Ousterhout
 

Today Cryptic Sea released the source code to Gish after pledging to do so for the Humble Indie Bundle. This is, in a word, frigging awesome!

Wait, that's two words... but that's okay because that's how cool it is!

For those of you unaware (which is to your detriment, I assure you!) Gish is a brilliant little indie platforming game involving a ball of tar, some really weird enemies, a glitchy physics engine, and some really simple multiplayer. That may not sound like much, but this game has actually gotten my friends and I kicked out of a LAN party before because we were laughing too hard. (True story! Embarrassing corollary: the LAN party was hosted at my house. The kicking was done by my wife.) It's available on Steam, and is worth whatever price they're asking at the moment.

At the very least you should check out the trailer.

Now, that's all well and good but what I actually wanted to talk about was the source code. It doesn't take long after beginning to browse through the code to see that the quality of the code is, frankly, atrocious. Magic numbers everywhere, very little in the way of abstraction, little to no comments. In short, it's everything that your CS teacher would have flunked you for.

And this is a good thing!

Why? Primarily because I think that there are a lot of very capable developers out there who will never, ever finish a personal project of this magnitude because we get too caught up in the structure of it all. After all, what use is a graphics engine if it doesn't have a completely abstracted, plugin capable shader system with a graphical designer, right? I've seen indie projects fail time and time again because the developers behind them spent an awful lot of time carefully constructing an "engine" but very little time actually making, you know, a game. Seriously, the Gamedev.net forums are full of 'em! It's kinda sad.

Which is why I think that the Gish code is great. Because it's a project that got finished! Who cares if the code sucks, it's making it's creators money right now. It's being played by gamers right now! How many indie developers can really say that?

So often the code we interact with takes the form of either:

A) A library, whose interface was agonized over and revised by multiple contributors to ensure that it's usable in the most abstract of scenarios or...

B) Some large, popular project like Quake 3 that gets open sourced after years of use by AAA studios that have beat it into shape, and was designed to be reusable from the get go anyway.

And sure, these projects have their quirks and oddities and funny variable names, but they still represent something that is reasonably polished, mostly reusable, and carefully prepped for consumption by others. That can taint our perception of what all code should look like.

The Gish code has very little of that. The creators essentially plucked the code off their hard drive and dropped it in our laps. Not much there in the way of polish. It does one thing and one thing only: Gish. It's not always pretty how it does it, either. But it works, and it shipped. And that is the single most important milestone that any chunk of code can ever attain. Everything else is just a bonus. Gish illustrates that beautifully by allowing itself to be ugly.

Now, am I saying to throw good design to the wind? No, not in the slightest. If nothing else it can save you a great deal of heartache if three months down the road you suddenly decide that gravity needs to be just a smidge stronger and you had the foresight to define it in a constant instead of using magic numbers everywhere. But we should never, EVER allow an overabundance of design to become a roadblock to the finished product.

Thursday, May 27, 2010

WebGL and Spore Critters

You know what's really lame? Blogs that have one post from two years ago that says: "Hi! I'm _____ and this is my blog and I'm gonna post on it every day!" Well, I'm bound and determined to make sure this blog isn't one of those. To that end, I've decided that if I do lose interest after one post, I may as well make it a good one. So... WebGL!

I've been on an HTML 5 kick recently. (I find that funny because I started out my programming career as a web developer for small internet marketing company. At the time I thought of it as just a stepping stone before I got to do "real code". Now I do "real code" at work every day and I can't wait to go home and play with my HTML!) I don't really care to go into an in-depth analysis of HTML 5 here, there's a billion other sites out there that do that. But one of the cooler bits that has come out of the whole HTML revamp is WebGL. As the name suggests, it's basically just OpenGL in a web page driven by javascript without plugins.

No, wait, I don't think you got that: OpenGL. In a web page. Javascript. No Plugins!

If you don't think that the above idea is awesome, get off my blog! For the rest of you, read on for demonstrations of said awesomeness.

I have a lot of random topics that I want to hit on in the future related to WebGL (performance, matrix libraries, shader organization, etc.) but for the time being you'll have to be content with a little demo. It's based off one of the earlier WebGL demos that appeared online, which displayed a critter exported from Spore in all his unlit, flat textured glory. On the page it mentions that the rendering is omitting the normal mapping and specular information provided with the model and encourages improvements. So I did:

[Update: This was easily the worst demo on the site, and hasn't actually been functioning for well over a year. I've felt it was best to take it down and spare the bandwidth. Sorry!]

Now, for most of you reading this any time near the original posting date, the demo above probably won't work. WebGL is still considered to be very experimental, and is typically disabled by default even if your browser supports it. Try it anyway, since it will point you in the right direction if it can't load properly.

For my version I used next to no code from the original (though I did lift the model, hope no-one minds!). Primarly, the Collada parser was re-written to be a bit more robust and generic (though mine is still extremely limited! Collada is a very complex format.) That said, there are still a great many things I would like to improve, but for the time being it's very fun just to get it up and running.

Enjoy!