# Random, noise and dithering

### Noise

* [Perlin noise — Wikipedia](https://en.wikipedia.org/wiki/Perlin_noise)
* [Value noise — Wikipedia](https://en.wikipedia.org/wiki/Value_noise)
* [Gradient noise — Wikipedia](https://en.wikipedia.org/wiki/Gradient_noise)
* [A SciPy implementation of the void-and-cluster method for generation of blue noise textures with arbitrary dimension](https://github.com/MomentsInGraphics/BlueNoise)
* [Improved Noise reference implementation](http://mrl.nyu.edu/~perlin/noise/)
* [Perlin Noise](http://wayback.archive.org/web/20160510013854/http://freespace.virgin.net/hugo.elias/models/m_perlin.htm)
* [Value Noise and Procedural Patterns: Part 1 (Introduction)](http://www.scratchapixel.com/lessons/procedural-generation-virtual-worlds/procedural-patterns-noise-part-1)
* [Perlin Noise: Part 2 (Perlin Noise)](http://www.scratchapixel.com/lessons/procedural-generation-virtual-worlds/perlin-noise-part-2)
* [Quasimondo - Mario Klingemann's Flash Blog: Optimizing Perlin Noise](http://www.quasimondo.com/archives/000672.php) - see <http://www.quasimondo.com/examples/OptimizedPerlin.as>
* [The Perlin noise math FAQ](https://mzucker.github.io/html/perlin-noise-math-faq.html)
* [advanced perlin noise - Inigo Quilez :: fractals, computer graphics, mathematics, demoscene and more](http://www.iquilezles.org/www/articles/morenoise/morenoise.htm)
* [Making noise by Ken Perlin](http://web.archive.org/web/20160422091821/http://www.noisemachine.com/talk1/)
* [Free blue noise textures](https://web.archive.org/web/20231012164354/http://momentsingraphics.de/BlueNoise.html) - [Calinou/free-blue-noise-textures: Free 2D, 3D and 4D blue noise textures from the Moments in Graphics blog](https://github.com/Calinou/free-blue-noise-textures) See also [The problem with 3D blue noise](https://web.archive.org/web/20230909063725/http://momentsingraphics.de/3DBlueNoise.html)
* [implementation - How is Perlin-noise in flash implemented? - Stack Overflow](https://stackoverflow.com/questions/8467685/how-is-perlin-noise-in-flash-implemented) - "Flash implementation is \[...] based on integer calculations rather than floats. This would explain why the rendering is fast"
* [Humus - 3D](http://www.humus.name/index.php?page=3D\&ID=29) - Perlin noise in a fragment program
* [Noise-Based Particles, Part I at The Little Grasshopper](http://prideout.net/blog/?p=63) and [Noise-Based Particles, Part II at The Little Grasshopper](http://prideout.net/blog/?p=67)
* [Quasimondo - Mario Klingemann's Flash Blog: Hydra: Noise](http://www.quasimondo.com/archives/000658.php) - sine noise
* [Inigo Quilez :: fractals, computer graphics, mathematics, demoscene and more](http://www.iquilezles.org/www/articles/morenoise/morenoise.htm) - advanced value noise
* [Inigo Quilez :: fractals, computer graphics, mathematics, demoscene and more](http://www.iquilezles.org/www/articles/voronoise/voronoise.htm) - voronoise. Use [Voronoi](https://github.com/mems/calepin/blob/main/Algorithms/Random,%20noise%20and%20dithering/Voronoi/README.md)
* [4D Noise Visualizer](http://dyadstudios.com/code/4dnoise/) - 4D noise with GLSL shader. Use a cube with 50x50x50 vertices
* [Playing With Chaos: The Book](http://www.playingwithchaos.net/)
* [Simplex noise - Wikipedia](https://en.wikipedia.org/wiki/Simplex_noise)
* [jwagner/simplex-noise.js: A fast simplex noise implementation in Javascript.](https://github.com/jwagner/simplex-noise.js)

```as3
function Noise(int x, int y)
{
	int n = x + y * 57;
	n = (n<<13) ^ n;

	return ( 1.0 - ( (n * (n * n * r1 + r2) + r3) & 0x7fffffff) / 1073741824.0);
}
```

```glsl
// 1D, 2D & 3D Value Noise
// From http://editor.thebookofshaders.com/?log=170202213311
// Based on Morgan McGuire @morgan3d
// https://www.shadertoy.com/view/4dS3Wd
float noise (in vec2 _st) {
    vec2 i = floor(_st);
    vec2 f = fract(_st);

    // Four corners in 2D of a tile
    float a = random(i);
    float b = random(i + vec2(1.0, 0.0));
    float c = random(i + vec2(0.0, 1.0));
    float d = random(i + vec2(1.0, 1.0));

    vec2 u = f * f * (3.0 - 2.0 * f);

    return mix(a, b, u.x) +
            (c - a)* u.y * (1.0 - u.x) +
            (d - b) * u.x * u.y;
}
```

* <http://www.connectedpixel.com/blog/texture/wood>

```c
/* coherent noise function over 1, 2 or 3 dimensions */
/* (copyright Ken Perlin) */

#include <stdlib.h>
#include <stdio.h>
#include <math.h>

#define B 0x100
#define BM 0xff

#define N 0x1000
#define NP 12   /* 2^N */
#define NM 0xfff

static p[B + B + 2];
static float g3[B + B + 2][3];
static float g2[B + B + 2][2];
static float g1[B + B + 2];
static start = 1;

static void init(void);

#define s_curve(t) ( t * t * (3. - 2. * t) )

#define lerp(t, a, b) ( a + t * (b - a) )

#define setup(i,b0,b1,r0,r1)\
	t = vec[i] + N;\
	b0 = ((int)t) & BM;\
	b1 = (b0+1) & BM;\
	r0 = t - (int)t;\
	r1 = r0 - 1.;

double noise1(double arg)
{
	int bx0, bx1;
	float rx0, rx1, sx, t, u, v, vec[1];

	vec[0] = arg;
	if (start) {
		start = 0;
		init();
	}

	setup(0, bx0,bx1, rx0,rx1);

	sx = s_curve(rx0);

	u = rx0 * g1[ p[ bx0 ] ];
	v = rx1 * g1[ p[ bx1 ] ];

	return lerp(sx, u, v);
}

float noise2(float vec[2])
{
	int bx0, bx1, by0, by1, b00, b10, b01, b11;
	float rx0, rx1, ry0, ry1, *q, sx, sy, a, b, t, u, v;
	register i, j;

	if (start) {
		start = 0;
		init();
	}

	setup(0, bx0,bx1, rx0,rx1);
	setup(1, by0,by1, ry0,ry1);

	i = p[ bx0 ];
	j = p[ bx1 ];

	b00 = p[ i + by0 ];
	b10 = p[ j + by0 ];
	b01 = p[ i + by1 ];
	b11 = p[ j + by1 ];

	sx = s_curve(rx0);
	sy = s_curve(ry0);

#define at2(rx,ry) ( rx * q[0] + ry * q[1] )

	q = g2[ b00 ] ; u = at2(rx0,ry0);
	q = g2[ b10 ] ; v = at2(rx1,ry0);
	a = lerp(sx, u, v);

	q = g2[ b01 ] ; u = at2(rx0,ry1);
	q = g2[ b11 ] ; v = at2(rx1,ry1);
	b = lerp(sx, u, v);

	return lerp(sy, a, b);
}

float noise3(float vec[3])
{
	int bx0, bx1, by0, by1, bz0, bz1, b00, b10, b01, b11;
	float rx0, rx1, ry0, ry1, rz0, rz1, *q, sy, sz, a, b, c, d, t, u, v;
	register i, j;

	if (start) {
		start = 0;
		init();
	}

	setup(0, bx0,bx1, rx0,rx1);
	setup(1, by0,by1, ry0,ry1);
	setup(2, bz0,bz1, rz0,rz1);

	i = p[ bx0 ];
	j = p[ bx1 ];

	b00 = p[ i + by0 ];
	b10 = p[ j + by0 ];
	b01 = p[ i + by1 ];
	b11 = p[ j + by1 ];

	t  = s_curve(rx0);
	sy = s_curve(ry0);
	sz = s_curve(rz0);

	#define at3(rx,ry,rz) ( rx * q[0] + ry * q[1] + rz * q[2] )

	q = g3[ b00 + bz0 ] ; u = at3(rx0,ry0,rz0);
	q = g3[ b10 + bz0 ] ; v = at3(rx1,ry0,rz0);
	a = lerp(t, u, v);

	q = g3[ b01 + bz0 ] ; u = at3(rx0,ry1,rz0);
	q = g3[ b11 + bz0 ] ; v = at3(rx1,ry1,rz0);
	b = lerp(t, u, v);

	c = lerp(sy, a, b);

	q = g3[ b00 + bz1 ] ; u = at3(rx0,ry0,rz1);
	q = g3[ b10 + bz1 ] ; v = at3(rx1,ry0,rz1);
	a = lerp(t, u, v);

	q = g3[ b01 + bz1 ] ; u = at3(rx0,ry1,rz1);
	q = g3[ b11 + bz1 ] ; v = at3(rx1,ry1,rz1);
	b = lerp(t, u, v);

	d = lerp(sy, a, b);

	return lerp(sz, c, d);
}

static void normalize2(float v[2])
{
	float s;

	s = sqrt(v[0] * v[0] + v[1] * v[1]);
	v[0] = v[0] / s;
	v[1] = v[1] / s;
}

static void normalize3(float v[3])
{
	float s;

	s = sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
	v[0] = v[0] / s;
	v[1] = v[1] / s;
	v[2] = v[2] / s;
}

static void init(void)
{
	int i, j, k;

	for (i = 0 ; i < B ; i++) {
		p[i] = i;

		g1[i] = (float)((random() % (B + B)) - B) / B;

		for (j = 0 ; j < 2 ; j++)
			g2[i][j] = (float)((random() % (B + B)) - B) / B;
		normalize2(g2[i]);

		for (j = 0 ; j < 3 ; j++)
			g3[i][j] = (float)((random() % (B + B)) - B) / B;
		normalize3(g3[i]);
	}

	while (--i) {
		k = p[i];
		p[i] = p[j = random() % B];
		p[j] = k;
	}

	for (i = 0 ; i < B + 2 ; i++) {
		p[B + i] = p[i];
		g1[B + i] = g1[i];
		for (j = 0 ; j < 2 ; j++)
			g2[B + i][j] = g2[i][j];
		for (j = 0 ; j < 3 ; j++)
			g3[B + i][j] = g3[i][j];
	}
}
```

#### Curl Noise

Aka 3D noise

* <https://github.com/cabbibo/glsl-curl-noise>
* [Shifting sands: Intro to Curl Noise](http://petewerner.blogspot.fr/2015/02/intro-to-curl-noise.html) - see [Curl Noise Slides](https://raw.githubusercontent.com/petewerner/misc/master/Curl%20Noise%20Slides.pdf)

#### Sinusoids combination

Could use [Diamond-square algorithm](https://github.com/mems/calepin/blob/main/Algorithms/Random,%20noise%20and%20dithering/Algorithms/README.md#diamond-square) to do the same effect, but often use a combination of multiple sinusoids

* [Plasma effect — Wikipedia](https://en.wikipedia.org/wiki/Plasma_effect)
* [0ldskool Plasma Effect - Bidouille.org](http://www.bidouille.org/prog/plasma)

### Dithering

* [Dither — Wikipedia](https://en.wikipedia.org/wiki/Dither)
* [Ordered dithering — Wikipedia](https://en.wikipedia.org/wiki/Ordered_dithering)
* [Color quantization — Wikipedia](https://en.wikipedia.org/wiki/Color_quantization)
* [Image Dithering: Eleven Algorithms and Source Code - Tanner Helland (dot) Com](http://www.tannerhelland.com/4660/dithering-eleven-algorithms-source-code/)
* [//game dev log of martins upitis: GLSL dithering](http://devlog-martinsh.blogspot.fr/2011/03/glsl-dithering.html)
* [Posterization — Wikipedia](https://en.wikipedia.org/wiki/Posterization)
* [Quantization -- IM v6 Examples](http://www.imagemagick.org/Usage/quantize/#ordered-dither)
* [JS Bin - Collaborative JavaScript Debugging](http://jsbin.com/iXofIji/2/edit?html,css,js,output)
* [OpenSource Image Dithering for AS3. (demo+source). | UnitZeroOne](http://unitzeroone.com/blog/2008/05/06/opensource-image-dithering-for-as3-demosource/) [imageditheringas3](https://code.google.com/archive/p/imageditheringas3/)
* \[Sphere surface uniform random sampling]\(Sphere surface uniform random sampling.html) - see [Román Cortés » Furbee - My Js1k Spring ‘13 entry](http://www.romancortes.com/blog/furbee-my-js1k-spring-13-entry/)
* [Floyd Steinberg dithering](https://codepen.io/nicoptere/pen/waPOOm)

Atkinson dithering:

* [gazs/canvas-atkinson-dither](https://github.com/gazs/canvas-atkinson-dither)
* [Atkinson dithering - Wikipedia](https://en.wikipedia.org/wiki/Atkinson_dithering)

### Random

Aka random number, pseudo random number (PRN)

See also [Noise](#noise)

* [nquinlan/better-random-numbers-for-javascript-mirror: A direct mirror of Johannes Baagøe's wiki on implementations of Randomness in Javascript.](https://github.com/nquinlan/better-random-numbers-for-javascript-mirror)
* [Poisson distribution — Wikipedia](https://en.wikipedia.org/wiki/Poisson_distribution)
* [Better, smaller and faster random number generator](http://www.rgba.org/articles/sfrand/sfrand.htm)
* unsigned 32-bit seed `n`, `n*=0x9e3779b1;` (`0x9e3779b1` is just a large prime number specified in hexadecimal). See [14 Character Random Number Generator](http://theorangeduck.com/page/14-character-random-number-generator)
* [Inigo Quilez :: fractals, computer graphics, mathematics, demoscene and more](http://www.iquilezles.org/www/articles/sfrand/sfrand.htm) - float, small and random
* [When Random Numbers Are Too Random: Low Discrepancy Sequences « The blog at the bottom of the sea](https://blog.demofox.org/2017/05/29/when-random-numbers-are-too-random-low-discrepancy-sequences/)
* [nquinlan/better-random-numbers-for-javascript-mirror: A direct mirror of Johanne Baagøe' wiki on implementation of Randomnes in Javascript.](https://github.com/nquinlan/better-random-numbers-for-javascript-mirror)
* [Better random number for javascript - JBWiki](https://web.archive.org/web/20120619002808/baagoe.org/en/wiki/Better_random_numbers_for_javascript)
* [coverslide/node-alea: A simple copy-and-paste implementation of Johanne Baagøe' Alea PRNG](https://github.com/coverslide/node-alea)
* [Park-Miller-Carta Pseudo-Random Number Generators](http://www.firstpr.com.au/dsp/rand31/)

Random points on the sphere surface (see also [Sphere Point Picking](https://mathworld.wolfram.com/SpherePointPicking.html)):

> The way to correctly generate a random point on the surface of a unit sphere is not to pick uniform distributions θ in \[0,2π) and φ in \[0,π), but instead choose u and v from uniform distributions on \[0,1). Then
>
> φ = cos⁻¹(2v-1) θ = 2πu — [Fermat's Library on Twitter: "The way to correctly generate a random point on the surface of a unit sphere is not to pick uniform distributions θ in \[0,2π) and φ in \[0,π), but instead choose u and v from uniform distributions on \[0,1). Then φ = cos⁻¹(2v-1) θ = 2πu https://t.co/Y6IX23ZGIv" / Twitter](https://twitter.com/fermatslibrary/status/1238088369420357633?s=12)

```js
// Mulberry32 pseudo random number generator (same result every time)
// example:
// const pseudoRandom = new mulberry32(12345678); // seed it
// const x = pseudoRandom(); // same as Math.random() but the same each time
// see https://stackoverflow.com/questions/521295/
function mulberry32(a){
    return function(){
        let t = a += 0x6D2B79F5;
        t = Math.imul(t ^ t >>> 15, t | 1);
        t ^= t + Math.imul(t ^t >>> 7, t | 61);
        return ((t ^t >>> 14) >>> 0) / 4294967296;
    }
}

```

```js
W=200; I=2; J=2;
Math.random()*W 2)
Math.cos(++I*I)*W 3)
++J**5%W
// [JS Bin - Collaborative JavaScript Debugging](https://jsbin.com/cihowe/edit?css,js,output)
```

```js
var seed = 1;
// Implementation of Park-Miller-Carta PRNG ported from http://lab.polygonal.de/2007/04/21/a-good-pseudo-random-number-generator-prng/
function random(seed) {
	seed = (seed * 16807) % 2147483647;
	return seed / 2147483647;
}
```

```as3
package net.dotswitch.math {
	import flash.errors.IllegalOperationError;

	public class Random {

		public function Random() {
			throw new IllegalOperationError("Illegal instantiation: Random.");
		}


		// just alias
		public static function random():Number {
			return Math.random();
		}

		public static function randomPair():Array {
			return [random(), random()];
		}


		public static function uniform():Number {
			return 2.0 * Math.random() - 1.0;
		}

		public static function uniformPair():Array {
			return [uniform(), uniform()];
		}


		public static function gaussian():Number {
			return gaussianPair()[0];
		}

		public static function gaussianPair():Array {
			var x1:Number, x2:Number, w:Number;

			do {
				x1 = uniform();
				x2 = uniform();
				w = x1 * x1 + x2 * x2;
			} while (w >= 1.0)

			w = Math.sqrt(-2.0 * Math.log(w) / w);

			return [x1 * w, x2 * w];
		}


		public static function spherical():Array {
			var theta:Number = 2.0 * Math.PI * Math.random();
			var z:Number = uniform();

			var c:Number = Math.sqrt(1 - z * z);

			var x:Number = c * Math.cos(theta);
			var y:Number = c * Math.sin(theta);

			return [x, y, z];
		}
	}
}
```

### Suffle

Aka randomize, random permutation

* [The Danger of Naïveté](https://blog.codinghorror.com/the-danger-of-naivete/)
* [Fisher–Yates shuffle — Wikipedia](https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle)
* [Fisher–Yates Shuffle](https://bost.ocks.org/mike/shuffle/)
* [How to randomize (shuffle) a JavaScript array? - Stack Overflow](https://stackoverflow.com/questions/2450954/how-to-randomize-shuffle-a-javascript-array/2450976#2450976)

### 3D volume distribution

* [3D volume distribution – Youpi !](http://barradeau.com/blog/?p=1058)

### Procedural

* Texturing and Modeling: A Procedural Approach — David S. Ebert 978-1558608481
* <https://watabou.itch.io/medieval-fantasy-city-generator>

### Visual representation of MD5 hash

* [PHP Identicons download | SourceForge.net](https://sourceforge.net/projects/identicons/)
* [FrancisShanahan/Identicon5](https://github.com/FrancisShanahan/Identicon5)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://mmems.gitbook.io/calepin/algorithms/random-noise-and-dithering/random-noise-and-dithering.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
