---
jupytext:
formats: ipynb,md:myst
text_representation:
extension: .md
format_name: myst
format_version: 0.13
jupytext_version: 1.11.5
kernelspec:
display_name: py5
language: python
name: py5
---
# How to Generate Pseudorandom Noise
[Pseudo-random noise](https://en.wikipedia.org/wiki/Pseudorandom_noise) functions can create sequences of numbers that seem random and unpredictable but are actually generated by repeatable, deterministic processes. These algorithms can be useful for various goals such as generating random textures and animating digital characters moving across the screen.
This library provides two algorithms for you to use to generate noise: the OpenSimplex algorithm and the Processing Noise algorithm.
Noise generation is a rich and complex subject that academics and researchers have been studying for decades. The noise functionality provided by py5 only scratches the surface of what is possible. You are encouraged to do your own research and experimentation to learn more.
Below is an overview of how to use py5's noise generation methods.
## OpenSimplex2 Noise
The first choice is [KdotJPG's OpenSimplex2 algorithm](https://github.com/KdotJPG/OpenSimplex2). Specifically, the OpenSimplex2S (SuperSimplex) algorithm. The [OpenSimplex algorithm](https://en.wikipedia.org/wiki/OpenSimplex_noise) was created in response to the copyright restrictions surrounding the use of Ken Perlin's simplex noise algorithm.
Below is an example of how to use the [`Sketch.os_noise()`](../reference/sketch_os_noise) method:
```{code-cell} ipython3
os_noise(1.1, 2.2)
```
OpenSimplex noise values will always be between -1 and 1.
The method can accept 2, 3, or 4 parameters to create 2D, 3D, or 4D noise.
```{code-cell} ipython3
os_noise(1.1, 2.2, 3.3)
```
```{code-cell} ipython3
os_noise(1.1, 2.2, 3.3, 4.4)
```
To generate 1D noise, add your favorite constant value as a second parameter.
If you like, you can initialize the OpenSimplex noise generator with a seed value using [`Sketch.os_noise_seed()`](../reference/sketch_os_noise_seed). This will ensure that your code generates the same noise values every time your Sketch is run. By default, py5 randomly picks a seed value for you when the Sketch starts running. Therefore the noise values will not be the same from one Sketch to the next.
```{code-cell} ipython3
os_noise_seed(42)
os_noise(1.1, 2.2)
```
The [`Sketch.os_noise()`](../reference/sketch_os_noise) method can accept numpy arrays as parameters. This will be dramatically faster than repeatedly calling the method in a for loop. Calling this method repeatedly in a for loop should be avoided whenever possible.
```{code-cell} ipython3
import numpy as np
a = np.linspace(0, 1, num=4)
b = np.linspace(10, 20, num=4)
os_noise(a, b)
```
If the array parameters are different shapes but can be [broadcast](https://numpy.org/doc/stable/user/basics.broadcasting.html) together, py5 will do the broadcasting for you and return the appropriate results.
```{code-cell} ipython3
import numpy as np
a = np.linspace(0, 1, num=3)
b = np.linspace(0, 1, num=4)[:, None]
print(a.shape)
print(b.shape)
```
```{code-cell} ipython3
out = os_noise(a, b)
print(out.shape)
out
```
Here's a quick example of how this can be used in a Sketch to create 2D noise.
```{code-cell} ipython3
%%py5bot
size(500, 400)
x, y = np.meshgrid(np.linspace(0, 10, num=width), np.linspace(0, 10, num=height))
out = remap(os_noise(x, y), -1, 1, 0, 255)
img = create_image_from_numpy(out, bands='L')
image(img, 0, 0)
```
## Processing Noise
The second choice is Processing's noise algorithm. These noise values will be identical to Processing's for the same input parameters. This algorithm is unique to Processing and has been used by countless artists and creative coders over the years for their projects.
Below is an example of how to use the [`Sketch.noise()`](../reference/sketch_noise) method:
```{code-cell} ipython3
noise(1.1)
```
Processing noise values will typically be between 0 and 1. By default it will always be within this range but can exceed it with some configurations of [`Sketch.noise_detail()`](../reference/sketch_noise_detail).
The method can accept 1, 2, or 3 parameters to create 1D, 2D, or 3D noise.
```{code-cell} ipython3
noise(1.1, 2.2)
```
```{code-cell} ipython3
noise(1.1, 2.2, 3.3)
```
Much like the OpenSimplex algorithm, you can set a noise seed to make the noise values repeatable every time your Sketch is run. By default the noise values will not be the same from one Sketch to the next.
```{code-cell} ipython3
noise_seed(42)
noise(1.1, 2.2)
```
The Processing noise algorithm is configurable in that you can adjust the number of noise "octaves" and the amplitude of the octaves. You should read the [`Sketch.noise_detail()`](../reference/sketch_noise_detail) documentation and do your own experimentation to fully understand what the options are.
```{code-cell} ipython3
noise_detail(7, 0.2)
noise(1.1, 2.2)
```
Like the OpenSimplex algorithm, you can pass numpy arrays to [`Sketch.noise()`](../reference/sketch_noise) that will be broadcast to the proper shapes if need be. Passing arrays will always be significantly faster than calling this method repeatedly in a loop.
```{code-cell} ipython3
import numpy as np
a = np.linspace(0, 1, num=3)
b = np.linspace(0, 1, num=4)[:, None]
print(a.shape)
print(b.shape)
```
```{code-cell} ipython3
out = noise(a, b)
print(out.shape)
out
```
Here's another quick example of how this can be used in a Sketch to create 2D noise. Observe that the visual characteristics of this noise is different from the similar Sketch created with OpenSimplex.
```{code-cell} ipython3
%%py5bot
size(500, 400)
x, y = np.meshgrid(np.linspace(0, 10, num=width), np.linspace(0, 10, num=height))
out = remap(noise(x, y), 0, 1, 0, 255)
img = create_image_from_numpy(out, bands='L')
image(img, 0, 0)
```
## Other Noise Options
If neither of [`Sketch.noise()`](../reference/sketch_noise) nor [`Sketch.os_noise()`](../reference/sketch_os_noise) meet your needs, there are other Python libraries available that you can consider instead.
* [noise][1]: Previous versions of py5 used this library to provide Perlin Noise and Simplex Noise algorithms. The library uses compiled c code to generate the noise values. It works well but has a few bugs, one of which can cause a py5 Sketch to suffer a segmentation fault. Unfortunately the library has not had a release in years so the bugs are not likely to be fixed. For these reasons and a few others, py5 can't have this library as a dependency and was removed. However, you may find it useful to install this library on your own if you want to use Perlin noise.
* [vec-noise][2]: Haven't actually used this one much but it seems to be a better and faster version of the preivously mentioned noise library.
* [vnoise][3]: Pure Python implementation of Ken Perlin's Improved Noise function. Seems to be a well maintained library. This library was seriously considered as a possible replacement for the original noise library but the noise calculations are very slow.
* [opensimplex][4]: Pure Python implementation of the OpenSimplex algorithm. If you install the optional dependency Numba, this library will be significantly faster than py5's open simplex implementation.
* [UniformNoise][5]: If you are willing to setup and work with a Java library, give the Uniform Noise library a try. The generated values will be uniformly distributed between 0 and 1.
* [FastNoiseLite][6]: Another Java library that is worth considering is FastNoiseLite. If nothing else, you can experiment with the GUI to learn more about the vast ecosystem of noise algorithms that are available.
Each of these noise algorithms have their own strengths, weaknesses, and idiosyncrasies. Explore and experiment to learn more.
[1]: https://pypi.org/project/noise/
[2]: https://pypi.org/project/vec-noise/
[3]: https://pypi.org/project/vnoise/
[4]: https://pypi.org/project/opensimplex/
[5]: https://github.com/micycle1/UniformNoise
[6]: https://github.com/Auburn/FastNoiseLite