I was wondering how to generate some nice cloudy like texture with a simple program. I first thought about using the Brownian motion, but of course if one uses it raw, with one pixel representing one movement in time, it's just going to look like a very noisy and grainy picture like this:
|
Normal noise |
There is however a nice continuous representation of the Brownian motion : the Paley-Wiener representation
This can produce an interesting smooth pattern, but it is just 1D. In the following picture, I apply it to each row (the column index being time), and then for each column (the row index being time). Of course this produces a symmetric picture, especially as I reused the same random numbers
If I use new random numbers for the columns, it is still symmetric, but destructive rather than constructive.
It turns out that spatial processes are something more complex than I first imagined. It is not a simple as using a N-dimensional Brownian motion, as it would produce a very similar picture as the 1-dimensional one. But
this paper has a nice overview of spatial processes. Interestingly they even suggest to generate a Gaussian process using a
Precision matrix (inverse of covariance matrix). I never thought about doing such a thing and I am not sure what is the advantage of such a scheme.
There is a standard graphic technique to generate nice textures, originating from Ken Perlin for Disney, it is called simply
Perlin Noise. It turns out that several web pages in the top Google results
confuse simple Perlin noise with fractal sum of noise that Ken Perlin also helped popularize (see his slides:
standard Perlin noise,
fractal noise). Those pages also believe that the later is simpler/faster. But there are two issues with fractal sum of noise: the first one is that it relies on an existing noise function - you need to first build one (it can be done with a random number generator and an interpolator), and the second one is that it ends up being more complex to program and likely to evaluate as well, see for example the code needed
here. The fractal sum of noise is really a complementary technique.
The insight of Perlin noise is to not generate random color values that would be assigned to shades of grey as in my examples, but to generate random gradients, and interpolate on those gradient in a smooth manner. In computer graphics they like the cosine function to give a little bit of non-linearity in the colors. A good approximation, usually used as a replacement in this context is
3x^2 - 2x^3. It's not much more complicated than that,
this web page explains it in great details. It can be programmed in a few lines of code.
|
very procedural and non-optimized Go code for Perlin noise |