Deriving simplex noise

Back to Perlin’s simplex noise

Abstract

The simplex noise algorithm, as described by Perlin in SIGGRAPH Course Notes (see references), has remained a bit mystical because the paper does not provide any derivations of the mathematical results. Furthermore, the provided source code is hard to understand because of its heavy optimizations and hard-coding of dimension-specific constants for . To address some of these issues, Gustavson has written a paper to explain the algorithm more intuitively with source code that is easier to understand (see references). However, neither of the papers give a detailed derivation of the mathematical results in n-dimensional space. Such derivations are important in ensuring correctness and in establishing the claimed properties. In this paper we provide the following:

Theory

Identifying simplices with vertex sets

Let , where the points of are affinely independent. Then the convex hull of is a simplex. The convex hull of a -sized subset of is a -simplex. In what follows, we identify a simplex with its vertices. A simplex is called regular if it holds that

where the norm is Euclidean.

Simplicial partitioning of integer cubes

In the following, by a partitioning of we mean a collection of sets which cover and whose pair-wise intersection has Lebesgue measure zero. An integer cube is a set of the form , where . An integer cube is identified with its lower integer coordinates . The simplex noise algorithm assumes that has been partitioned by (not necessarily regular) simplices. To find such a partitioning, first consider a partioning given by the set of by integer cubes. If is an integer cube, then clearly its vertices are given by . We would like to partition the cube with simplices such that each simplex contains as vertices and . Those simplices are given by the set:

where is the i:th standard basis vector. Because the number of permutations of is , there are also simplices in . This procedure gives a partitioning of into simplices. However, these simplices are not regular nor close to being regular.

Scaling along a cube diagonal

Define the regularity of a simplex as the ratio of the length of its shortest edge and its longest edge. It is easily seen that the regularity of all the simplices in the simplicial partitioning of integer cubes is . We would like to have a transformation class which would have a simple form, and then from that class find a transformation which maximizes regularity. Following Perlin, we shall consider a transformation which scales the space along the vector . Such a scaling is given by:

where , , and is the dot product. Applying this scaling to the standard basis vectors gives:

Edge lengths of the transformed simplex

A simplex from an integer cube partitioning is transformed into:

The vector between simplex vertices and , with , is given by:

Its squared length is given by:

Denote . Then:

Choosing to maximize regularity

We would like to choose such that regularity is maximized. Let

.

Then

.

The critical point of (assume ) is found by equating its derivative to zero. Whether it is a maximum or a minimum depends on the value of .

From here on the computation of regularity branches based on the position of the critical point. The following inequalities reveal the dependence of to :

Thus, if it holds that , then is increasing in and the squared regularity is given by:

This is a decreasing function (w.r.t. ) when restricted to , and thus it is maximized by :

If it holds that , then

and

If one picks , then

For all it holds that . I suspect this is the value of which maximizes regularity. However, I haven’t managed to prove this yet. As a result of this scaling transformation all simplices have a minimum edge length of .

Deforming transformation

The transformation from the non-regular simplex partitioning to a more-regular simplex partitioning is linear and is given by the matrix :

It can be shown that the inverse matrix of is given by:

These are the transformations that seem to be used in the original algorithm. However, the problem with these transformations is that the minimum simplex edge length varies with dimension. This in turn implies that the feature size varies with dimension. Therefore, it is better to apply an additional uniform scaling, which expands distances but does not affect angles. Since the minimum length of the simplex edges is , the minimum edge length of 1 is obtained by multiplying with :

Containing simplex

Assume the space is partitioned according to the more-regular simplicial partitioning as described above. Given a point , we would like to obtain the vertices of that simplex which contains .

This is easily solved by transforming the vertices of the simplices to the integer grid. This works because containment is invariant to linear transforms. This transform was already given as the matrix . It is worthwhile to expand the matrix-vector multiplication because of the simple structure of the matrix:

where . The simplicity of this transformation is not a coincidence: the simplex partitioning was specifically chosen (by Perlin) to yield this kind of transformation. The original algorithm does not have the factor.

Vertices of the containing simplex

Clearly the containing cube for a point is given by

.

The simplices inside the cube can be identified with traversals in , such that the traversal begins from and ends to , where one is only allowed to move along standard basis axes and no backing is allowed. It is easily seen that the number of different traversals is , and that the path contains exactly vertices.

Let , . Further, order the components of into descending order . Then the vertices of the containing simplex are given by . These (n + 1) vertices can be mapped back to the regular simplex space by using the transformation :

where .

Scalar fields

Consider the more-regular simplex space again. Each simplex vertex in this space is associated with a gradient vector. This is the gradient of the noise function at that point. The noise function itself is zero at each vertex. The gradient vector of a given vertex defines a scalar field centered on by:

This scalar field is attenuated by a spherically symmetric function centered on :

where is the percentage of the minimum simplex edge length after which must have been attenuated to zero. Because of the normalization of the simplex edge length, we have and thus the expression for simplifies to:

The product of the scalar functions and , centered on , is given by:

Choosing

The must be chosen appropriately: the support of the function must be such that it is contained in the union of those simplices which are connected to the given vertex. If this were not the case, then it would not be sufficient to evaluate only surrounding vertices for a given point. Out of the possible values for we want the largest one. This is given by such that , where is the height of a regular simplex of the minimum edge length :

Thus

and

The idea is that the true height of the simplex must be greater than the height of a regular simplex with minimum edge length.

Simplex noise function

Let be the set of all simplex vertices. The noise function is given by:

‘’text(noise)(x) : RR^n -> RR : text(noise)(x) = sum_{i = 1}^oo e(x - v_i)

Because has bounded support, this sum actually contains only non-zero terms: these terms are those corresponding to the vertices of the simplex containing .

Problems with the original algorithm

Difference to the original attenuation function

The attenuation function we give differs from that given by Perlin for :

However, this function is erroneous: its support leaks into neighboring simplices. This is because the squared height of the simplex in is given by:

which is less than 0.6.

Diminishing support of in higher dimensions

From the given formulae it is evident that as dimension grows, more and more of the scalar field inside the simplex is zero. For example, in , only 42% of the shortest edge of a simplex is covered by the scalar field of its either end-vertex. This means that 16% of the edge has zero, which implies that there is considerable amount of volume inside the simplex which has zero. In the limit, as dimension increases, is zero almost everywhere.

This is a fundamental restriction of the simplex noise algorithm: it isn’t suited for higher dimensions. However, an open question (to me) is: what is the highest dimension in which the results are still acceptable? Clearly the result in and in higher dimensions is not acceptable. On the other hand, from practical tests it can be seen that the result in (e.g. time-varying 3d-noise) is still good. The question then is if the maximum acceptable dimension is 4, 5, or 6?

Still of exponential complexity

One major feature of simplex noise was supposed to be that it does not have exponential dependence to dimension. However, the algorithm that Perlin uses to compute the pseudo-random gradient index seems (to me) to have exponential dependence to dimension. This is why we use a traditional table of permutation values instead (of exponential size), as given by the GradientField class.

Acknowledgements

‘Hagman’ and ‘Tonico’ from the newsgroup sci.math helped me with finding the transformed simplex edges with minimum and maximum length. The name of the thread was Minimize and maximize.

References

Real-Time Shading SIGGRAPH Course Notes, Chapter 2: Noise Hardware, Ken Perlin, 2001.

Simplex Noise Demystified, Stefan Gustavson, 2005.

See also

Gradient field