Improved Spotlight Culling for Clustered Forward Shading

I've been fiddling a lot with tiled and clustered forward shading implementations in my work both professionally and personally. If you're not familiar, there has been some work in the past few years to exploit modern GPU's ability to handle dynamic loops to allow for a larger number of dynamic lights than frequently afforded by a standard forward rendering implementation. Some strategies have been to read back the depth buffer in a compute shader to identify the min/max range of a sub-frustum, frequently referred to as "Forward +" and another set that does not and instead uses fixed partitions in the frustum to identify lights may be touching with regards to scene depth. Really if you're not familiar, there's a good set of links discussing it over on Aras Pranckevičius's blog that will bring you up to speed on a lot of ideas. I'm mostly interested in techniques that do not require reading back depth information, due to the flexibility it offers on scheduling, and you can decide to implement it on either the CPU or GPU depending on what works best for a given project. Emil Persson of Avalanche has a great presentation on their research into that approach, check out the details on his site.

Besides figuring out how to efficiently test lights against a large number of clusters (since more clusters can equate to tighter culling), another huge impact on these techiques is how good the math is for testing a primitive against a given cluster. Persson discusses this at length in his slides, since there are difficulties in testing small clusters against large primitives. The traditional method of testing six planes of a camera frustum against a primitive is ineffective, leaving you with large numbers of false positives. The primitive will tend to look like more of a box than its actual round shape. I've put together a little test bed in Unity just to help me visualize different culling techniques as I've played around with this, and you can see here how badly a point light does when doing six plane/sphere intersection tests for each cluster:

Emil Persson proposed refining the sphere size smaller along each axis direction to get tighter culling. There's also another approach presented by Marc Fauconneau of Intel at Siggraph 2014 and has source code included in their clustered shading sample. The sample is somewhat focused on leveraging Intel's ISPC to compute the culling results, however the math is certainly interesting outside of that context for clustered light culling in general. His approach is to find a plane between the point light and the center of a cluster, and test each point against that plane as what I like to think of as a sort of "poor man's separating axis theorem," in that it would likely be more accurate to test each corner against a newly calculated SAT plane, but that would add a lot more overhead to the test. Here's what the previous point light test looks like changed over to use the Intel approach:

So much better! But as you may have gathered from the title of this post, I'm actually interested in spotlight culling (so I don't have an implementation or results for Persson's approach in this case). For spotlights, Persson states that they approximate the cluster with a bounding sphere and test against that, however his slides are very light on the actual specifics of the math that they use. There's obviously some issues with approximating a cluster with a sphere, especially if they start to become stretched out in depth (the density in the previous screenshots is awfully high to get clusters that are more cube shaped). On the other hand, the Intel approach just leaves spotlights to the reader's imagination, which isn't very useful either. So before I get to how I've gone about filling in the blanks on how the Intel approach might get adapted to handle spotlights, here's a quick screenshot of my own implementation of testing a spotlight using bounding spheres to approximate each cluster:

I have no idea how well my implementation matches Avalanche, and I'm not super familiar with intersection tests for spheres and cones, but my rough logic is as follows: start with two simple tests of sphere/sphere with the spotlight position+radius against the cluster sphere (early out with failure) and a point/sphere test against the sphere using the origin of the point light (early out with success if this passes). Then for the actually interesting bit, I find the "maximum angle" that would cause the sphere to intersect the cone by taking the arcsine of the sphere radius over the distance between the spotlight origin and the sphere center. I sum the resulting angle with the angle of the spotlight (or half of the angle in my sample code since the "angle" in unity is for the full spotlight width, i.e. think radius vs. diameter). This gives me an angle I can test against with the dot product of the spotlight direction. I suspect I'm struggling to describe this super clearly, so here's the source code for my test function in C#/Unity:

I'm not super jazzed that my spotlight code includes trig and inverse trig functions, and the nagging feeling that someone much smarter than me probably has a much better way of doing that test. So it's not what I would necessarily refer to as "production ready," but it does do a good job of approximating the conical shape of the spotlight! Fellow Iron Galaxy'er Nate Mefford made the useful observation that there's likely cheaper approximations of the ASin that can be used, and of the trig in general. Possibly one strategy would be to use a rough approximation as an initial early out and then refine with the full arcsine for the tightest level of culling.

