Posted on

Table of Contents

Antialiasing

aliasing

Using the centre of a pixel to determine if the pixel should be rendered can cause aliasing.

Some artifacts include:

  • Jaggies (artifacts caused by sampling in space)
  • Moiré (artifacts resulting from down-sampling)
  • Wagon wheel effect (artifacts due to sampling in time)

These artifacts occur when the sampling rate is lower than the actual rate.

Pre-Filtering

To suppress the high-frequency signal, use a low-pass filter:

pre-filtering

But why does pre-filtering then sampling work, whereas sampling then blurring to reduce aliasing does not?

Fourier Transform

By employing the Fourier transform, we can convert a function from the spatial domain to the frequency domain and vice versa: F(ω)=f(x)e2πiωxdx F(\omega) = \int_{-\infin}^{\infin}f(x)e^{-2\pi i\omega x}dx

f(x)=F(ω)e2πiωxdω f(x) = \int_{-\infin}^{\infin}F(\omega)e^{2\pi i \omega x} d\omega

A low-frequency sampling will lose information from a high-frequency signal.

Filtering involves using a filtering kernel for convolution in the spatial domain or multiplying the filtering kernel in the frequency domain.

sampling

Sampling is essentially multiplying by a single-frequency pulse function. This process repeats the original frequency content within a limited frequency range (sampling frequency).

signal-aliasing

Therefore, a lower sampling frequency will cause signal aliasing. A low-pass filter can remove the high-frequency aliasing part to improve the quality of the image.

low-pass

Thus, our filter should be a 1-pixel width low-pass filter to precisely limit the frequency to the image frequency.

Multi-Sample Anti-Alias (MSAA)

Antialiasing through super sampling involves super sampling each pixel (like 2x2) then calculating its 2x2 width low-pass filtered result to use as the color of the pixel.

msaa

However, this method is very costly, with the calculation being n2n^2 times more intensive.

There are also other sampling strategies, such as sharing sampling points among pixels or across the temporal domain.

Similar strategies are employed to handle super-resolution, even with Deep Learning algorithms.

Z-Buffering

Painter's Algorithm: Paint from back to front, overwrite in the framebuffer. It takes O(nlogn)O(n \log n) to sort in depth.

Z-buffering, is pixel-wise painter's algorithm.

  • Store current min. z-value for each pixel.
  • Use a buffer to store depth value
    • frame buffer: color value
    • depth buffer: depth value

For depth, we can use absolute value of z. (smaller depth is closer, larger depth is further).

fn render(&self, frame_buffer: &mut FrameBuffer) {
        for x in 0..frame_buffer.width {
            for y in 0..frame_buffer.height {
                if self.depth < frame_buffer.pixels[x][y].depth {
                    frame_buffer.pixels[x][y].color = self.color;
                    frame_buffer.pixels[x][y].depth = self.depth;
                }
            }
        }
    }

The z-buffer should be initialized to f32::INFINITY. Then during rendering, if current pixel is not occluded, update color and depth of frame.

In this way, we are only finding the minimum value of z-index. The complexity is O(n)O(n) and the calculation is order-free.