Daniel Taylor

== Aliasing === A closer look at box filters

This is my kneejerk reaction to aliasing:

img(funny.png)[Oh god it’s aliasing!]

This is probably a little overkill. For example, here are two sinousoids in the horizontal spacial dimension, $\sin(2 \pi 0.49 x)$ and $\sin(2 \pi 0.51 x)$, sampled at each pixel with no filtering (constant frequency response). Can you tell the difference?

imgcmp(cos49.png)[]

I can’t.

That being said, when I do any sort of computer graphics thing, I usually do default to box filters. It’s just real easy to jitter rays in a square, or to render at 4x resolution and then downsample 4x, for example.

I know intellectually that box filters alias, but I don’t think I’ve ever really seen it. So let’s do that.

Miore

The big effect of aliasing is Miore patterns, so let’s see that.

Here is a (red) signal $\sin(2 \pi \frac{7}{8} x)$, box filtered (green), sampled at integer coordinates (white), and then reconstructed (blue).

img(aliasing_graph.png)[]

The blue curve, $\cos(2 \pi \frac{1}{8} x) \text{sinc}(\frac{7}{8}) \approx 0.14 \cos(2 \pi \frac{1}{8} x)$, is very heavily aliased.

The frequency response of a box filter, the sinc function, does heavily attenuate aliased components with a frequency near 1. Also, frequencies near 0.5, or probably any frequencies between 0.5 and 0.7 are going to be hard to identify as aliased in a normal rendering. I picked the frequency of $\frac{7}{8}$ because when multiplying the red base signal by 128 (i.e., a peak-to-peak range of 256), the blue aliased signal gets attenuated down to a peak-to-peak range of $256 * 0.14 \approx 36$, which should be both large enough and bright enough to see with the naked eye, without zooming in.

Here’s a rendering of that pattern, $\sin(2 \pi \frac{7}{8} x)$, texturing a plane 1 unit away from the aperture of a pinhole camera, and a harsh light. So, essentially the exact same situation, but now in 2d. The image plane is sampled 512 times per unit area. The image plane is box filtered, and sampled at the integer coordinates.

img(aliasing_render.png)[]

And, of course, we see $\frac{7}{8}$ cycles/px signal being aliased down to $\frac{1}{8}$ cycles/px, resulting in a wave pattern in both the x and y dimensions.

Flickering

The other big effect of aliasing is flickering when the signal.

img(flickering_graph_animation_opt.gif)[]

The red curve is $\cos(2 \pi \frac{7}{8} (x - t)) + \cos(2 \pi \frac{1}{8} (x - t))$.

The red signal is box filtered to make the green signal: $\cos(2 \pi \frac{7}{8} (x - t)) \text{sinc}(\frac{7}{8}) + \cos(2 \pi \frac{1}{8} (x - t)) \text{sinc}(\frac{1}{8})$.

The green signal is sampled at integers coordinates and sinc-reconstructed to make the blue signal: $\cos(2 \pi (\frac{7}{8} x + \frac{1}{8} t)) \text{sinc}(\frac{7}{8}) + \cos(2 \pi \frac{1}{8} (x - t)) \text{sinc}(\frac{1}{8})$. The $\frac{7}{8}$ frequency component aliases and interfears with the $\frac{1}{8}$ frequency component causing the undulation in the blue signal.

But you can see how I might not notice this in a renderer, right? At the large scale, the blue wave is momving to the right. And on the small scale, the blue undulations peak when the sampled point aligns at the tip.

Without knowing the underlying signal, it’s hard to tell that there’s something wrong. It’s only when you see it in motion that there’s a tiny undulation, or (when aliasing very high frequencies) flickering effect.

Here is that same signal, $\cos(2 \pi \frac{7}{8} (x - t)) + \cos(2 \pi \frac{1}{8} (x - t))$, box filtered and sampled. You can see the undulation above in the gif below with the naked eye.

img(flickering_render_opt.gif)[Look closely!]