On a similar note, I would also call out that theoretically the set of clusters has already been reduced at this point, especially if the code executing on the CPU where that sort of thing is easier to architect. In the code given, you start by rejecting based off of the full sphere first, and then worry about the more expensive bits. If I'm reading the slides from Persson correctly they sweep across their clusters with fasts tests against the planes of the clusters in each major axis of the view frustum (i.e. left to right, top to bottom) to find the boxy-looking culling as shown with the point light at the top of the post, and only *the* do the more expensive culling on the reduced set, which may only be doing 10% of your total cluster count. In my experience doing something like that is a lot harder in a compute shader, where I've found throwing a separate thread at each cluster to work well. Almost so well I'd use the phrase "embarrassingly parallel" but then you'd have to put me down out back for using buzzwords, but the idea is that all clusters are totally independent of each other and are just reading from a shared buffer of total lights to cull. I think possibly the approach to get some hierarchical culling on the GPU would be to do a small amount of coarse culling on the CPU. For example: split the frustum into 8 octants, build light lists for each octant, and then dispatch separate compute jobs for each one.

I'm much happier with how my approach to adapting Intel's point light test to handle spotlights has turned out as far as the raw math goes. I drew inspiration for the idea from Christer Ericson's description of testing a cone against a plane in Real-Time Collision Detection, where he uses a couple of cross products to figure out the vector on the cones cap that points towards the plane. My idea was this: start by testing the spotlight a full sphere, then orient a plane on the side of the cone and repeat the test against that plane. That oriented plane will have the vector from the spotlight position to the closest point on the cap as one of it's tangents, and the second tangent (and then the normal), can be found with the cross product of that tangent and the vector from the spotlight position to the cluster center. Here's the result of my test with the spotlight from before:

I chose this spot in particular because there's some clusters misbehaving behind the origin of the spotlight, which could be improved upon by testing yet another plane oriented with the spotlight itself (a hemisphere shape would result if you combined that with just the initial pointlight test), but I haven't decided if practice that's actually worth doing. In the given example, only 2 additional clusters would be culled. Furthermore, the previous test resulted in 588 clusters being lit, this test results in 506. There's already an improvement over the sphere approximation in this example, so it's not like we need to play catch-up by throwing even more math at the problem. The code is a bit longer than the previous, but at least avoids anything more expensive than the cross products. Here's my source code for that function, I should note that I use Fauconneau's optimized code for testing the vertices against the plane:

In conclusion, I wanted to give a little discussion on culling spot lights against clusters along with some code samples, since it seems to be a bit glossed over in some of the resources floating around out there, but the resources *are* excellent, so definitely go read those if you are not familiar with the work in culling lights with frustum clusters. Personally, I like the projected plane approach because it's very clean to have the math for the spotlights built directly out of the point light culling logic, and in my particular implementation, I'm currently seeing the best quality results with it. As I said before though, I'm not confident that I have the best approach to doing a sphere/cone test, especially with regards to performance.

Finally, I leave you with one final shot that I didn't find a reason to include earlier, of how poorly the results are by using the cone/plane math from Real-Time Collision Detection to test against six plane similar to the point light shown at the beginning, clocking in at 1408 lit clusters, for a further reminder that testing against the six planes of the cluster frustum is usually a bad idea:

Thoughts on Engine Licensing

I seem to have hit a strange impasse of decisions regarding game engine licensing. It used to be a simple decision on my part for licensing an engine for personal use: cobble together the cheapest Unity license possible. Now things have changed, both personally and with modern game engine licenses. Its led me to be thinking about this a fair bit recently and I decided maybe I should just write it up as food for thought for anyone that might stumble across this.


I learned Unity extensively at my first game development job Michigan State University back in 2008. The head of my lab had decided to begin using the engine both in the classes he taught and in most of his academic classes, accurately predicting that its trajectory would lead it to be an affordable and beginner-friendly tool for game development, that would still have enough depth to produce a top tier game if put in the right hands.

