Voronoi Noise
Site Map Feedback

Download:

Up Mosaic Perlin Simplex Voronoi

Stars Moving Voronoi Noise produces very structured random patterns which can be given different characters by manipulating the distance calculations done between random points. Three dimensions are used to generate noise, so animation is possible (using time as the third dimension). This image shows frames taken at z=0 to z=1 in steps of 0.05; and looks like stars.

There are a lot of possible variations from the two enums which select the shape:

  enum DistanceMethod {Length, Length2, Manhattan, Chebychev, Quadratic, Minkowski4, Minkowski5};
  enum VoronoiType {First, Second, Third, Fourth, Difference21, Difference32, Crackle};
The algorithm comes up with four numbers to choose between and VoronoiType lets you specify which one, or which popular combination. The following table shows what the combinations are doing:
VoronoiType
Difference21 Second - Third
Difference32 Third - Second
Crackle Max(1.0, 10*Get(...Difference21);

The DistanceMethod alters both the look and the time taken. Each DistanceMethod will be called 27 times per pixel:
DistanceMethod
Length sqrt(x*x+y*y+z*z); Euclidean (shortest line). Square Root may be slow for some applications.
Length2 (x*x+y*y+z*z) The length squared. Saves the slow Square Root for some calculations.
Manhattan The length of the distance in axial directions (as if travelling around a city).
Chebychev The length of the longest Axial journey.
Quadratic (x*x+y*y+z*z+x*y+x*z+y*z) The sum of everything multiplied by everything else!
Minkowski4 Same as Minkowski(4); pow(x*x*x*x+y*y*y*y+z*z*z*z,0.25);
Minkowski5 Same as Minkowski(0.5);
general Minkowski is very slow:
double Minkowski(p) {return pow(pow(fabs(x), p) + pow(fabs(y), p) + pow(fabs(z), M_E), 1.0/p);}
This is the code used to generate the images:
  for(WORD x=GetWidth(); x--; ) { // Loops are best comparing the counter with zero, so this counts down.
    double u=double(x)/Width; // Calculate the parameter (ratio in the range [0,1]) indicating how far through the loop is.
    for(DWORD y=GetHeight(); y--;) {
      double v=double(y)/GetHeight(); // Calculate the parameter (ratio in the range [0,1]) indicating how far through the loop is.
      BYTE B=BYTE(Round(255*Clamped(0.0, Voronoi::Get(x/10.0,y/10.0, 0.5, Voronoi::Difference21, Voronoi::Quadratic), 1.0))); // Turn the parameter into a Greyscale Level.
      SetPixel(x,y, RGB(B,B,B));
  } }
GetWidth(), GetHeight() and SetPixel are members of CPixelBlock which was used as a base class.
Round and Clamped are declared in Global.h.

The following images show the patterns available. Be aware that the Voronoi::Get method returns values that may be outside the [0,1] range, so the Clamping results in a lot of white on some images, and that the the negatives of the images (reverse black and white) are as important as the versions here:
49 Clamped Variations of Voronoi Noise

The DistanceMethod 'Crackle' is supposed to be white, but to see what lies behind the white, the following images have been autobalanced rather than clamped:
49 Variations of Voronoi Noise
To generate these images, the image was saved using DWORD greyscale values: SetPixel(x,y, Round(10000000*Voronoi::Get(...)) The minumum and maximum values were stored and in a second pass, each DWORD was Mapped to the usual [0,255] range to auto-balance the greyscale levels:

void SetLevels(DWORD Minimum=0, DWORD Maximum=255) { // A Compander (Compressor/Expander)
  DWORD MinLevel=ULONG_MAX, MaxLevel=0;
  for(DWORD* ptr=&Bits[Width*Height-1]; ptr>=Bits; --ptr) {
    if(MinLevel>*ptr) MinLevel=*ptr;
    if(MaxLevel<*ptr) MaxLevel=*ptr;
  }
  for(DWORD* ptr=&Bits[Width*Height-1]; ptr>=Bits; --ptr) {
    *ptr=Interpolate(Parameterize(*ptr, MinLevel,MaxLevel), Minimum,Maximum);
  }
  GreyScale=Maximum;
}
Interpolate and Parameterize are declared in Global.h. There is also a page devoted to Interpolation.


Another Dimension

Voronoi Noise Adding a third dimension allows noise over a three dimensional surface, or 2D animation with time as the third dimension. To create a looping animation, the following code uses z in the Interval [0,1] and uses that to blend between two adjacent noise function cells:

  for(int Frame=20; Frame; --Frame) {
    double z=Frame*1/20.0;
    for(WORD x=GetWidth(); x--;) {
      for(WORD y=GetHeight(); y--;) {
        double d=(1-z)*Voronoi::Get(x/10.0,y/10.0, z  , Voronoi::First, Voronoi::Length2)
                    +z*Voronoi::Get(x/10.0,y/10.0, z-1, Voronoi::First, Voronoi::Length2);
        SetLevel(x,y, Round(255*Clamped(0.0, 1-d, 1.0)));
    } }
    CString S;
    S.Format("Frame%02u.bmp",Frame);
    Save(S);
  }
GetWidth(), GetHeight(), SetLevel() and Save are members of CPixelBlock which was used as a base class.
Round and Clamped are declared in Global.h.


THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.