Table of Contents

Sep 2013

These are some quick & dirty experiments I did with 2D noise. The main article describes 1D noise but the same principles apply here.

This page is rough, and originally only for me; I haven’t polished it like most of my articles, but decided to share it anyway. It doesn’t work on all browsers but should work on desktop Chrome, Safari, and Firefox.

#Generating noise

Background: I wanted to generate maps by mixing together sine waves, using the Inverse Fourier Transform. On the introductory article, I do that step by step, with sample code and diagrams for 1D noise. Here I experiment with 2D noise. For each frequency we need to choose an amplitude. By setting the amplitude to 0 we don’t mix that frequency in at all; by setting it to 1 we mix it with full force.

In 2D there’s an amplitude for every combination of X-frequency and Y-frequency. This is too much to specify by hand. So instead, I have three frequency controls:

  1. freq start: fmin sets the lowest frequency
  2. freq range: frange sets the highest frequency to be fmin + frange
  3. exponent: e shapes the amplitudes in that frequency range (all f in fminfmin + frange) to be f ^ e

See the introductory article for an exploration of the exponent. The TL;DR is that negative exponents are used to generate height map landscapes and positive exponents are useful for placing map features.

Note that there’s some redundancy here. If you only want low frequencies, you could either do that by limiting the frequency range, or by setting the exponent to be low. Similarly, you can limit to high frequencies in two ways. In the next section it’ll be more free form.

freq start:
freq range:

Things to try:

  1. Low freq start, high freq range, start exponent around -1 for pink noise. Move the exponent slider to see how the same sine waves mixed together differently produce different outputs.
  2. Low freq range, exponent near 0, start raising freq start to see how it increases frequencies. You can see what a narrow band of frequencies can produce.
  3. Low freq range, exponent near -1, try different freq ranges to see how adding higher frequencies makes the output “grainier”.

Interpreting the noise as a landscape only works well when using negative exponents. Higher exponents are used for non-landscape uses of noise like textures or object placement.

#Sculpting the frequency spectrum

As explained on the main page, we’re not limited to using exponents. We can use any mix of frequencies. In this section, we’ll start with exponent-shaped frequencies, but then you can change it to anything you want.

Reset the frequency spectrum to use an exponent, then draw on the spectrum chart (log-log scale) to generate 2D noise:

Reset to use an exponent:

Things to try:

  1. Low everywhere except a small spike in the middle. Try spikes on the left or right to see what those frequencies look like.
  2. Try two spikes. Notice how high frequency spikes have a stronger effect than low frequency spikes. Why is that? I think it’s because the low frequency spike is spread out over space so it’s harder to see, but I’m not sure. It could be something in my code.
  3. Try a spike on the very right side. It doesn’t seem to make a difference. Why? I think it’s related to the Nyquist Limit: the very high frequencies produce features that are too fine to be seen in the 128x128 bitmap.

We’re not even limited to frequencies chosen this way; we can choose frequencies separately in the X and Y dimensions. I won’t demo that though.

#Test cases

This section is just for me to test the code across browsers. I start with a 2d sine wave (real component is the sine wave, and imaginary component set to zeros):

Take the FFT of that, real and imaginary components:

The same FFT but showing magnitude and phase components (note that phase becomes meaningless when the magnitude approaches zero, so that’s why it’s so noisy):

Now convert them back to a signal. It should match the original sine wave:

Does it? Yes, with Chrome/Firefox/Safari/IE10. It works on Android/Chrome. It does not on Opera on Mac, nor on Safari on iOS 7.