Click here to Skip to main content
15,123,923 members
Articles / Programming Languages / C#
Posted 6 Nov 2014


49 bookmarked

Procedural seamless noise texture generator

Rate me:
Please Sign up or sign in to vote.
4.98/5 (39 votes)
3 Feb 2015CPOL4 min read
Presentation and testing of some procedural bitmap creation algorithms .


I used the basis of this article in the tool you can find :


For some stuff I get involved concerning run time planets generation I faced procedural seamless texture generation. To create a planet at run time is foundamental to manage seamless texture. A seamless texture can work as greyscale highmap and/or landscape texture and/or atmosferic effects.

Searching the web I found some well known tecniques like perlin noise ( or fractal noise.

So I decided to arrange a c# "sandbox" small project to experiment some texture generation algorithms, to test performance , and so on. In particular I implemented a Perlin noise generator using resources from web (references will follow), after that I've created some recoursive algoritms that can reach, in my opinon, sadisfactory effects compared to Perlin, at a good performance cost.  Here I'm going to share some stuff. 



I implemented Perlin noise studing these web sources : and . I'm not going to explain Perlin noise , first reason I'm not so smart to explain something I merely understand better than the links above.

Another (this time easy) thing usefull before going ahead is to know what a grayscale image is and how usefull it is for define a heightmap. At the same time is usefull to know how to use the alpha chanell of an image , for example to add clouds on a predefined sky.

The basic idea is to draw on a random sub region of the image a light grey rectangle (let's call it a "box") covering the sub region. After that we calculate n random point near the center of first box , we reduce box size (i.e by half) and we repeat for the n small boxes. Every time we draw a box we add its grey delta to the preexistents pixels.

In the sequence below we start with 2 recursion calls and we end with 20 recursion call. For the last image we repeat it 7 times and we reduce the grey delta to make vanishing the bigger boxes.

Finaly, the textures created are seamless and perfectly tileable

Using the code

The main recursive method of Contoli noise is very simple :


private void printQuad(float [,] Values, int wid, int hei,int x, int y, int boxSize, int deepness, int delta) {

            if (deepness > 0 && boxSize>=1)
                for (int i = -boxSize/2; i < boxSize/2; i++)
                    for (int j = -boxSize / 2; j < boxSize / 2; j++)
                            /*seamless management start*/
                            int pixX = (x + i) % wid;
                            int pixY = (y + j) % hei;
                            if (pixX < 0)
                                pixX = wid + pixX;
                            if (pixY < 0)
                                pixY = wid + pixY;
                            /*seamless management end*/

                            Values[pixX, pixY] = Values[pixX, pixY] + delta; // add value

                    int xx = r.Next(x, x + boxSize);
                    int yy = r.Next(y, y + boxSize);
                    printQuad(Values, wid, hei, xx, yy, boxSize / 2, --deepness, delta);




Values is the bidimensional array of float representing the image pixels

wid and hei are the image dimension

and are the center point coords of the box

boxSize is the size of the rectangle

deepness how deep in recursion are now

delta how many grey scale we add over existing values. (It represent the delta height)

Stopping the recursion : 

if (deepness > 0 && boxSize>=1)

we stop the recursion if we are too deep or if box size reachs zero.

To call it ;

r = getrRandom(); //r is public Random class accessed by all methods
for (int nr = 0; nr < N_Repetitions; nr++) {
    //get a random point
    int x = r.Next(0, wid - 1);
    int y = r.Next(0, hei - 1);

    printQuad(Values, wid, hei, x, y, box_size, Godeep, d);

updBitmap(Values, tmp, grayScale.Checked);
pictureBox1.Image = tmp;

updBitmap converts the Values array in a greyscaled bitmap.

getRandom initialize the random number generator used inside printQuad.

N_Repetitions is self explained.

The application:

The Contoli Noise Methods:

Quad : the simplest already discussed;

Circ : draws circles instead of rectangles, we get a better effect keeping recursion deepness low;

Func ; draws a 2 variable function instead of rectangles. Actualy the function is a Torus ( .

Quad (left) VS Circ (right): 

The torus example: 1 recursion deepnes vs 33 recursion deepnes. 

General note: when incrementing "recursion" value is good to decrement "delta color" value.

Using the printFunc code. 

f func  = (x1,y1) => (float)Math.Sqrt((0.4f * 0.4f - Math.Pow((0.6f - Math.Sqrt(x1 * x1 + y1 * y1)), 2)));//TORUS

printFunc(Values, wid, hei, x, y, box_size, Godeep, d,func);
useValueArray = true;

printFunc accepts a function f delegate. If you don't like TORUS You can redefine it the way you want.

Example for paraboloid:

f func =  (x1,y1) => 1f + (float) ((x1*x1)/1f + (y1*y1)/1f) * -1f; //PARABOLOID

In the "Distance alg." section I present a set of algorithms to generate effects over a bitmap using tecniques based on distances from a set of random points. It's work in progress.

Voronoi diagram

In the Voronoi section we can experiment some implementations of the procedural space tesselation, based on Voronoi idea. The basic idea is : 1) take a random set S of points on a plane; 2) every point "s" of S defines a region "r" on the plane where each point in the region "r" is the closest to point "s" (harder to explain tha understand) 3) use some random color (grayscale) to paint each region (or the region borders) 4) add some coding to keep all the stuff "seamless"

The examples:

The code:

private void Voronoi(float[,] Values, int wid, int hei, int[,] points)
    for (int i = 0; i < wid; i++)
        for (int j = 0; j < hei; j++)
            float minDist = Math.Min(wid,hei);
            int minV = 0;
            for (int p = 0; p < points.GetLength(0); p++) {
                int pX = points[p, 0];
                int pY = points[p, 1];
                int pV = points[p, 2]; //0..255
                Double Dist1X = Math.Abs((i - pX));
                Double Dist1Y = Math.Abs((j - pY));
                Double Dist2X = wid - Dist1X;
                Double Dist2Y = hei - Dist1Y;
                /*to grant seamless I take the min between distX and wid-distX
                 |                       |
                 |                       |     ----------- = Dist1X
                 |...i-----------X.......|     ..........  = Dist2X
                 |                       |
                Dist1X = Math.Min(Dist1X, Dist2X);
                /*to grant seamless I take the min between distY and hei-distY*/
                Dist1Y = Math.Min(Dist1Y, Dist2Y);
                float dist = (float)Math.Sqrt(Math.Pow(Dist1X, 2) + Math.Pow(Dist1Y, 2));
                if (dist < minDist) {
                    minDist = dist;
                    minV = pV;
            Values[i, j] = minV;


3D Noise

Going 3d. I added a 3d implementation of contoli noise and voronoi noise. To test it simply push "Start 3d noise" , wait some time depending on the parameters , enjoy.

Some explanation , in this case the 3rd dimension is TIME, so we get an "animated" noise. If you comapare printQuad3D with printQuad you'll find the 3rd dimension management. Obviosly, even the 3rd dimension is seamless, and let the animation to loop without cuts.

Animation demo links:

Quad 3d noise:

Circ 3d noise:

Voronoi animations



First version.

9-NOV-2014 : added VORONOI section.

12-NOV-2014 : added 3D Noise section.

14-NOV-2014 : added 3d noise demos youtube links


This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


About the Author

andrea contoli
Software Developer
Italy Italy
No Biography provided

Comments and Discussions

QuestionBitmap output Pin
Member 1446187324-May-19 5:06
MemberMember 1446187324-May-19 5:06 
QuestionStarfield generator Pin
Ihor Salnikov6-Apr-15 5:15
MemberIhor Salnikov6-Apr-15 5:15 
AnswerRe: Starfield generator Pin
andrea contoli6-Apr-15 7:54
Memberandrea contoli6-Apr-15 7:54 
GeneralRe: Starfield generator Pin
Ihor Salnikov6-Apr-15 8:08
MemberIhor Salnikov6-Apr-15 8:08 
QuestionMy vote of 5! Pin
Volynsky Alex12-Nov-14 5:04
professionalVolynsky Alex12-Nov-14 5:04 
GeneralMy vote of 5 Pin
Stylianos Polychroniadis11-Nov-14 12:00
MemberStylianos Polychroniadis11-Nov-14 12:00 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.