One of the most frequently requested features on the ParaView mailing list has been for anti-aliasing support — that is, the ability to smooth out the jagged edges of lines and polygons that aren’t neatly aligned to pixel boundaries. The image below shows a scene rendered with aliased and anti-aliased edges (click to enlarge). Highly aliased areas are enlarged and compared in the bottom portion of the image to demonstrate the effect.
The anti-aliased image was generated using a technique commonly known as FXAA. The effect of FXAA is quite noticeable on the edges of the orange sphere that intersects the pink cone. While the green lines still retain some of the ‘stair-step’ effect in places, they are significantly smoother.
There are many ways to produce an anti-aliased rendering. However, most techniques aren’t feasible in ParaView: Multi-Sampling (MSAA) would introduce artifacts when rendering in parallel, and Super-Sampling (SSAA) is simply too expensive for complex scenes and parallel communication.
Most anti-aliasing techniques modify the rendering process to smooth out edges as they’re drawn. FXAA, or Fast approXimate Anti-Aliasing, however, is a post-processing technique that is applied to the final image of a scene rendered with aliased edges. This offers several advantages:
- The execution time is dependent on the screen size and not the scene complexity, so it scales well for complex scenes with lots of rendered polygons.
- FXAA does not affect the rendering process. This allows us to perform distributed parallel rendering in ParaView, compose each processor’s contribution, and then anti-alias the final image without introducing seams or other artifacts at the processor boundaries.
- FXAA is implemented in the fragment shader of a single OpenGL full-screen pass, and thus takes advantage of highly parallel GPU resources. The glsl source for the shader is freely available on github.
How does it work?
The FXAA implementation in VTK is an extension of the algorithm described by NVIDIA in their whitepaper. It addresses two types of aliasing:
- Subpixel Aliasing: A single pixel that has high contrast with its immediate neighbors (often caused by specular highlights and shadow effects).
- Edge Aliasing: The jagged, ‘stair-step’ edges produced when an object is rasterized to a display of finite pixels.
Subpixel aliasing is detected by computing the contrast between a pixel and its neighbors. It is corrected by blending an average of the pixel’s 3×3 neighborhood into the pixel’s final color.
Correcting edge aliasing is more complex. First, an edge detection method is used to determine whether the pixel is part of a horizontal or vertical edge. Second, a search is performed along the edge direction to identify the endpoints of the edge (i.e. the extent of the ‘stair’ in the stair-step). Finally, based on the pixel’s distance from the nearest edge endpoint, its color is adjusted to create a gradual blur that runs along the edge, smoothing the jagged appearance of the rasterized edge.
FXAA is disabled by default in ParaView, but can be enabled in the ParaView Settings dialog under Render View >> Antialiasing Options. The default settings for FXAA balance quality with performance, but these can be adjusted to achieve a desired result. Each option has a brief description that explains its effect on the final image:
The addition of this feature was made possible by Timothy Lottes of NVIDIA, who designed the original FXAA algorithm, and the VTK/ParaView implementation was funded by Sandia National Laboratories.
10 comments to New FXAA Anti-Aliasing Option in ParaView/VTK
This is great! Is this feature only working in built-in mode or does it work with remote rendering on paralllel render servers too?
It works for both. For parallel rendering, each processor renders its geometry without any anti-aliasing, and then the client composes them and runs FXAA as a post-processing pass on the composed scene.
We turned this on by default in Tomviz, and it looks great! Thanks for getting this working, and for making it so easy to enable.
Thanks! Glad it’s working for you 🙂
Looks great! What problems did you face implementing MSAA? From what I’ve read online, MSAA is preferred for VR because of the limited resolution (since FXAA is basically selective blurring).
MSAA will no doubt give a better result for typical rendering cases, but in ParaView, it’s not the case. Since ParaView is frequently used for distributed rendering (ie. a ParaView client showing images generated by multiple renderserver instances running on multiple nodes of a supercomputer), MSAA will create artifacts at the processor boundaries, since it must be applied during rendering, and thus before compositing the final image shown on the client. The depth-based composition used by ParaView does not work when a given pixel has partial contributions (due to AA) spread across multiple processors.
However, since FXAA is applied as a post-processing pass, we can render each processor’s contribution without AA, compose them into the final image, and then perform FXAA on the final image without introducing artifacts at the processor boundaries.
BTW, MSAA is also available in VTK (vtkRenderWindow::SetMultiSamples), it’s just not exposed in ParaView for the above reasoning.
Oh I see. I didn’t realize that MSAA was in VTK already!
MSAA seems to be broken in VTK 7.1 RC1: vtkRenderWindow::SetMultiSamples(8) does not activate multisampling anymore.
The same code build against VTK 7.0 and it worked perfectly.
Please make a post on the VTK mailing list (http://www.vtk.org/mailing-lists) or file a bug report (https://gitlab.kitware.com/vtk/vtk/issues) to report issues.
I filled a report here: https://gitlab.kitware.com/vtk/vtk/issues/16875.