3 Years Later: Year Three

This post is drawing to a close my little series on how I went from not knowing the first thing about game development to being a programmer that eats rendering code for breakfast (as all good graphics programmers should). Here are links to my posts about Year 1 and Year 2.

Olympus

After finishing out my second year of college, I spent my Summer working on what would become the longest running project I've ever been a part of. Olympus is a project from the MSU Games for Entertainment and Learning Lab developed to study the effectiveness of exercise in motion games in the context of a game intended primarily for entertainment.

The design was that of an action adventure game set in Greek mythology. It not only required us to support toggling everything from dialog options to whether the game was played with a 360 Controller or a Wii-mote/Dance pad combination for various research groups, but it also demanded that we deal with the problems of maintaining a codebase over the course of a long-term project.

The lessons here were invaluable. There were only ever two main programmers on Olympus at a time, with Shawn Henry Adams and myself moving into those roles as the original two graduated. It very quickly became apparent to us that the code base was riddled with quick fixes, lack of proper tools, and poor software engineering. In other words- it was made by students, and not bad students at that. The fact that students are rarely have to revisit class projects in the future is something that I think should be fully realized when doing a student based project.

I'm not sure when students are supposed to learn the life lessons of the dangers of ignoring an attempt at good software design, but I certainly learned it from Olympus. It was also the most fun I ever had making a game for the GEL lab, working with my coworkers to get through the challenges of developing hours of gameplay and adapting existing, and often messy, systems to new designs. So as a student if you have the chance to work on or take a class that involves a project that lasts at least a semester, don't let it pass you by.

Becoming Nocturnal

When school actually started up, I was enrolled in two classes that changed me forever. One was the portfolio class for the game development track at MSU, and I threw myself into that class like there was no tomorrow. There was not an all-nighter that I wouldn't pull for the sake of my games, and looking back now I'm pretty sure I know why I had that mentality. The number one thing that I've ever heard about getting a job in game development is that a stellar portfolio is essential. Worthwhile? Yes. Although, as I lamented in my last post, a passing grade is not enough incentive to have people create amazing games. For me, feeling like I'm the only one working on a project is a lot more troubling than a difficult technical challenge. I'll always help and vouch for the kids that throw themselves at their work, because with a little direction, they'll always do great things. But in a portfolio class, it was always frustrating to deal with kids that had already let their enthusiasm slide to the point of no longer pursuing game development seriously.

I also took Yiying Tong's graduate level graphics programming class that Fall, and it was perhaps both the greatest and hardest class I've ever taken. There's a different lesson to be learned here than working hard to make a good game: it's worth it to go way over your head in a subject you enjoy. While a lot of it was beyond my comprehending at the time, I've come to learn that not being afraid of material you don't fully understand can help you out in the long run. Maybe the first time or the second time it doesn't make sense, but eventually, it all comes around.

On My Way Out

The Spring of junior year brought along my first serious attempt hunting for a job in the industry beyond Michigan State University's game development research projects. It also brought about the beginning of my writing for AltDev, the beginnings of a stint writing tutorials for Shaders in Unity, and my first semester as a TA for the introductory Game Design course. This was a bit of a tipping point for me and draws my story to a close.

I never had a good gauge for whether or not I was on track to make games professionally after college. When I seriously started teaching others how to make games, and people actually seemed to be improving as a consequence of my effort, I began to realize I was probably doing alright. My hunt for a game development internship landed me at the mighty Iron Galaxy Studios, and maybe someday after what I was working on gets announced I'll talk a little about my experiences as an intern there (spoiler: it was great!), but it certainly reaffirmed my suspicions that I had gone from someone wanting to learn game dev to someone that could competently contribute to a substantial game.

A final word on my efforts to contribute to helping others learn about game development: it's very rewarding. If you find yourself in a position to help others out, seriously consider it, whether it's teaching a class or writing a blog post or even giving a presentation at a local club or IGDA chapter meeting. I know that the reason I enjoy spending so much of my time trying to give back to the game development program at MSU and the development community as a whole is because a younger version of myself would have loved to be on the receiving end of any of the information I've shared. Many people helped me along the way to understanding what I've learned and experienced, it's all I can do to continue that effort now that I'm in their shoes as one of the more experienced individuals at MSU.

3 Years Later: Year Two

This is part two of my little series about what I've done in the past 3 years of my life to take myself from a kid that had never made a 3D game in his life to someone who lives and breathes game programming on several projects (commercial and otherwise). Here's a link to the first post in the series.

