Procedural Generation

Generating Textures/Cellular Noise

Building textures
Lets look at the process of building these camo textures, and some other textures. The first thing we do, is build 'difference noise' I based the shader off of a tutorial found at Quantum Pet Shop. I would also suggest looking at the Source Code for these effects, as well as the Source code for the library methods.

This is a noise variation that is built from taking the differences between multiple samples of noise. The output value is 0 when the noises are the same, and 1 when the noises are maximally different (0 and 1 or 1 and 0). This creates an interesting pattern with 'ribbon' like features stretching across the noise field.

NF1 (Noise Field 1)
NF2 (Noise Field 2)
abs(NF1 - NF2)

We can do this a number of times, and compile a bunch of difference noise ontop of itself.

4 layers of difference noise

The next step was is to increase the contrast of difference noise, so that there's only black and white output. This creates two separate regions. One of these regions can be used, and the other can be discarded. Then we do this 3 times, and assign each one a different color.

Clipped Difference Noise

Then, we just composite all of these on top of eachother, and assign a 'background' color.

Combined Clipped Differense Noises

And then, we can change parameters for colors, seed, scale, etc, to generate different textures. View a few example variants Here. The code is included in the source for each page, and this common.js file included in each page.

I also converted this other tutorial on creating Electric arcs. I had to do some research on how the 'curves' and 'levels' filters work in Photoshop.

Electric Ring

So, if I break down this effect, It starts out similar to the camo, with a few layers of difference noise. The difference noise determines the brightness of the pixel. Then, the center is darkened, and the edges are brightened little blending with a radial gradient. Then, the output levels are adjusted. This is a feature from photoshop. The adjustment performed here clamps the brightness value of a pixel into the range (.38, .49), and then stretches that range so that .38 becomes 0, and .49 becomes 1. Then, we switch coloring modes, rather than the brightness determining the color, we divide the brightness value by the distance from the center to that pixel. Then, we apply some adjustment curves to the original brightness value, which makes values close to .5 be the brightest, and values of both 0 and 1 be dark. Then, finally, the coloring changes again, so that there are constants controlling how much the brightness value is multiplied by before being divided by the distance value. The values are (.51, 2.0, 15.0), creating a mostly blue/cyan ring. The values near the middle areas of the ring are very large, leading to both blue and green being present. Areas further away from the middle region are mostly colored using blue, and little to no red is ever present. Here are some discriptions of each cell, moving from left to right, and top to bottom.

  1. Brightness = Raw difference noise
  2. Blended with black-white radial gradient
  3. Output levels adjustment (.38, .49) -> (0.0, 1.0)
  4. Rendering changes to Brightness/Distance (to center)
  5. Pre-divide Brightness value Curves adjustment, .5 region is brightest, (0, 1) are darkest.
  6. Uses the 'color' (.5, 2.0, 15.0) as a blend color

I do a few extra things as well, like rotating the ring over time, and scaling the time of the animation by the distance from the center.

Cellular Noise
Sometimes, we need a different kind of noise, to generate other interesting looking things. We can build a 3d 'voroni distance' noise out of our noise function.

Manhatten Voroni Distance Noise
Closest-Point Voroni Distance Noise
Second-Closest Voroni Distance Noise
"Worley" Voroni Distance Noise
1 - (Above noise)
These are referred to as 'cellular noise', and are a very useful noise 'primitive'. These noises are based off of the distance from the point a pixel is at, to the closest 'feature'. To get these feature points, we sample a hash function at some offset from the original pixel, and use the resulting value from the hash function to offset the position of the 'feature' point from the fixed grid we're sampling on. On the next page, details about how voroni noise works will be looked at and broken down.