Search this blog

08 October, 2012

Notes on optimizing a deferred renderer

Oh my, I forget to post things... Space Marine, a game that I'm very fond of having been part of. The second third person action done by Relic, and the first multi-platform console game of a studio well known for incredible PC RTS titles. It came out maybe a bit short on content (cuts, time...) but it's a technically excellent game and it's plenty of fun too (it's one of the few games I had fun playing multiplayer on the 360).

Its rendering does most of the things a modern deferred should do, quite a few things that only an handful of other titles manage to pull off (i.e. almost zero latency) and a couple of novel things as well (the way it does Oren-Nayar, its "world occlusion", the DOF/MB filter, the hair lighting trickery and some other details).

The people working on it were a-m-a-z-i-n-g, I was "overseeing" the rendering performance across the platforms and I was surprised to see that we managed to more than double rendering performance in the six months before shipping, to a solid thirty (I would have bet it was not possible, when I joined. They proved me wrong).
Most of the work described in the notes was done near the end of the product (i.e. shadows, post effects, ssao were rewritten from scratch, software occlusion added, SIMD and threading everywhere, I had a list of more than twenty tasks per each platform and I'd say more than 80% of them were done by the end).

This presentation was done a while ago now, it started as something I wrote internally as a post-mortem for other studios to see, then I removed some implementation details and presented it (thanks to Relic's openness when it comes to sharing knowledge) at a very informal meeting of rendering professionals I organize sporadically here in Vancouver. The version I'm uploading was cleaned up even more (well, censored... mostly replaced images with public screenshots of the game) to be able to publish it online... but then forgot, until today, when I got someone asking me for this material again.

It's not much of a "presentation", it's more notes written in powerpoint, as it was originally meant not to be presented live but to just be read by people.

07 October, 2012

Supersampling and antialiasing distance fields

Just found this note cleaning up my stuff, thought I might as well post it...

We had some issues with using signed distance fields for font rendering and antialiasing. The idea is to conceptually similar to doing a two dimentional marching squares and then computing the area of the resulting convex polygon.

If you can't (or don't want to read) my horrible note, the "algorithm" samples four taps of the distance field (use ddx/ddy UV for the width) on a (unit) square and then walks the vertices and edges of the square counterclockwise (first a vertex, then an edge, then the next vertex and so on).

The polygon is constructed by taking the coordinates of all the vertices that are inside the distance field and computing an intersection point for all the edges that are between two in-out vertices. The polygon area (which equals the coverage) is computed incrementally using the determinant method. All unrolled in a shader.

Jason Peng, an incredibly talented UBC student implemented this at Capcom Vancouver. He tells me it worked :)

P.S. You'll notice that I write counterclockwise and then draw all the arrows clockwise... :) Stupid me.