Getting Paid to make a Game

During the academic semesters for my first two years of college, I got paid by a scholarship to work for the Games for Entertainment and Learning Lab (an incentive to have first and second year students involved in research labs on campus). However, part of the way through the summer leading up to my second year of college, I got pulled on to a project as a second programmer, and being paid outside of the academic year by the Lab's actual budget was exciting for me. However, the project went anything but smoothly (and had been a mess well before I was brought on).

I've noticed that sometimes game devs talk about getting jaded or disillusioned after getting into game development professionally. If there was ever a project that did it for me it was this one, a serious game about power plant management. It was continually misdirected by a client that didn't understand game design or development. The project got extended into the Fall semester as the development continued to be a mess. Eventually this culminated into the client asking us to add back as many of the features the Lab had attempted to add to make the game more fun, finally realizing that the direction they had been steering it was keeping it from being fun for the target audience.

For as unfortunate as that was, I think something really important came from this, the knowledge that programming, not game design, was what I loved no matter how badly a project was going. Level design in particular came hard for me, realizing that it really just couldn't hold my interest like a programming challenge. I think most people can find a lot of glamour in more than one discipline of game development, and for me I thought that maybe game design was as an enjoyable as coding. Clearly I was wrong, and it proved to me that even a bad project can have a lot of value, giving me a better sense of direction of what I wanted to do moving forward.

Greener Pastures

While the power management game was wrapping up, two much more promising projects were just starting up. One was a competition hosted by Ford Credit between Michigan State University and University of Michigan's game development clubs (Ford is headquartered in Michigan, thus the localness of the competition). The goal was to make an serious/adver game to teach potential Ford customers about car financing. The target audience was people in their early 20's, so having college students make a Flash game seemed like a great way for Ford Credit to go about it and was probably a fun PR stunt at the same time.

While the content of the game might not sound amazing, Ford Credit was very hands off about the development, which was a breath of fresh air compared to the project I was coming off of. The real kicker though was the prize: all expenses covered for GDC with all-access passes. I threw myself into that project like there was no tomorrow, and it ended up being the first project I seriously crunched on as the team streaked towards our relatively aggressive deadline (I believe we had 3 or 4 months of development, and many of us had never done a Flash game before). It wasn't uncommon for me to be up at 2 am rolling in features and artwork that probably should have been cut for scope reasons, and even then I was fixing bugs right up to the deadline. And when I say "right up to," I mean that I did the submission build of the game on a laptop in the back of a van as we drove to present the game to the judges in Dearborn. You can check out the game here.

The result was that we won, and getting to go to sessions at GDC 2010 blew my mind. While I know many devs that have been in the industry go to GDC as much for the socializing as the sessions, as a student I'd say that the talks are infinitely valuable. Especially compared to the Career Pavilion, which I'd wager is what the majority of students attend GDC for. It was also then that I realized that the allure of rendering and engine code was ever so tantalizing, with John Hable's talk about HDR lighting in Uncharted 2 convincing me to drown myself in graphics programming in my spare time. This was a big jump for someone that thought they might still want to be a game designer less than a year earlier.

Lesson here? Student competitions are important, teaching more about deadlines and quality game development than any class could, because to be honest, student projects often are only a fraction of a someone's grade. The project for Ford Credit had that extra mile of polish that can only come from really wanting to make the best game possible. Getting in that extra stretch of polish and bug fixes before a class deadline lacks incentive because it probably won't budge someone's grade unless it's worth at least half the student's grade. I'll be revisiting that theory of mine in my next article.

Enter: Olympus

