Yet another AA technique - SDAA

Humus

Crazy coder
Veteran
I have posted a demo of yet another AA technique called SDAA (Second-Depth Anti-Aliasing). This technique uses the depth buffer and a second-depth buffer (i.e. the depths of all backfacing surfaces) to AA the image. The easiest way to get a second-depth buffer is to just switch the pre-z pass to frontface culling and then copy the result to another texture. As it turns out, a second-depth pre-z pass is often more efficient than a regular pre-z pass, depending on the scene of course. In this demo it sure is. The actual AA is done by computing the intersection point of the lines formed by the depth values in the buffer, or depth buffer + second-depth buffer in the silhouette case.

SDAA.jpg


Download demo here:
http://www.humus.name/
 
I haven't looked at this but I assume it's just discovering distance-to-edge data by looking at the slope of the depth deltas as they approach a silhouette edge and otherwise doing the same thing as GBAA? Makes sense and might be a better fit for pre-DX10 hardware (or on cards with very slow geometry shaders) but as you note not all surfaces are nicely modeled with thickness. I've had no end of trouble with this in the realm of shadows :)

The biggest issue I've seen with GBAA so far is that when the scene is suitably complicated you get aliasing in the distance-to-edge buffer itself. While this is expected and no post-process technique is going to magically recover sub-pixel data, the issue with GBAA is that it then interprets this aliased data as noisy offsets, which makes both edges and occasionally surface internals noisier than they had been previously. Sometimes this is actually worse looking than the original aliased image if - say - you have a clean edge that gets complicated topologically at once point, so most of it is anti-aliased but then you get weird speckles somewhere in the middle of it due to the underlying geometry.

Have you played with GBAA in scenes with smaller triangles (JC2 or something say)? The demo scene has really, really large triangles so you don't really notice any of these issues there. Any solutions?

bigtabs: these techniques aren't really the most suitable for DLL injection or control panel overrides, even if those weren't the most evil things ever ;) GBAA requires a geometry shader, SDAA requires an additional pass over the scene and both require some additional storage. They are very easy to integrate into an engine IMHO, but not magically "inject" into a rendering command list. Just let the game developers implement these things as necessary.
 
I haven't looked at this but I assume it's just discovering distance-to-edge data by looking at the slope of the depth deltas as they approach a silhouette edge and otherwise doing the same thing as GBAA?

Yes, the slope of the depth and the slope of second-depth, and finding the intersection point. Once the distance is found the filtering is done the same way as in GBAA.

Have you played with GBAA in scenes with smaller triangles (JC2 or something say)? The demo scene has really, really large triangles so you don't really notice any of these issues there. Any solutions?

One of these days I will update my artwork. ;) I made some effort trying to get GBAA into our current project, but haven't had enough time to put into it, so far I didn't get much further than adding geometry shader support to the engine. I think I may give SDAA a shot though. Should be much quicker since we have pre-z support, although we barely use it.

I noticed the issue even in my demo since a quad is made up of two triangles, and near the tip of a long triangle for a number of pixels you may get no pixels rasterized for the closest triangle to the edge, so instead you get the geometry information from the adjacent triangle, which results in incorrect distance information and some visible artifacts. That could be worked around by encoding some sort of distance information in the vertices such that it doesn't matter which of the two triangles it is grabbing the info from since it should be the same. The good news is that SDAA doesn't suffer from this problem. Although I have yet to test how well SDAA holds together with thin triangles and very dense geometry. Since I need two neighbors left and right chances are triangles smaller than a couple of pixels wide may have trouble. The other problem with SDAA is that you need enough precision in the depth buffer. 16bit was too little for this demo. 24bit works fine though, but I went full 32bit though. I'm not sure if there will be enough precision in a JC2 style game environment.
 
The good news is that SDAA doesn't suffer from this problem.
That's a good point. If you're just treating the two buffers as pure depth information then you've effectively decoupled it from the triangle structure and gone back to analyzing nice "surfaces", which doesn't really have the same problem. It may well be that the issues with thin/one-sided geometry are less than the mesh topology issues that I ran into...

A lot of facade geometry in games tends to be 1-sided, but hey if you can convince them to start changing this for AA then it'll benefit shadows a lot too (really for good shadows objects need some thickness as well) ;)

Unfortunately (fortunately?) this means I might have to go back and implement SDAA now too :)
 
Back
Top