The university had previously used the Torque engine for teaching 3d game design classes, which gave full access to native source code... but apparently the view on that was that it was more a necessity than a bonus to be able to get around stability issues when using the engine. Unity on the other hand has resisted allowing full source access from the beginning. This always seemed to make sense to me since their business model has seemed to roughly be to market a fully capable 3d game engine as a piece of software akin to Photoshop. The parallels can definitely be drawn to Flash's use as a 2d game engine, which at the time seemed to be filling a vacuum of products with real consumer demand, Flash seemed to me to be a piece of software intended more for generic "interactive media" but was instead being coerced into being a fully functional architecture for increasingly ambitious 2d games. It always struck me as incredible that something as simple as adding a data structure equivalent to the STL's vector would be considered a groundbreaking advancement in Flash game performance optimizations. But, enough about Flash, my point is that I'm happy I hopped onto the Unity train when I did. It's proven to be an effective tool for prototyping new ideas, rapidly building projects in game jams, testing out some of the latest rendering techniques, and building full scale projects intended to have hours of gameplay.

GDC 2014

As you may be aware, this year's GDC brought in a whole wave of competitive moves by several of the larger game engines. Unity announced the next major iteration of their engine and key features in development for it. My rapidly expiring educational license is in limbo due to a crashed hard drive. Now the desire to go through the hassle of trying to recover it is rapidly fading since a new engine version would require a new license anyways.

I'm nearly at the end of ways I can weasel my way through pro trials, all my academic licenses from my days at University are either for much older engine versions or have expired. Unity's previous introduction of a 99 dollar educational use only license was a great stab at what I'm going to talk about when I get around to actually making a relevant point in this post, but that license is now very difficult for me to acquire as my ties to the University dry up. Unity offers a 75 dollar a month subscription license, but witha 12 month contract, it doesn't really save anyone any money. If you only need Unity for 3 months, you're still going to end up paying the full prices.

In the mean time, Crytek and Unreal both announced competitive pricing for their engines at GDC. Crytek offers a 10 dollar a month subsctiption service now. My understanding is that this allows access to a gameplay layer of sorts for licensees, but a full engine source license is different. Unreal on the other hand stepped forward with a 20 dollar a month subscription with full access to the engine source for Unreal Engine 4, a step away from the restricted model they followed with UDK for Unreal Engine 3. This comes witht the caveat that you must pay 5% of your revenue to Unreal if you release a commercial game.

This fascinates me. Unreal has single handedly made itself a very interesting engine for people like me: people that have little to no intention of releasing a commercial video game.

Non-Commercial Use

 My continual usage of Unity in my spare time is driven by a few key pillars:

  • Staying familiar with an engine I have expert level knowledge of is worthwhile, even though Iron Galaxy historically uses Unity very rarely. If that were to change, which is possible since we do lots of external contracting, my experience would certainly come in handy. It would also likely be useful in the unlikely case of Iron Galaxy being sucked into a dimensional rift while I'm oversleeping and suddenly I find myself in need of a new job.
  • Unity makes for an excellent choice for experimental game design: whether its a game jam or a prototype of an idea that might eventually turn into a real thing, fast set-up and fast iteration make it very appealing engine for that sort of thing. The free version does a very decent job of this still. I've been using free version features only to slowly poke at a prototype of a silly Manatee-based game. I might release it at some point. Probably for free. Probably no one will notice. That's fine.
  • It offers an interesting trade-off as a choice for prototyping rendering techniques. On the upside, boring things like particle systems and model importing are handled for you already. On the downside, you have to work around the choices made by the rendering engineers there. This is true of all licensed engines. With full source this becomes easier, but only to the extent that merging the latest engine revision might be a huge headache if you get too agressive with modifications. It's best to live in harmony with an engine instead of fighting it, and I think its worth practicing that in projects outside of the office.
  • Students, indies, and professionals might find implementations and blogs about work in Unity interesting since they might be using it too.

So here's the dilemma: I could license Unity 5 and go on my merry way. Or. I could purchase a new guitar with that money. What I have done is license Unreal 4 for 20 dollars, and I don't have to pay for a full 12 months if I don't see the need to. Unreal has out of the blue become something very interesting to me for use as my platform for prototyping new techniques. In fact, Unreal has done a huge favor to researchers everywhere that might want to prove out their ideas in a commercial engine. With full source access, building in even esoteric (if potentially ill-advised) revisions to the engine should be painless. They can keep their source drop even if they don't keep paying for source access, and they can share it freely among their groups/labs/grad student slave labor/etc. I'm excited to be able to tell a researcher that there's no reason they can't test something out in a commercial engine.

