Skip to content
JTippetts edited this page Aug 15, 2015 · 1 revision

Accidental Noise Library

A C++ library for the generation of complex noise functions.

Basic Structure

The library is essentially organized as a base kernel class (CKernel) which represents a complex tree of noise functions (generators, modifiers, transformations) ordered in a sequential array. The CKernel interface provides means for constructing the function trees, while the class CNoiseExecutor is used to call the noise function with a specified set of coordinates. Other utilities are provided for visualization of noise functions (mapping them to 2D arrays or 3D volumes).

Introductory Example

Here is a basic example demonstrating the working of the library:

CKernel k;
CArray2Drgba img(512,512);
CInstructionIndex n1=k.simplexBasis(12345)
CInstructionIndex sig=k.sigmoid(n1, k:constant(0), k:constant(2));

SMappingRanges ranges;
ranges.mapx0=1;
ranges.mapy0=1;
ranges.mapx1=6;
ranges.mapy1=6;

mapRGBA2D(SEAMLESS_NONE, img, k, ranges, 0,sig)
saveRGBAArray("img.png", img)

The example begins by creating a kernel, k, and an image to map to, img. Then the method simplexBasis is called on the kernel, to create an instance of a simplex noise function. The simplex noise function is based off a modified version of Ken Perlin's original simplex noise algorithm. The simplexBasis function accepts a single parameter, a random seed.

Next, the example calls the method sigmoid, to create a sigmoid function. The sigmoid function accepts a source (specified as a CInstructionIndex instance, which type is returned by all function creation methods of CKernel). It also accepts an index to a function that specifies the center point of the S curve (in this case, 0) and the ramp, or slope of the curve (in this case, 1). The sigmoid function implements the function (1/(1+exp(k*(t-t0)))), where k is the ramp factor (here, 2) and t0 is the center (here, 0). The sigmoid function takes the output of any function and adjusts it to the range of 0,1.

The function is then mapped to the image, using the function mapRGBA2D. Note that all function chains can be interpreted as either scalar or RGBA data. Functions such as simplexBasis evaluate to a greyscale color as well as their scalar output, whereas functions such as combineRGBA evaluate RGBA colors.

The result of the above snippet:

Simplex Basis

This snippet shows a typical use case of constructing a noise function and mapping it to an image (either grayscale or color, as needed). However, kernels can also be evaluated directly.

CKernel k;
CInstructionIndex fbm1=k.simplefBm(1, 3, 8, 1, 1000, true);
CInstructionIndex sig=k.sigmoid(fbm1, k:constant(2.5), k:constant(5));
CNoiseExecutor vm(k);

double v=vm.evaluateScalar(0.2,0.4);

In this snippet, an instance of the class CNoiseExecutor is constructed, with the kernel, k, passed in the constructor. Then the method evaluateScalar is called on vm with the (x,y) coordinates of the desired location to evaluate. The result:

print(v);
>0.8040224009424

For simplicity, the CNoiseExecutor class implements methods evaluateScalar and evaluateRGBA in 2D, 3D, 4D and 6D flavors. Behind the scenes, these methods construct a CCoordinate object and pass the object to CNoiseExecutor::evaluate(). They are provided for simplicity; evaluate can also be called directly with your own explicitly constructed CCoordinate object. The function mapRGBA2D from the previous snippet constructs a noise executor behind the scenes.

The design of the kernel and noise executor system is such that multiple executors can make use of one kernel. Each executor implements its own cacheing internally, so that, for example, a block or image can be split into multiple pieces and each piece assigned to a thread. Each thread would own its own noise executor, ensuring that cacheing in one thread does not trample cacheing in another. In fact, the map2D functions internally use C++11 threading behind the scenes if the USETHREAD compile-time constant is set.

Clone this wiki locally