TAA, SMAA, or FXAA, which one should you choose? Three options and these are just anti-aliasing technologies we’re talking about. Modern games include a slew of graphics settings to choose from to get the best performance for your hardware. Other than Anti-Aliasing (AA), you’ve got Ambient Occlusion, Screen Space Reflections, Shadows, Texture Filtering, Post-Processing, and more. In this post, we have a look at three of the most popular anti-aliasing techniques and explain how they differ from one another.
Note: You can open the images in another tab by clicking on them to get a better look.
Anti-Aliasing: MSAA vs FXAA vs SMAA vs TAA
Anti-aliasing is one of the primary graphics settings you’ll find in games. You’ve got the traditional MSAA, SSAA, FXAA, and the newer shader-based SMAA and temporal techniques (TAA) that has become the norm. So, what does anti-aliasing do? In short, it gives the image a cleaner look by removing the rough or jagged edges around objects.
Above’s an example of how FXAA (fast approximate anti-aliasing) improves image quality by reducing jaggies. Enlarge the images and see how the second one is notably smoother. Here’s a comparison of how AA impacts your game. Below you can see SMAA in action:
The differences are subtle but can be seen across the entire image. Observe the electric pole and the wiring. They lose the teeth on the edges when SMAA is turned on. The buntings and the vegetation also get the same treatment. However, unlike FXAA, SMAA isn’t too strong. It gets rid of the aliasing without blurring the texture detail.
There are two main types of anti-aliasing techniques:
Traditional sampling-based methods: These include MSAA (Multi-sampling AA) and SSAA (Super Sampling AA), which were popular last-gen and for a good reason. They produce the best image quality (broadly speaking), but the performance hit is severe. They work by rendering the image at a higher resolution and then scaling it down to fit the native resolution. This makes the entire image sharper and more detailed, scaling down the rough edges in the process but not removing them entirely. Here’s an example:
Super Sampling renders the entire image at a higher resolution and then scales it down to fit the target resolution. You are sampling the color and depth samples four times per pixel (refer to the above and below images). The image can be rendered at a higher resolution along both the x and y-axis or one of them. The most commonly used variations of SSAA are 2x and 4x, although 8x and 16 are also technically possible.
The final color of the pixel is determined by taking the average of the four samples. This significantly improves image quality and almost entirely removes the jaggies. On the downside, it’s extremely expensive as you’re essentially rendering the image at 2x or 4x the native resolution.
MSAA, or multi-sampling, is similar to SSAA, except it upscales select areas of the image (the ones prone to aliasing). Like SSAA, the amount of additional sampling varies from 2x to 8x. The rasterization stage of both SSAA and MSAA are identical. Each pixel’s depth (buffer) sample is rendered at Nx, where N is the sampling rate. This includes coverage and occlusion tests (checking which triangles are visible to the viewer/player), done at 2x/4x/8x.
The key difference between MSAA and SSAA arises in the latter half of the pipeline. While SSAA applies the pixel shader to each pixel 2x or 4x, MSAA only executes the pixel shader once every pixel. Essentially, it “multi-samples” around the triangle edges using the coverage and depth tests, smoothening out the edges in the process.
One drawback of MSAA is that it can’t be used with deferred lighting techniques which are quite popular in modern games. Deferred lighting or rendering delays the lighting calculation from the vertex shader to the fragment shader. This saves a lot of performance, as applying lighting on a vertex basis would mean calculating it for several millions of polygons. In the case of fragments, you’re usually calculating it on a fragment basis which generally corresponds to the target output resolution.
Shader-based AA techniques: are more efficient and don’t reduce performance by much. They work by blending neighboring pixels (applying a blur filter) to the scene, making the image smoother but at the same time reducing the sharpness:
FXAA is a good example of how shader-based AA eliminates aliasing but reduces the level of detail. This is because FXAA uses luma or contrast-based edge detection (AA is applied wherever the luma difference is higher than a certain threshold). This isn’t very accurate and tends to blur objects with complex multi-colored patterns. FXAA can also treat sub-pixel AA. This is done by taking a square (3×3) grid and comparing the luma of the outer pixels to that of the central pixel. The smaller the contrast difference between the two, the less aliased it will be.
Newer methods, such as SMAA, greatly reduce blur intensity while eating up most jaggies. However, it suffers the same drawback as MSAA: It doesn’t work with transparent textures.
Morphological Anti-aliasing (MLAA) was one of the first shader-based AA techniques to gain widespread adoption. It is implemented in the last stage of the rendering pipeline (post-processing) and works by searching for discontinuities (see the perpendicular green line at a) and classifies them according to a series of pre-defined patterns/shapes. They are then virtually re-vectorized (blue line), allowing the calculation of the coverage areas (visible triangles/objects) for the involved pixels.
These areas are then used to blend with a neighbor, therefore smoothening them out. The shaded pixels (here a) get a color depending on the surrounding pixels. The edge detection is carried out using depth or luma information, pattern detection, and calculation of coverage areas (given by C). Pattern detection searches the two ends of an edge and analyzes the crossing edges.
One of the primary drawbacks of MLAA is that it doesn’t work well with geometry that contains a lot of thin lines and objects. It was designed to anti-alias silhouettes of objects, and with sharp geometric features, it results in blurry results:
SMAA was introduced to rectify the shortcomings of FXAA (too much blurring) and MLAA (limited coverage), which works well in most scenarios. It works by leveraging edge-detection based on color-specific luma and searching the edges at the top and left of every pixel while retrieving the other two from neighboring pixels.
SMAA uses multiple (1-pixel long for sharp geometry and multiple pixels long for diagonal patterns) crossing lines to enhance edge detection and reduce blurring and improve coverage. With thin lines and objects prone to blurring with FXAA/MLAA, a rounding factor scales the coverage areas obtained by the pixel-long crossing edges.
SMAA is often paired with temporal anti-aliasing (SMAA T1x/T2x), which uses temporal data from neighboring frames to improve the stability and quality of anti-aliasing. Furthermore, unlike MLAA, SMAA uses multiple samples per pixel, allowing for improved image quality. The usual value is two, but four are also used in some cases. The following modes are usually considered viable for SMAA:
- SMAA 1x: includes accurate distance searches, local contrast adaptation, sharp geometric features, and diagonal pattern detection.
- SMAA S2x: includes all SMAA 1x features plus spatial multi-sampling.
- SMAA T2x: includes all SMAA 1x features plus temporal super-sampling.
- SMAA 4x: includes all SMAA 1x features plus spatial and temporal multi/super-sampling
The latest and most popular form of AA is temporal anti-aliasing. TAA focuses on removing temporal aliasing or shimmering. It’s most evident in motion. Temporal aliasing is caused when the frame rate is too low compared to the transition speed of the objects in the scene. This makes the boundaries of the objects appear in motion. TAA works by comparing neighboring frames (temporally) and blending them to create a cleaner image in motion.
The present frame is rendered along with the geometry and shading, after which it is reprojected on the previous image using the jitter offsets and motion vectors. After that, a rectify filter is used to compare the frame and check for any ghosting, and the post-processing effects are applied, thereby completing the frame. Similarly, this frame is used for reconstructing (by reprojection) the next consecutive frame, and the process continues.
As TAA is essentially an approximation of sorts: It uses two images to extrapolate the final image, it also causes a good deal of blurring, losing some texture detail in the process. This is evident in the above image. The image is rendered across different frames at a particular resolution, and with each additional image, a jitter offset (camera shift of a few pixels) is applied. This produces multiple images from a single frame which are then used for supersampling and/or upscaling.
Temporal upscaling uses a similar method to upscale lower-resolution images. The core difference is that, unlike TAA, alternating pixels are rendered in consecutive frames and fill the gaps using interpolation and samples from the neighboring pixels.
- Read more here: NVIDIA DLSS 2.0 vs PS4’s Checkerboard Rendering: Comparing RTX Upscaling with Console Technology
Here’s a comparison of FXAA vs TAA used on the same image:
The main advantages of TAA over FXAA are more pronounced in motion. The “teeth” at the boundaries of the objects appear to be moving when you are in motion in-game. TAA works to smoothen these artifacts, while FXAA simply applies a “Vaseline filter” which, although effective, produces curvy lines that jump around when there’s a transition in the scene.