I mentioned that their were two projects in the wake of the power plant management game. The second one was a motion controlled action adventure about Greek Mythology. The purpose of the game was to be used to study the effectiveness of aggressive motion controls in an entertainment game (as opposed to a game like Wii Fit, where exercise is the consumer's intent).

I started as what I would probably refer to as a "junior programmer" handling basic gameplay tasks while I was still heavily involved in the Ford project and my first class about game design and development. However, I would inherit the role of leading up the player and motion control code when the original programmer graduated, continuing into the summer. I'll pick up on that story in my next post about lessons from my third year of learning game dev.

3 Years Later: Year One

A while back, someone on Twitter (I can't find the original conversation), asked me if I would consider writing up how I learned to program video games. I'm going to split this into several articles (for better or for worse) based around each year, and then one wrapping everything up with a big dump of the tools, articles, and books I've found incredibly helpful along the way. I thought splitting them up would be good because I'm only *a little* busy with moving back to Michigan and getting up to full steam on a project for IGF.



I think very few people will disagree that it's a lot harder to get into the games industry than it used to be, being that there are so many more people interested in getting into the industry these days. I've been happily interning for these past months at Iron Galaxy Studios where I do programming work commercial games, so I'd say that I at least got some important bits right. I think a lot of what I've done can manifest itself in a slightly different way for other prospective game developers, so hopefully these are helpful in some way to them.



Year One



When I started college, I knew I wanted to make video games for a living. However, like most college freshmen, I didn't know how to make video games, but I did know that getting into the games industry was no cakewalk. One of my scholarships paid a stipend in exchange for working 10 hours a week under a professor, essentially a way for the university to get underclassmen involved in research without putting strain on a lab's budget. Due to my interest in game development, I joined the MSU Games for Entertainment and Learning (GEL) Lab to work under Professor Brian Winn, but I suppose it was not the most opportune time to be a GEL Lab professorial assistant.



There was very little going on in the lab that year other than a small game design conference that we helped organize called Meaningful Play. However, beyond helping prepare for the conference, there was very little concrete game development work to hand me. Besides the lack of projects, I didn't know a whole lot about game development. I can still remember not having a good answer about what part of developing games I actually liked doing when I first started in the lab. All I knew was that I liked programming in general from the few classes I had in High School, although game design still seemed like "the cool thing" at that point, and I thought that I would probably enjoy design more if I was given the chance (spoiler alert: programming is actually way cooler, but this won't be discovered until year 2).



Contrary to what one might think, something very good came out of the lull of activity in the GEL. My commitment to GEL Lab was for 2 years, so Brian had me begin to teach myself how to use Unity with the hope that I'd be able to use it for future projects, being that the department had just adopted into the curriculum as its 3D engine of choice. As a result I had a conscious reason to teach myself game development, putting in at least 10 hours a week towards a small 3D project. I started with the standard tutorials, which are only really helpful for learning the menu flow. As with any first 3D game, the learning curve still felt steep even though I was using a fairly user-friendly engine like Unity. However, if you get a jolt of excitement from getting a cube to move back and forth across the screen for the first time in your life, then you know that game programming might actually be your thing. The project evolved into a small game that I presented at the end of my Spring semester.



It was an action-adventure game about a manatee. It was terrible, and my code base was even worse, but to this day I still love it (and amazingly its poster presentation won an award). What's important here? I did everything, even the art, and I committed to spend at least a minimum amount of time on it each week. I learned so much, and I didn't have things like fears of letting team members down, because I was the whole team.



Speaking of teams, I did get involved with Spartasoft, the student game development club, which was another important step toward being able to program a half-decent game. The club served a few primary purposes at that point, such as hosting a games party occasionally and getting alumni to come back and present to the club about their experiences in the games industry. However, the most important function for me was the 48 hour Game Jams that were hosted every few months. If you're not familiar with the concept of a game jam, we basically split into small teams on a Friday evening, a theme is announced, and then each team makes a game about that theme over the course of 48 hours. It often results in a lot of terrible games, but inevitably there's something new that's learned, new game ideas explored, and a lot of friendships built with game developers that you might not otherwise get to know. I cleared my schedule for these as a Freshman, and participated in every single one.



It's how I got connected with a couple of seniors, and I ended up putting in more than just 10 hours a week on one project in the Spring. I started meeting with them in between game jams to polish some of our better ideas. The fact that upperclassmen like Bert, a programmer that now works with me at Iron Galaxy, and Marie, an amazing artist that's now a grad student at SCAD, wanted to work with some freshman was amazing. I had gotten past the hump for being able to contribute to a game at all. I could help make their games better, and because I was more than ready to step up to the task, I ended up learning a lot back from them.



Conclusion



So what can be learned from my first year making games? First, don't be afraid to go it alone and force yourself to spend at least a minimum amount of time each week working on it. Secondly, game jams are great, especially if you don't know very many people to collaborate with. Between the manatee game and the game jams, I had worked on 6 different games by the time I finished my first year of college. How many games had I worked on for class? Zero, and Michigan State even has a game development curriculum! If you have the opportunity to work on *any* game when you're just starting out, even a game jam game, you'd better have a damn good reason if you pass on it. Failing any opportunities for collaboration, the only person keeping you from making your own game is yourself. Don't be the asshole that's keeping you from learning how to make video games. I got lucky that I didn't do that, it's easy to be lazy when you're an 18 year old college freshman.

Backface Culling 101

This post is for artists, designers, and anyone else who has had backface culling shoddily explained to them. Perhaps I should have checked the Venn Diagram of AltDev readership before writing about a rendering technique specifically with non-programmers in mind. I know I've gotten embarrassingly confused by forgetting what's important as little as 2 months ago.

The "Simple" Answer is Misleading

Backface culling comes up all the time when people are first becoming acquanted with 3D game dev. All it takes is deleting half of a cylinder in Maya and dropping it inside of an easy to use engine like Unity. Then they're suddenly be trying to figure out what got screwed up that's causing the inside of it to be invisible. Inevitably the answer given is that those faces are backface culled to avoid rendering the inside of 3D models. That's true to some extent, but in my opinion very misleading.

The other part of the common answers is that backface culling works by only drawing the side with outward facing normals. This part, is not actually right and it leads to a lot of misunderstandings. I think this answer comes up because people like artists and designers are used to thinking of meshes in 3D space, rarely do people think about the process that turns it into a 2D image unless they get into rendering programming.

The Triangles are not Drawn twice

First off, understand that you have a big mess of triangles that you are using to represent your piece of art. One of the simplest representations of this is to have all the vertices in a big long list, and then to have a big long list of triangles defined from those points. Your computer is taking those triangles and transforming them into the 2D space that is displayed to you. That triangle is so simply defined to expedite rendering that it has no concept of "front" or "back" (well it does, but I'm getting to that). The vertices may have normal information, but that's used for lighting, not culling. Consider a camera pointed at a half-cylinder that renders properly in the first case, with the following badly drawn diagram taken from above. The green lines are normals:

Now consider the *exact same* list of triangles with the only change being to flip the normals at each vertex. If you try this on your own, it is probably best done by modifying your vertex list in the rendering code, for reasons that will be explained shortly.

With backface culling turned on, you will still see the cylinder in each image, except the lighting will be flipped in the second one. And if you turn off backface culling then the same images will be rendered, and it will be done so with the same number of triangles, because there are no backfacing triangles in the given example. Don't think that the GPU is rendering the backside and then going over it a second time when you have backface culling turned off for the front side, unless you actually did specify two triangles in that big list of triangles with vertices in the exact same locations.

Assuming you understand that what I described is not what typically happens, let me now explain the point that I'm making. When you flip the normals in a 3D modeling package it's doing more than just changing the vertex information, it's also changing that triangle list. This is because the front and back face of a triangle are determined through the novel concept of winding order, which is quite simply that the front of a triangle is the side of the face where vertices are viewed counterclockwise. Suppose you have a mesh with no normal data, just positions in 3D space for vertices. You can still use backface culling just fine as long as your triangle list is specified in the proper order, a point that I think is often missed by designers and artists when trying to understand backface culling.

If you want the proof in the pudding, here's the OpenGL call to specify culling:

glFrontFace(GLenum mode);

Where mode is either GL_CW or GL_CCW, standing for clockwise and counterclockwise, notice that this has nothing to do with vertex normals!

And here's a diagram to illustrate which side is the front for a triangle by default (you could assume that triangles are front clockwise as your standard if you really want to, but the default is counterclockwise). If the points defining your triangle are listed in an order that would cause the diagram on the left to be true after transformed into screen-space, then that triangle is front facing:

So what are we culling again?

We're culling triangles facing away from the camera, which are going to be obstructed by the forward facing polygons on a closed mesh. Those triangles that would be drawing the inside of that cylinder are just going to be covered up by the front-facing triangles that you would actually see. With the winding order in hand, the triangle's face normal can be determined and checked against the camera. I made this little diagram (insipred by the great explanation for backface culling in Real-Time Rendering). The triangles on the backside of the full cylinder are facing away from the camera, so they are culled (indicated by the dotted part).

So on a closed mesh like a full cylinder, you can avoid doing the work of rendering all of those triangles that you already know are going to be obscured. This is why disabling backface culling is typically not the correct answer when you have triangles culled that you didn't intend to, and it's also bad because that usually means that the backfacing triangles are being shaded incorrectly with backwards normals.

If you do intentionally cut that cylinder in half, the easy fix is to add front facing triangles along the inside of the mesh. I believe there is functionality these days (DX10 maybe?) to figure out which side of the triangle is being rasterized. Theoretically you could have the shader flip the normals based off of that information to still have correct lighting, but if you just read a post on the basics of backface culling, I bet that's not what you're looking to do.

Because 3D modeling programs are automatically adjusting the winding order for you based off of what direction your normals are, it's easy to mistakenly think of backface culled triangles as triangles with incorrect normal information, when really it's winding order that determines it. This is why sometimes you can really end up in weird situations while using a 3D modeling package. I know that as a Freshman in college, there were many models at game jams that had those stray triangles that artists just couldn't get to show up, and maybe if they did the lighting got all weird. Perhaps thinking about what's actually happening can help alleviate those pains.

Obligatory FXAA Post

I did a quick search through AltDev and I don't think anyone else has really talked about FXAA on AltDevBlogADay yet, but the time is long overdue. I'm a little late to the game trying out Timothy Lottes' post-process anti-aliasing technique, but I had been noticing people saying great things about it when I finally decided to give it a serious look over 4th of July weekend. I had already been thinking about writing about my experiences with it when I saw Eric Haines had posted up a glowing review of it over on realtimerendering.com. So if you don't trust the judgement of some intern that doesn't even have a college degree completed, please refer to all the more qualified people that are having similar experiences to me.

The Problem at Hand

For those of you that might be reading this and haven't drank the graphics programming Kool-Aid, I'm going to fill you in a little bit as to why we care about anti-aliasing.

In our line of work, the end result of a rendered scene is typically a 2-dimensional array of colors that is displayed on the user's monitor. Just like how audio (which is originally analog), is quantized when it is made digital, the image is built into a discrete number of pixels during the process of rasterization (i.e. filling in each triangle). The measure of how many pixels are used to display the image is of course known as the resolution, which is why things become increasingly blocky as you lower a game's resolution, due to there being fewer dots per inch.

Even at high resolutions, individual pixels can still often be identified by the viewer, because the lines and edges of triangles form distracting "jaggies". This is noticeable along the outline of an object being displayed due to rasterization, but can also occur on interior surfaces for other reasons such as shadows and texture map resolution. The user typically picks the resolution their monitors are set at, but most console games provide 720p or 1080p images to the TV, and monitors tend to follow suit (my laptop is set to ~720p). Other than relying on hardware to pack more pixels into the same physical area by increasing the dots per inch (which is something that Apple is claiming with it's retina displays, but check out this post for an interesting look at that), we have to find ways to smooth the transition between pixels. Perhaps the simplest strategy to dealing with aliasing is to render into a texture twice as large as the target resolution and then downsampling it to actual output resolution. This allows you to take the average of every four pixels, softening out the boundaries by averaging the edge colors together. However, this also just straight up sucks for performance. You end up processing 4x as many fragments from the higher resolution, and you have 4x the memory usage for the buffer. This is way too high a cost to pay for some smooth edges.

The Hardware Option

There is a hardware accelerated method, MSAA (Multi-Sample Anti-Aliasing). This operates by computing additional samples when rendering the frame instead of rendering additional pixels and downsampling. The fragment shader is only run once for each group of samples. The problem is that it doesn't work with the increasingly popular deferred rendering techniques, because you can't really take more samples of a buffer you've already rendered. In short, the damage is already done, the data has been discretized to a particular resolution. Furthermore, I've always found that MSAA is still pretty expensive (but then again, the only way to make your rendering take 0 ms is to quite doing rendering and switch to a job in finance).

New Maps of AA-land

The desire to use deferred rendering has pushed alternate forms of anti-aliasing to get a lot of attention (I mean who doesn't need more acronyms, right?). Perhaps the most prevalent that you may have heard of is MLAA, but most of the techniques that I'm referring to here are post-processing techniques that rely on detecting and softening edges. By doing anti-aliasing as a post-process, it will work seamlessly with deferred rendering, and pretty much anything else for that matter. If the technique only needs the color buffer access, then it can even be applied to video/screenshots/whatever of existing games, which I think researchers in this area have found as a great method of showing off how their work.

MLAA was originally a CPU based technique developed by Intel, that has since then been adopted to be done on the GPU. This has been outlined in GPU Pro 2, Game Developer Magazine, and around the net, but if you're not familiar with it I'll make a few brief points about it. It essentially boils down to storing edges in a texture with different colors indicating which side of the pixel the edge is located at, and an additional buffer is used to calculate the blending weights for the blurring.

Impressively, they found results falling somewhere between 4x and 8x MSAA, while being 11x faster than 8x MSAA. The memory footprint of the technique is 1.5x or 2x the size of the back buffer depending on the hardware (2x for the Xbox 360 for all you console devs who probably have already heard everything I'm saying). That's pretty good for something that solves the problems encountered with deferred rendering at the same time. This is undoubtably why the technique has garnered so much attention, and I really recommend the article in GPU Pro 2 if you want a clear view of all of the details.

Enter: FXAA

As you may know from reading other posts, my big side-project/hobby/thing is that when I give a new technique a try, I do it in Unity because it a) is usually not straightforward and requires actually understanding the technique to get it working and b) can be evaluated using the many projects I've done in Unity previously. From looking over the details of MLAA, I knew it would probably take a full weekend to get it right, and I had been procrastinating quite a bit with getting around to doing it.

When the third iteration of FXAA rolled out I decided to take a look at what it entailed. I knew in the back of my mind that FXAA was a strictly luminosity based technique, which is interesting to me. The authors of MLAA recommend using depth to determine edges for best results and performance. However, luminosity based techniques offer the advantage/disadvantage of smoothing boundaries that exist in places other than depth, such as with aliasing on texture maps and with shadows. The downside is that this can produce results that are too blurry in places you don't want blur, such as with text on a prop in 3D space. I once tried a very, very simple luminosity based AA filter, that resulted in too many cons (especially with blurry text) for me to seriously use. I was curious if FXAA would give me similar problems.

With the intention of just looking over the code briefly, I suddenly found myself staring at a very simple and easy to use code base offering a ton of well explained pre-processor options for target platform and quality. Being around midnight when I started looking, I quickly decided that porting the higher-quality PC version of the HLSL code to CG/Unity would be fun. There were two steps involved:

1) At the end of all the other post-processing, calculate Luminosity and slam it into the alpha channel (super easy to do).
2) Perform the FXAA pass. Porting mostly involved fixing texture look-up syntax.

No extra buffers involved. This cuts down on the extra memory needed for MLAA, and the code seemed simple enough that it would probably be pretty fast. I ported all the code within 2 hours and then went to sleep. The next morning I finished setting it up for use in Unity... and was blown away by the speed and the results. Here's a breakdown of what I got running in the Unity editor at ~720p, using Dust, a previous project of mine, to test it. These are PNG's cropped down at native resolution:

Shot 1: No Anti-aliasing

Shot 2: FXAA3

Shot 3: 6x MSAA

It takes FXAA3 only ~1 ms [Note: corrected from an erroneous order of magnitude type when I first posted this article] on my laptop (MacBook Pro with an NVIDIA GeForce 320M) to be completed (including the luminosity calculation), and as I mentioned, no additional memory either. I'll pay that millisecond any day of the week for that quality of anti-aliasing. Furthermore, the blurriness on text was much more acceptable than the fast blur I had tried previously. Note that this text is not really meant to be read, but rather recognized to match the voice over so the player can understand that the voice is that of the journal's author. I wish I could credit the sources where I put together the fast blur from, but it's been more than a few months since I implemented/ditched it. Here's a comparison:

Shot 1: No Anti-aliasing

Shot 2: FXAA3

Shot 3: Fast Blur

This is getting a bit more to the personal opinion end of things, but even though FXAA3 does blur the text, I feel like the fast blur makes it almost uncomfortable to look at. I get the sensation that I'm getting tested for a new prescription of glasses, and have to recognize out of focus letters. To me, that seems like a pretty good indication that your luminosity based AA technique isn't up to snuff if you get that type of blurring. FXAA3 on the other hand seems acceptable enough that it'll definitely be enabled in future builds of Dust that get pushed up onto my website.

What did we learn?

Hopefully we learned that FXAA is both fast and doesn't require additional memory, and is trivially simple to implement or port. There are versions for the 360, PS3, and PC, as well as HLSL and GLSL variants. It's a luminosity based solution, and comes with the associated pros/cons those techniques have, but I've found FXAA to minimize the cons. It should literally take you at most a few hours to get it up and running in your game and evaluate if it's a good fit for what you're doing. Furthermore, it is in the public domain (credit to the post by Eric Haines for this twitter snippet):

Although at this point, I'd the amount of quality you're getting for the effort of implementation, it might as well be under the beer license. Finally, I would point out that Timothy Lottes is still improving on the code, and has already released version 3.9 in the time since I first touched it. You can find the latest source links and updates on his blog: http://timothylottes.blogspot.com/.