Skip to main content

A diffusion-driven procedural noise library.

Project description

Longdin Noise


What is it?

Longdin Noise is a noise type that uses per-pixel vectors to propagate pixel values.

It is interesting in the fact that two different configurations can produce wildly different results. A high density with low iterations can produce a blocky, glitchy looking noise. A low density with high iterations can produce a sort of bubbly or brush-like noise.

Why was it made?

For no particular reason really. It's strange pattern makes it impractical for common examples in games (like landscapes for video game with Perlin Noise). It's definitely an example of more artistic noise - although, if you can find a genuinely practical use for this thing, please do let me know via my email!

It started off as a desperate wrestle with the boney hands of boredom. It's strange to think the wonders one's mind can produce when one is desperately in need of something to do - or, indeed, type. If you ever find yourself desperately bored with nothing to do, create a new python file and type the following:

class Universe:
    pass

There's something about the openness of an unimplemented class that allows the mind to wonder. It doesn't have to be Universe. It can really be anything - in my case it gradually morphed into _Noise. Although, the broad topic that is the entirety of existence is definitely effective.

The Inner-Workings

All three of the generator functions first instantiates a _Noise object. _Noise is an internal class and is not intended for use outside of the API.

Initialisation

When _Noise instantiates, it generates a 2D numpy array that takes on the shape (height, width, channels) where channels is either 1, 2, or 3. (more on that later!) These are the cell 'values'. It generates another array of the shape (height, width, 2) to store each cell's influence vector.

The density (a float bigger than 0 up to 1) is just the percentage of 'cells' that are active. The generator decides which cells should be inactive using this value and zeros out each of these inactive cells.

The Algorithm

Each iteration runs the same algorithm on the data that either the initialisation or last iterative pass produced.

First things first, it gets all active cells and shuffles that data's order. A cell is active if it has an influence vector and a value associated. The shuffle helps to mitigate undesired and unpleasant row artifacts produced by the parallelism used to speed up the algorithm.

The algorithm then loops through all active cells. For each cell, it does the following:

  • Get all cells within the radius of the active cell (excludes cells if the active cell is not pointing towards them within 90°)
  • Computes the distance from the origin (active cell) to each cell within its range (radius)
  • Uses the distance to compute the influence the active cell has on each cell
  • Each cell is then lerped towards the active cell's data using the calculated influence as the factor.

To finish off the iteration, the list of active cells is updated ready for the next iteration.

Installation

pip install longdin-noise

How to use it?

Here's a quick example of how one may use this library using PIL:

from longdin_noise import generate_mono
from PIL import Image
import numpy as np

result = generate_mono((512, 512), 42, 0.05, 10)

# result is a (512, 512) array of floats in the range 0..1
# multiply by 255 and convert to uint8 for PIL
image_data = (result * 255).astype(np.uint8)
img = Image.fromarray(image_data, mode="L")
img.save("mono_noise.png")

This will create you a lovely greyscale image using the longdin_noise python library:

Mono noise example

Parameters

Parameter Type Default Valid Range Description
size tuple[int, int] Any positive ints Width and height of the output
seed int Any int Random seed
density float 0 < x ≤ 1 Proportion of initially active pixels
iterations int ≥ 1 Number of diffusion passes
radius int 8 ≥ 1 Influence reach in pixels

Tweaking the Values

The effect the values have on the resulting noise can be obscure and difficult to figure out at first. Hopefully this short guide can help you to understand how to craft your desired effect.

The number of iterations — in short — just increases the amount of smearing in the noise. As the vectors' influences propagate outwards every iteration, the colours mix more and boundaries become less clear.

The density will basically dictate how noisy the image is. A really, really low density like 0.0005 - especially on a low number of iterations like 1 - 4 - scatters 'searchlights' across the image. I have yet to find a use for this but it's pretty cool. A high density creates a more tightly packed image where blending between colours occurs much sooner in the iterative process.

The radius is quite simple. It just affects how far each active cell can influence. I haven't had an opportunity to experiment with this much, but it should have an 'octaves' effect where higher values create simpler noise.

Example Images

Low density, high iterations (0.005 Density, 20 Iterations)

Mono Bi Tri

High density, low iterations (0.6 Density, 4 Iterations)

Mono Bi Tri

Dependencies

This module requires numpy and numba.

License

This is under the MIT license. Truly do whatever you want with this code and what it produces.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

longdin_noise-0.1.1.tar.gz (333.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

longdin_noise-0.1.1-py3-none-any.whl (6.7 kB view details)

Uploaded Python 3

File details

Details for the file longdin_noise-0.1.1.tar.gz.

File metadata

  • Download URL: longdin_noise-0.1.1.tar.gz
  • Upload date:
  • Size: 333.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.3

File hashes

Hashes for longdin_noise-0.1.1.tar.gz
Algorithm Hash digest
SHA256 310c6a483d90d0a73f96705228e6900f627d167bd9c762182f33c0ff8af5e768
MD5 6ba1aeee2b32d4f395ddb57b397e61be
BLAKE2b-256 bad4eab8b53f9b69b74811d56f4e7ccf135bde1881dd27ceed9357f15a188dfc

See more details on using hashes here.

File details

Details for the file longdin_noise-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: longdin_noise-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 6.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.3

File hashes

Hashes for longdin_noise-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 7de4d09035c3c86655da45fb85708b5fa7d333cc1b2471fc0e126ddea2161d2e
MD5 fc8b95c4b7bf95f90fe8f5589df6a5f5
BLAKE2b-256 75822ffc120a5242e00e2e2061400c6012f762229fb7784c8bf8cfb08eaeacf1

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page