Save Expand icon

Ron Valstar

front-end developer

Experiment: Not Perlin

İ wanted some noise. Not Perlin noise, but unprocessed noise, to give these villages some foliage and grass.

There is a way to generate Perlin noise with SVG. But that is overkill for what İ really need. So what İ ended up doing is create a simple method that turns a randomised canvas element into a data-url so it can easily be used as a CSS background.

CSS interpolates

Playing around with this İ noticed that upscaled backgrounds are interpolated.

The image on the left (scaled defaul) is the same image as the one on the right, but interpolated (the right has CSS image-rendering: pixelated;).

Real Perlin (and Simplex) noise use a smoothstep variant for interpolation. Browsers use bilinear interpolation for images. The -bi- is both horizontal and vertical. This looks fine but does have clear artifacts (crosses).

İn terms of random noise, here is what linear interpolation looks like for the first row of pixels in that image. ( to rerender)

And here it is in (a) smoothstep.

You can see that smoothstepping random numbers turns out quite nice. are a bit weird though, but it's less off an 'artifact' than plain linear.

Small sidenote here: Perlin noise is really just the single octave noise interpolation. Stacking noises is really called fractal noise, or fractal Brownian motion. But Perlin noise is often used to denominate everything, even Simplex noise, because it is easier to generalise.

Linear works fine

But even with those linear artifacts we can still create something that resembles Perlin/noise by stacking and multiplying different images.

Early implementations speak off 'octaves' and 'falloff'. Octaves are the number of images, where each next image is doubled in size. Falloff is the weight of each image or octave; we can add either more of the upscaled image for a smoother look, or more of the original size for more grain.

to rerender, or click the to stack/unstack.

It moves

Those are the basics. For the experiment example in the header I also animated the noise by simply moving layers.
That code is below and should just work when you save it to HTML.