The idea of sampling is ubiquitous in computer graphics and imaging. A video samples time (e.g. 30 fps = 30 samples per second). A photograph samples an image sensor plane. The process of rasterization involves sampling 2D positions. Ray tracing involves sampling light rays. Lighting integrals involve sampling incident angles to accurately capture lighting effects.
In graphics and imaging, sampling artifacts arise - side effects associated with sampling (e.g. wagon wheel, moiré, jaggies). These artifacts are a product of aliasing, the misidentification of frequency signals.
Aliasing arises when we sample fast-changing (high frequency) signals too slowly. Antialiasing provides a remedy - we filter out high frequencies before sampling. In other words, we apply a low-pass filter.
Let's look at an example of antialiasing in time in the form of a stream of water.
60 FPS, 1/4000 second exposure. This signal is sharp in time (high-frequency), and thus, it causes time aliasing when rendered on 60 FPS.
60 FPS, 1/60 second exposure. This is motion-blurred in time, and no aliasing occurs.
Recall that rasterization is effectively point sampling in space. Given a signal (e.g. continuous triangle), we sample locations on a 2D grid to construct our array buffer pixel values. In this context, we can think of high-frequency signals as sharp edges; in other words, edges of the triangle are where the signal is changing the fastest! Consequently, when we apply a low-pass filter, the high frequency edges are knocked out, thus blurring the edges and minimizing jaggies.
When we apply this antialiasing technique, we end up with a smoother end result. However, we must pay attention to the order in which we apply the blur operation: we want to knock out high frequency signals before we take our samples.
For the rest of this note, we'll take a look at the fundamental reasons as to why this works, and look at implementations of antialiased rasterizations.
When thinking of aliasing and antialiasing, it's important to reintroduce the notion of the frequency domain. Whereas a time-domain graph (or a space-domain grid) shows how a signal changes over time (or space), a frequency-domain graph (or grid) shows how much of the signal lies within a given frequency band over a range of frequencies.
Let's consider the case of two fundamental frequencies - cosine and sine.
If we write these signals as cos(2πfx)
, then we the frequency of the signal is f
. Recall that the frequency, f
, is equal to the reciprocal of the period, t
(f = 1/T
).
The Fourier Transform allows us to represent any function as a weighted sum of sines and cosines. It decomposes a signal into frequencies, converting it from the spatial domain to the frequency domain. The Inverse Fourier Transform allows us to do the reverse.