- I. Basics: scaling and translation
- II. Classic Clouds and Fractal Noise
- III. Terrain generation and Color Mapping
- IV. Solar flares and Turbulent Noise

*I strongly recommend reading Stefan Gustavson's
Simplex noise demystified for an explanation of
the mathematics of gradient noise. I will be making references
to concepts which he explains far better than I could.*

My goal is to focus on coding for procedural noise. So, let's go straight to a code sample!

The following Java fragment shows a typical usage of SimplexNoise. It is followed by a graphic of the texture generated.

1: BufferedImage image = new BufferedImage(width, height, 2: BufferedImage.TYPE_INT_RGB); 3: WritableRaster raster = image.getRaster(); 4: int[] pixel = new int[3]; 5: 6: double noiseValue; 7: 8: for (int y = 0; y < height; y++) 9: { 10: for (int x = 0; x < width; x++) 11: { 12: noiseValue = SimplexNoise.noise(x / 128f, y / 128f); 13: noiseValue = (noiseValue + 1) / 2; 14: noiseValue *= 256; 15: 16: pixel[0] = (int)noiseValue; // red 17: pixel[1] = pixel[0]; // green 18: pixel[2] = pixel[0]; // blue 19: 20: raster.setPixel(x, y, pixel); 21: } 22: }

**Fig. 1 Resulting texture**

The main task involves iterating through every pixel of the
desired image, making use of the coordinate values of the pixels
as parameters in the noise function call. We do this with
nested *for* loops. The noise function call, on line 12,
returns a *double* that has a value within the range
(-1, 1) which is stored in the variable *noiseValue*.
On lines 13 and 14, noiseValue is transformed into a number
that has a meaningful color value: an integer in the range
[0, 255]. In line 13, we add 1 to the noiseValue, which shifts
the range to (0, 2), then we divide by 2 to *normalize*
the range to (0, 1). If you are defining your colors via a
normalized float, the step on line 14 would be omitted.
In lines 16 through 20, the pixel is defined and used to set
the corresponding pixel in the graphic.

Note that in this example, the *X* and *Y*
values are multiplied by factors of 1/128 prior to serving
as parameters. The exact factor used will vary depending
on the graphical goals, and is directly related to
the locations of the anchor points of the random gradients.
As Gustavson explains, in 2D, the random gradients are
positioned in a triangular gridwork with the base of the
triangles being a unit in length. By using a factor of 1/128,
it will take 128 iterations, i.e., 128 pixels on the screen,
for the X or Y coordinate to progress one unit. Higher
or lower factors can be used to make the values change
more quickly or more slowly over the range of the graphic,
as can be seen in the following diagram.

**Fig. 2 Three scalings, from left to right,
(a) X interval is 1/128, (b) X interval is 1/256 (twice as small), (c) X interval is 1/64 (twice as large). The Y interval remains 1/128
in all three.
**

The scaling factor is usually expressed as a variable, e.g.,

noiseValue = SimplexNoise.noise( x * xScaling, y * yScaling);

When more than one *octave* of noise is being combined,
the most common situation is that each octave has its own set of
scaling factors. We will discuss this more in the next tutorial.

The value used as the scaling factor is usually defined either
to be relative to the screen resolution or to the size of the graphic.
In the first case, the texture always has the same density on the
screen, regardless of the size of the graphic. In the second case,
the texture's density will track the of size of graphic. To achieve
this, the *width* of the graphic is used in the definition
of *xScaling* and the height is used for *yScaling*.
Scaling can become even more sophisticated, creating directional
or even perspective effects, when the value of the scaling factor
is itself a function of *X* or *Y* or some interesting
combination.

Another common operation is to add in a *transpositional*
value to the noise parameters. This could look like the following:

13: noiseValue = SimplexNoise.noise( xTransposition + (x / 128f), yTransposition + (y / 128f) );

**Fig. 1 Two translations, (a) xTranslate = 0
(b) xTranslate = 1. The texture has been shifted to the left.
**

Sometimes, one puts in a translation value to "seed" the texture. This could also be done by adding another dimension and giving that dimension a constant value other than zero. But adding dimensions has a significant cpu cost, and a large, random x or y translation should suffice to guarantee that while the basic aspects of the texture will be similar, the particular details will be unique.

__Implementation of scaling and translation in SiVi__:

Scaling in SiVi has a built in base factor of 1/256. Scalings that
are proportional to the size of the graphic, or are a function of
*X* and/or *Y* have not been implemented,
though I have placed this on the project *wish list*.
*X* and *Y* translations are possible, but
with a limited granularity. Another project *wish list*
item is to allow *X* and *Y* translation to be
animation parameters.

*If you found this tutorial helpful and wish to show your
gratitude, please let me know. Your "thank you" will be greatly
appreciated!*