SSAA - Antialiasing
I got inspired by a thread on GameDev by Styves to work on a screen-space AA post-process. Unfortunately the algorithm outlined in this thread would not work for me, or at least only partially.
I had the idea of blurring a picture's edge by averaging samples along its direction a long time ago but never thought it would give meaningful enough results to bother try it out. Implementing the GameDev filter gave me just the opportunity to try that approach out. Please note that both this filter and Styves one are very close and only differ marginally.
The Filter
This filter is extremely short and simple. It should not cost much more than a fullscreen 1x1 gaussian blur pass. The texture reads are very localized and the arithmetic are close to zero. The basic idea is to estimate the tangent to the edge the current fragment is sitting on and to average a few blur samples along that direction to approximate AA.
Here is the shader used to take the shots on this page:
-
float lumRGB(vec3 v)
-
{ return dot(v, vec3(0.212, 0.716, 0.072)); }
-
-
void main()
-
{
-
vec2 UV = gl_FragCoord.xy * inverse_buffer_size;
-
-
float w = 1.75;
-
-
float t = lumRGB(texture2D(source, UV + vec2(0.0, -1.0) * w * inverse_buffer_size).xyz),
-
l = lumRGB(texture2D(source, UV + vec2(-1.0, 0.0) * w * inverse_buffer_size).xyz),
-
r = lumRGB(texture2D(source, UV + vec2(1.0, 0.0) * w * inverse_buffer_size).xyz),
-
b = lumRGB(texture2D(source, UV + vec2(0.0, 1.0) * w * inverse_buffer_size).xyz);
-
-
vec2 n = vec2(-(t - b), r - l);
-
float nl = length(n);
-
-
if (nl < (1.0 / 16.0))
-
gl_FragColor = texture2D(source, UV);
-
-
else
-
{
-
n *= inverse_buffer_size / nl;
-
-
vec4 o = texture2D(source, UV),
-
t0 = texture2D(source, UV + n * 0.5) * 0.9,
-
t1 = texture2D(source, UV - n * 0.5) * 0.9,
-
t2 = texture2D(source, UV + n) * 0.75,
-
t3 = texture2D(source, UV - n) * 0.75;
-
-
gl_FragColor = (o + t0 + t1 + t2 + t3) / 4.3;
-
}
-
}
Results
While these screenshots might not show it very well the filter tends to eat sharp edges a bit so the sample weights might need to be lowered depending on your source material. The filter also does not carry any sub-pixel information and as such cannot help with edge shimmering. So, far from being the deferred shading AA silver bullet it still bares some interest as it really bring a lot of visual comfort when used on moving images.
A possible extension to alleviate edge shimmering issues is to use temporal AA by jittering the projection matrix along a specific sub-pixel pattern. Crysis 2 and Halo: Reach seem to be using such a combination with very good results.

Aliased/SSAA

SSAA saves the day.
In motion
The following videos were taken with the SSAA filter enabled which, if you can bare the Youtube quality, provides a lot of visual comfort when put in motion.
Mediécross on the latest GameStart build.
Brute force rendering 4000 trees with volumetrics.
- Emmanuel Julien's blog
- Log in or register to post comments