This section is part of Hyatt Moore's final project report on Procedural Noise. Here, I chose to examine the Perlin Noise algorithm in greater detail by implementing it in Matlab. The process and results are provided in the following sections.
What is Perlin Noise?
Loosely, Perlin Noise can be described as a means to roughen up the smooth edges and make a computer generated surface look more realistic. This "texture mapping" technique was quickly adopted for use in the film industry; you've probably seen the results in movies such as Jurassic Park, Terminator 2, The Lion King and, yes, Toy Story. The Perlin Noise technique is now routinely used in major software systems ranging from 3-D rendering software such as Softimage and Renderman to image processing in Photoshop, and even appears as a hardware instruction on the Intel Pentium MMX chip. (from [site:http://www.nyu.edu/its/pubs/connect/archives/99fall/lewisimprov.html])
Matlab is an interpretive language, which helps with the development process, but suffers at a lack of speed. It does not offer a practical means of implementing Perlin noise for special effects where speed is a priority. Generating a single channel of noise over a 256x256 took roughly 10 seconds on my first implementation. I was able to double the speed and reduce the time to 5-seconds, but this is still horribly impractical. Never-the-less, Matlab offers a variety of tools by which to examine and analyze the signals/textures that are produced.
The above plots are a 2D slice from a three dimensional implementation of Perlin noise, and are in fact copies of the same run. The color difference between them is a result of using Matlab's jet colormap to highlight the changes. These results are much more stimulating than the traditional uniform noise, be it single channel or not, as compared below.
One of the great advantages of Perlin noise is its scalability. The literature on Perlin noise refers to this scalability in terms of octaves. To demonstrate this several 256x256 pixel views of Perlin noise were generated covering different grid sizes or lattices. A very large grid size looks similar to white noise, yet narrowing down to a small grid with increased sampling (i.e. the same number of sample points but over a smaller area) provides whatever level of detail necessary.
The necessity for using pseudorandom numbers for noise in special effects over true random noise is exemplified in the above plots. A black and white version of the same results is shown on the Lattice Gradient Noises section of the Categories page.
While Perlin's noise is interesting, further perturbation or distortion is helpful in creating more visually pleasing effects.
Fortunately, there have been a variety of ways that Perlin noise is implemented in special effects. Noise has been used in the synthesis of both textures and hypertextures, as well as creating animation paths for gasses and fluids, and more recently human motion. This section covers just a few examples of how Perlin noise has been used.
The majority of special effects require some method of distorting the noise first to make it to alter it from its original form and then applying some further procedure to shape the desired outcome and content, whether it be a texture or an animation. A variety of turbulence, perturbation, and flow functions have come out over the years to accomplish this task.
A common turbulence function, designed by Perlin and implemented here in Matlab, is given below.
function x = turbulence(pos, pixel_size) x=0; scale = 1; while(scale>pixel_size) pos = pos/scale; x = x + noise(pos)*scale; scale = scale/2; end;
At the same time that Perlin's noise was published (in 1985), Ken Perlin also showed how it could be used to create marble textures by using his noise function in conjunction with a turbulence function and a marble coloring function. The results from this algorithm in a Matlab implementation are shown below.
The initial marble texture was too blocky for my taste, and so I have shown the results of low pass filtering this result with several different averaging kernels of increasing size. There is of course some trade off between the detail and smoothness between the kernel sizes.
The Matlab implementation for generating the Marble color, based on Perlin's initial aglorithm, is provided here.
function rgb = marble(pos) rgb = zeros(1,3); x = sin((pos(2)+3.0*turbulence(pos,0.0125))*pi); x = sqrt(x+1)*.7071; rgb(2)=.3+.8*x; x = sqrt(x); rgb(1)= .3 + .6*x; rgb(3)= .6 + .4*x;
In the above code, pos is a three element vector consiting of x,y,z coordinates, and rgb is a 3 element vector consisting of red, green, and blue values ([0, 1]) for the given position pos.
An animation of the Marble forming was rendered at 15 FPS for 30 seconds at 128x128 resolution. A 60 second version was made at 256x256 initially, but failed after hour 10 of rendering. Needless to say, while Matlab is very helpful in developing concepts and algorithms it is not the best tool to use for production work.
A few screen shots of the original 256x256 version are shown here.
Ebert discussed how a glow factor can be introduced to give the appearance of heating and cooling of the marble can be seen as it bands together over time. The results of this experiment were captured in the following short .mov clip.
Although not realistic, the effect does add a nice touch to the animation.
Analysis and Summary
There is definitely a lot to cover when it comes to noise, and while the field is still growing at an incredible rate it is interesting to see that Perlin noise remains a dominant player in the field. This is most likely due to its speed and relative simplicity. In future work I hope to explore some of the other noise functions listed here, particularly Gabor noise, and take a further look at different ways noise is being used. And of course I would like to further explore my own new noise kernel, kernel Hyatt as shown on the categories page.