There's some problems with jumping ship from Unity for the time being though:

  • I like leaving the door open to using cutting edge or impractical rendering tricks in small projects where the render budget might otherwise go unused.
  • My accrued Unity knowledge will begin to collect more dust than I'd like.
  • Iron Galaxy already has a lot of familiarity with Unreal, including myself. So I lose the benefit I mentioned before about diversifying my experiences.

Why Any of this might be relevant to Unity

There are two reasons why I think Unity is leaving themselves exposed in a few ways to Unreal's decisions besides the competitive pricing they're offering. There's the aforementioned issue of the ease of access for academics to use it as a test bed of choice. Furthermore, Unreal is introducing a marketplace for selling engine enhancements, just like Unity does. It seems that the Unity Asset Store has been very successful for them: it allows additional engine features that they have not personally developed, and they get a cut of the revenue of transactions in the store.

In my mind, developers targeting tools development are essentially paying for the engine twice. Once for the license, and again with a revenue cut. Unreal's making a compelling point that for that system to make sense: the up front cost should be as low as possible.

Where this leaves Me

I think 1,500 dollars for a game engine is incredibly cheap for developing a commercial game. I'm less inclined to think it makes sense for somebody making an art game or prototyping a new rendering technique, or even just someone making improvements that Unity or Unreal is getting a cut of in their stores when other developers by their tools. So for now it seem increasingly likely that I'll be splitting my free time between Unity and Unreal. Not sure if I have the appetite to give CryEngine a spin just yet. In the end, it surprises me that I'm even having to have this dilemma, since Unreal and Unity used to occupy very different spaces when it came to hobbyists. Weird.

Notes on Skin Shading

If you've followed my musings for a while, you'll know that I real-time skin shading is one of my favorite topics to read about, regardless of what I'm actually working on professionally. It's been a while since I've posted on the subject which is a bit remiss since there's a useful note on Pre-Integrated Skin Shading that I believe I've neglected to post here (I skimmed through my history and couldn't see anything about even though I know I had the intent to), and a few useful presentations have discussed techniques in the past year or two that I've never mentioned here. For reference, a younger version of myself has written very mediocre posts on the topic here and here. I figure I ought to continue that trend.

First and foremost, in response to my original post about implementing Pre-Integrated Skin Shading (PISS) into Unity3d, David Neubelt from Ready at Dawn (and I saw it on the comments at least somewhere where that post got reposted) pointed out a minor bit of incorrect math in the generation of the look-up texture. If you the examine the math in Penner's slides, you'll see the following figure:

$ D(\theta) = \dfrac { \int_{-\pi}^{\pi} \cos (\theta + x) \cdot R(2 \sin (x / 2))\,dx } { \int_{-\pi}^{\pi} R(2 \sin (x / 2))\,dx } $

What's of interest here is the limits of the integral. If you go and look at my Unity code in my old post about PISS, you might notice in the sample code that I use $-\pi \over 2$ to $\pi \over 2$ for the integral's loop. This is an error that I carried over from Penner's sample code in GPU Pro 2. When corrected to $-\pi$ to $\pi$ to match the integrals in the equations, there are only subtle changes, but those subtle changes are for free at run-time from improving the look-up texture quality, so there's no reason not to have them.

Speaking of David from Ready at Dawn, him and Matt Pettineo have included their experiences with using PISS in the upcoming title The Order: 1866 in their presentations at SIGGRAPH and GDC. They include useful math for combining PISS with Spherical Harmonic lighting. In fact, all of the sets of course notes from the Physically Based Shading course at SIGGRAPH are worth looking at if you haven't already.

Finally, I saw John Hable's talk at GDC this year about his experiences with trying to produce high quality, compressed facial animation. The interesting bit about his presentation is that he touches briefly about skin rendering towards the end. He has an interesting approach on shading that goes back to Texture Space Diffusion, which is what most modern techniques have used as a reference for a high quality result but have tried to get away from for more performant options. The key bit to Hable's approach is that instead of doing multiple convolutions, he does a one-pass approximation in a 256x256 texture. It seems like this might have some advantages in certain contexts over PISS or screen-space techniques, but obviously it suffers from the inevitable scaling issues of needing to process a separate texture for each character visible on screen at the same time.

Scaling a Sobel Filter

I've worked on a few different games that use edge detection to render non-photrealistic lines and this has lead me to do a fair bit of fiddling on my own time with various techniques, looking into both the quality of the effects and how to optimize them. This post is about my experiences taking one of the simplest filters in use and looking for a way to make it even cheaper without drastic quality loss.

An interesting issue with post-processing in any game, is that if you take it to a new platform that is substantially less powerful, how to scale the quality of it without requiring re-tuning of content (i.e. you don't want art to have to go through and readjust every use of depth of field in the game because your original technique was too complicated). Morgan McGuire discussed the importance of this in his methods for scalable motion blur and depth of field processing presented at Siggraph 2012 ( While McGuire's talk is focused on scaling between console generations, the engineers over at Unity frequently have discussed porting expensive effects down to mobile which is a similar problem (, In an ideal world, you can mitigate these situations by planning for your slowest platform from the beginning, but the realities of the games business don't always allow for that sort of planning.

One of the most straightforward and efficient ways to render lines for a non-photorealistic render in real-time is to process a sobel filter as a post-process on some property of your main render, typically depth and/or normals. The way a sobel filter works is pretty simple, here's a quick refresher (adapted from the wikipedia entry). For a source image\(\matrix A\), two convolution operations are applied:

$$ \matrix {G}_x = \begin{bmatrix} -1 & 0 & 1 \\ -2 & 0 & 2 \\ -1 & 0 & 1 \\ \end{bmatrix} * \matrix A \\ \\ \matrix {G}_y = \begin{bmatrix} 1 & 2 & 1 \\ 0 & 0 & 0 \\ -1 & -2 & -1 \\ \end{bmatrix} * \matrix A $$

The best way to think about these are applied in an implementation is that for the processing of each fragment, the values in the matrix notation are simply weights applied to the surrounding pixels sampled by the program, and then summed together. The magnitude of the gradient approximation from the sobel filter can be calculated via \(\sqrt {{{G}_x}^2 + {{G}_y}^2}\). That magnitude is typically then used to determine if the fragment should be a line or not.

Here's a shot of a test scene I've set-up in Unity to run my effects on:

I've taken the built-in edge detect effect that ships with Unity pro has a couple of filtering variations. I've simplified the "SobelDepthThin" filter a bit (it's "thin" since the filter is tweaked to exclude exterior edges, which gives the nice property of avoiding artifacts with other depth based post processing). I've tweaked their implementation slightly to more closely match the standard Sobel filter formula I discussed previously. Here's a shot of a test scene using the effect, rendered as one minus the gradient magnitude, blended against white instead of the scene color so that only the edges are visible:

So here's a thought, what if we removed half of the weights out of the image? At some point there's only so much you can optimize the ALU of a relatively simple shader taking 9 samples (the 9th is the center pixel) to get any benefit, dropping 4 samples would have a benefit no matter what. Here's what it looks like if the vertical and horizontal samples are simply commented out of the shader:

This is a bit interesting since the main details of the effect are mostly intact, but the lines are rendering more faintly for details across smaller depth discontinuities, such as with the bottom left of the capsule in the center where it overlaps the box. It seems like there should be a way to account for this and have the effects line-up reasonably well. What I realized with this was that there's actually a super convenient approximation that make these have very similar properties without hand tuning any parameters. Let's step back and look at the math for calculating \(G_x\) and \(G_y\) from the following set of samples \(M\), where \(x\) is the center depth sample:

$$ \matrix {M} = \begin{bmatrix} a & b & c \\ d & x & e \\ f & g & h \\ \end{bmatrix} \\ \\ {G}_x = -1 * a + 1 * c + -2 * d + 2 * e + -1 * f + 1 * h \\ \\ {G}_y = 1 * a + 2 * b + 1 * c + -1 * f + -2 * g + -1 * h $$

I wrote out all of the multiplications to try to help illustrate how they match up to the kernels up at the beginning of the post. In the initial approach of just dropping the weights effectively turns samples \(b\),\(d\),\(e\), and \(g\) into zeros. The trick to balance how the filter is behaving, is to treat each of those terms as the average of the two neighboring samples. Here's what that would look like plugged into the equations:

$$ {G}_x = -a + c + -2 * (0.5 * a + 0.5 * f) + 2 * (0.5 * c + 0.5 * h) + -f + h \\ \\ {G}_y = a + 2 * (0.5 * a + 0.5 * c) + c + -f + -2 * (0.5 * f + 0.5 * 0.h) + -h $$

And then if we combine the terms together, we get something very clean:

$$ {G}_x = -2a + 2c + -2f + 2h \\ \\ {G}_y = 2a + 2c + -2f + -2h $$

So the moral here, is that I just used a bunch of math to simply express "multiply the diagonal weights by 2." I guess it was really just an excuse to add more LaTeX to this post. What's more interesting is seeing how this holds up in an actual scene.

This actually looks very close to the original image! Close enough that the differences are what you call subtle. Clearly, there have to be differences Here's a BeyondCompare diff of a close-up of the cylinder/sphere intersection in the middle:

The original version is on the left, the simplified version on the right. As you can see, there are actually differences being picked up, but if you look closely a lot of the details missing are the grey / semi-opaque pixels from the left are completely black on the right. So, unfortunately, there is some quality to be lost, but nothing is for free. If you're doing something like running FXAA afterwards, that would probably more than compensate for the loss of those minor details, although on something super low powered like a mobile platform that's probably not an option. Perhaps the coolest thing that I like about the trick though is that straight lines like the vertical ones on the capsule end up essentially correct under the approximation.

So in summary, dropping half the weights out of a sobel filter turns out to potentially not be the worst idea in the world. Additionally, this post was the first time I've use LaTeX or any sort of fancy styling for it, so hopefully MathJax did not steer me in the wrong direction with its claims of "works in all browsers." Hopefully I'll get around to writing some more technical pieces in the not so distant future.

Best Albums of 2013

Kelsey's been spending the past few weeks trying to figure out what she's going to list for her top albums of the year over on Violent Success, the music blog that she's an editor and contributor for. I've come up with a short list of my own from discussing what's actually come out this year that I've been listening to. Assorted punk rock goodness of 2013 follows.


The past year and a half has seen me begin to embrace a newfound obsession with surf-influenced punk rock coming out of LA. The debut LP from FIDLAR, takes the mellow fuzz of surf punk and cranks the speed and energy way up. Most surf punk shows I go to are pretty tame with people enjoying the music. Last time I saw FIDLAR live, the kids were climbing on the rafters and 2 girls dressed as nuns (it was halloween) were not pulling any punches in the pit. The energy matches the name, which stands for "Fuck it dog, life's a risk."

Audacity: Butter Knife

Audacity is the band that originally made me realize my love of surf punk with their album Mellow Cruisers, which would become my anthem for the summer last year. This fall brought about the release of their third LP, Butter Knife. It's a bit more laid back than their previous efforts, which is complemented by some really great song writing on guitar with catchy riffs that really tear through the speakers. It all fits together into an incredibly well rounded album that I've been listening to a ton in the past month.

Smalls: Expecting the Worst

This little 4 song EP has made me excited to see what's next for this relatively new pop punk band from LA. They're my new hope for some fresh pop punk in the vein of Daggermouth or Set Your Goals. I first heard what is possibly the best song of the four, Game of Kings, on Act Your Age, a punk rock podcast out of Vancouver, that I've been listening to since its inception. Game of Kings took me by such surprise that I literally paused it to look them up halfway through the song and start syncing the album to my phone from spotify. I'm also very upset with them because they're about to go on tour through my hometown in Indiana but aren't making the effort to come up to Chicago.

The So So Glos: Blowout

I have a long history of seeing The So So Glos play basements and abandoned theatres in Fort Wayne to crowds of only a few dozen people. They somehow captured the hearts of a rag-tag assortment of punks and metal heads in my hometown with their punk-influenced indie stylings. Which is why I was surprised to see them drop an album that Pitchfork reviewed, and even liked. And then I went and screwed up and didn't get tickets soon enough to a sold out Chicago show with Desaparecidos. What's great about Blowout is that despite their newfound publicity after years of staying strong as a relatively unknown group, is it stays true to their style. Dreamy songs of life in the city, with faster riffs coming in at just the right time, and great lyrics over the top of it all.

Night Birds: Born to Die in Suburbia

This album really caught me by surprise. I picked it up on a whim at the record store, having never really gotten into Night Birds previously. What I got was an incredible album that is both poignant and clever. For some reason this band is in my imagination what FEAR would be like if they were a modern punk band influenced by the likes of Dillinger Four instead of an 80's hardcore band.

Direct Hit!: Brainless God

I started listening to this pretty late in the year. After seeing them play in the rain on the last day at Riot Fest, I decided they warranted a further listen and got really hooked. It's fast, offensive, and catchy. What more can you ask for from a pop punk band?