New Research: Supply Chain Attack on Axios Pulls Malicious Dependency from npm.Details →
Socket
Book a DemoSign in
Socket

p5.grain

Package Overview
Dependencies
Maintainers
1
Versions
10
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

p5.grain

p5.grain is a p5.js library for conveniently applying grain and texture overlays to artworks.

latest
Source
npmnpm
Version
0.8.0
Version published
Maintainers
1
Created
Source

🌾 p5.grain

p5.grain is a p5.js library for conveniently applying film grain, seamless texture overlays, and manipulate pixels to achieve nostalgic and artistic effects in p5.js sketches and artworks.

Ideal for deterministic generative artworks, p5.grain ensures consistent film grain effects with each reload. It's perfect for platforms like fxhash, where generative artworks should use a deterministic approach to randomness.

The initial release of the library was accompanied by the article "All About That Grain" co-authored by Gorilla Sun and Joseph Miclaus. Since then, p5.grain has been regularly updated to further enhance its functionality, performance and ease of use.

Table of Contents

Getting started

Download the latest version from Releases and embed either the full version (p5.grain.js or p5.grain.min.js) or the lite version (p5.grain.lite.js or p5.grain.lite.min.js) in your project's HTML file after loading p5.js but before loading your sketch code.

<script src="./lib/p5.min.js"></script>
<!-- insert after p5.js -->
<script src="./lib/p5.grain.min.js"></script>
<script src="./sketch.js"></script>

Go to top ⬆

Which file should I use?

Use the full version of p5.grain (p5.grain.js or p5.grain.min.js) while working on your sketch. This version includes error and warning reporting to help with debugging, and therefore has a larger file size. Once your sketch is final and you’re confident that no p5.grain–related errors or warnings can occur, you may want to switch to the lite version (p5.grain.lite.js or p5.grain.lite.min.js).

FileSizePurposeErrors & Warnings
p5.grain.js~ 44.3 kBdevelopmentYes (can be turned off)
p5.grain.lite.js~ 29.2 kBdevelopmentNo
p5.grain.min.js~ 13.4 kBproductionYes (can be turned off)
p5.grain.lite.min.js~  5.6 kBproductionNo

Go to top ⬆

Setup

The first step is to set up p5.grain according to your project's needs in the setup function of your sketch.

Non-deterministic setup

Use this setup for p5 sketches that do not need to use deterministic randomness.

function setup() {
    p5grain.setup();
}

Deterministic setup

Use this setup for p5 sketches that need to use deterministic randomness.

Simply set the seed value for the random function using randomSeed(). In the example below, the seed value 16 (one million) is used, but you can choose any seed value you like:

function setup() {
    randomSeed(1e6);
    p5grain.setup();
}
Deterministic setup (fxhash)
Use this setup when using p5.grain for fxhash generative projects.

If you're unsure how to correctly use randomness for fxhash projects, we recommend reading the "Deterministic Randomness" guide in the fxhash documentation first.

In most cases, you will use $fx.rand() as the single source of randomness for your generative project. In this case, you simply have to configure p5.grain to also use $fx.rand() as the underlying source of randomness:

function setup() {
    p5grain.setup({ random: $fx.rand });

    // Use `$fx.rand()` for all randomness in your fxhash project.
}

Note: Please refer to the fxhash API reference for further information.

Method 2: Using p5's random for randomness

Although this method is not used that often for fxhash projects, you can use p5's random function as the single source of randomness for your generative project too. To achieve this, you'll need to use $fx.rand() once to generate an initial deterministic number for computing the seed value for random.

In the example below, a seed value is computed by multiplying $fx.rand() with a number of your choice. In this case, 16 (one million) is used, but you can choose any number you like:

function setup() {
    randomSeed($fx.rand() * 1e6);
    // noiseSeed($fx.rand() * 1e6); // <-- when using noise()

    p5grain.setup();

    // Now you can use `random()` for all randomness in your project, but it's still recommended that you stick to `$fx.rand()`.
}

Note: Please refer to the fxhash API reference for further information.

Techniques

p5.grain currently supports the techniques: pixel manipulation, texture overlay and SVG filter. WebGL shader technique is planned for the future. Stay tuned!

Depending on how your artwork is created and whether you want to animate texture overlays, you would use p5.grain methods within the setup or draw functions of your sketch.

The best way to get you started with a technique is to check out the provided standalone examples. There is an example for each technique currently supported by the library.

Go to the standalone examples:

Here are a few examples of a basic implementation for each respective technique. All the examples below showcase how to use p5.grain in global mode and non-deterministically.

Pixel manipulation

function setup() {

    p5grain.setup();

    // draw something...

    applyMonochromaticGrain(42);
    // applyChromaticGrain(42);
}

The next example demonstates modifying the artwork's pixels using the tinkerPixels(callback) function. Here the red channel of each pixel is set to a random value between 0 and 255:

function setup() {

    p5grain.setup();

    // draw something...

    // set the red channel of each pixel to a random value between 0 and 255
    tinkerPixels((index, total) => {
        pixels[index] = random(0, 255); // red channel
    });
}

Read-only mode

If you only want to loop over pixels without changing them, you can use loopPixels:

loopPixels((index, total) => {
    // read-only mode
    // ...
});

Alternatively, you can use tinkerPixels in read-only mode:

tinkerPixels((index, total) => {
    // read-only mode
    // ...
}, false); // <-- shouldUpdate = false

Go to top ⬆

Texture overlay

let textureImage;

function preload() {
    textureImage = loadImage('./assets/texture.jpg');
}

function setup() {

    p5grain.setup();

    // draw something...

    textureOverlay(textureImage);
}

Note: the texture is rendered directly onto the canvas.

Go to top ⬆

Texture overlay + Texture animation

let textureImage;

function preload() {
    textureImage = loadImage('./assets/texture.jpg');
}

function setup() {
    p5grain.setup();
}

function draw() {
    // draw something...

    textureOverlay(textureImage, { animate: true });
}

Note: the texture is rendered directly onto the canvas.

For more concrete use cases, please have a look at the provided examples.

Go to top ⬆

Ignoring errors and warnings

Errors and warnings can be disabled only when using the full version of p5.grain (p5.grain.js or p5.grain.min.js). The lite version (p5.grain.lite.js or p5.grain.lite.min.js) does not handle errors or warnings. (see Which file should I use?)

Initially, p5.grain will attempt to extend p5.js core functionality by registering new functions. If a function cannot be registered because the function name is already in use, p5.grain will log a warning with a suggestion of an alternative usage. You can prevent warnings to be logged by passing ignoreWarnings: true to the config object when setting up p5.grain.

When using p5.grain functions, the library validates the parameters passed to the respective functions, and error messages are thrown in case of invalid parameters to attract attention during development. You can prevent errors to be thrown by passing ignoreErrors: true to the config object when setting up p5.grain.

When your sketch is final and you've made sure that p5.grain-related errors or warnings cannot occur, you may use the lite version (p5.grain.lite.js or p5.grain.lite.min.js) instead of manually ignoring errors and warnings as shown below, since errors and warnings are not handled in the lite version of p5.grain.

function setup() {
    // ignore warnings and errors
    p5grain.setup({
        ignoreWarnings: true,
        ignoreErrors: true,
    });
}

Go to top ⬆

Global and instance mode

p5.grain supports both global and instance mode. You can read more about p5.js global and instance modes here.

All examples from above showcase p5.grain usage in p5's global mode.

In order to use p5.grain on a specific p5.js instance, you can pass the respective instance to the p5grain.setup function. Since p5.grain functions are registered to p5.prototype, you can call registered p5.grain functions directly on your p5.js instance. Here's how to use p5.grain in p5's instance mode:

let myp5 = new p5((sketch) => {
    sketch.setup = () => {

        // configure p5.grain to be used on a specific p5.js instance
        p5grain.setup({ instance: sketch });

        // draw something...

        // example: apply monochromatic grain
        sketch.applyMonochromaticGrain(42);
    }
});

To better understand how p5.grain works in instance mode, please have a look at the provided examples.

Go to top ⬆

API

Note: p5.grain is still in the initial development phase and the API can still change. Always review the release notes.

The library initializes the global p5grain variable to a new P5Grain instance. You can directly access the properties and functions below from the p5grain variable. The library also attempts to register all p5.grain functions except setup with p5.js by adding them to p5.prototype. This way, instead of calling, for example, p5grain.applyMonochromaticGrain(42), you can conveniently call applyMonochromaticGrain(42), although the former is also possible.

p5.grain exposes the following properties and functions:

Properties

PropertyTypeDescription
versionStringHolds the p5.grain version in SemVer format.
ignoreWarningsBooleanSpecifies whether warnings should be ignored. (default: false)
Note: not available in the lite version.
ignoreErrorsBooleanSpecifies whether errors should be ignored. (default: false)
Note: not available in the lite version.

Functions

MethodDescription
setup([config])Setup and configure p5.grain features.
applyMonochromaticGrain(amount, [shouldUpdateAlpha], [pg])Apply monochromatic grain.
applyChromaticGrain(amount, [shouldUpdateAlpha], [pg])Apply chromatic grain.
tinkerPixels(callback, [shouldUpdate], [pg])Loop through pixels and call the given callback function for every pixel. Pixels are manipulated depending on the given callback function, unless read-only mode is enabled.
loopPixels(callback, [pg])Loop through pixels and call the given callback function for every pixel without updating them (read-only mode).
textureOverlay(textureImage, config)Blend the given texture image onto the canvas. The texture is repeated along the horizontal and vertical axes to cover the entire canvas or context.
textureAnimate(textureElement, config)Animate the given texture element by randomly shifting its background position.

Go to top ⬆

p5grain.setup([config])

Setup and configure p5.grain features.

ParameterTypeDescription
configObject(optional) Config object to configure p5grain features.
config.randomfunction(optional) The random function that should be used for e.g. pixel manipulation, texture animation, etc. Here you could use a custom deterministic random function (e.g. $fx.rand()). (default: p5's random function)
config.randomModeString(optional) Specifies the mode of the internal random function. Either float for floating-point numbers or int for integers. (default: float)
config.instanceObject(optional) Reference to a p5.js instance. Read how to use p5.grain with p5.js instance mode here.
config.ignoreWarningsBoolean(optional) Specifies whether warnings should be ignored. (default: false)
Note: not available in the lite version.
config.ignoreErrorsBoolean(optional) Specifies whether errors should be ignored. (default: false)
Note: not available in the lite version.
Examples

Custom random function

Configure p5.grain to use $fx.rand() as the internal random function:

function setup() {
    p5grain.setup({ random: $fx.rand });
}

Configure randomMode

Configure the internal random function to generate integers:

function setup() {
    p5grain.setup({ randomMode: 'int' });
}

Configure the internal random function to generate floating-point numbers:

function setup() {
    p5grain.setup({ randomMode: 'float' });
}

Note: randomMode is float by default, so you only need to do the above if you have previously configured randomMode to something other than float and you now need to generate random floating-point numbers again.

Ignore errors and warnings

Make sure you’ve read the section on Ignoring errors and warnings. It explains how to suppress errors and warnings in the full version of p5.grain:

function setup() {
    p5grain.setup({
        ignoreErrors: true,
        ignoreWarnings: true,
    });
}

Go to top ⬆

applyMonochromaticGrain(amount, [shouldUpdateAlpha], [pg])

Apply monochromatic grain.

This function generates one random value per pixel. The random value ranges from -amount to +amount. Each generated random value is added to every RGB(A) pixel channel.

ParameterTypeDescription
amountNumberThe amount of granularity that should be applied.
shouldUpdateAlphaBoolean(optional) Specifies whether the alpha channel should also be modified. (default: false)

Note: modifying the alpha channel could have unintended consequences. Only use if you are confident in what you are doing.
pg|imgp5.Graphics|p5.Image(optional) The offscreen graphics buffer or image whose pixels should be manipulated.

Note: When using an offscreen graphics buffer, use the usual syntax pg.applyMonochromaticGrain(amount, shouldUpdateAlpha). Only in case p5.Graphics.applyMonochromaticGrain could not be registered, use the alternative syntax p5grain.applyMonochromaticGrain(amount, shouldUpdateAlpha, pg).

Note: When using an image, use the usual syntax img.applyMonochromaticGrain(amount, shouldUpdateAlpha). Only in case p5.Image.applyMonochromaticGrain could not be registered, use the alternative syntax p5grain.applyMonochromaticGrain(amount, shouldUpdateAlpha, img).

Go to top ⬆

applyChromaticGrain(amount, [shouldUpdateAlpha], [pg])

Apply chromatic grain.

This function generates one random value per pixel channel. The random values range from -amount to +amount. Each generated random value is added to the respective RGB(A) channel of the pixel.

ParameterTypeDescription
amountNumberThe amount of granularity that should be applied.
shouldUpdateAlphaBoolean(optional) Specifies whether the alpha channel should also be modified. (default: false)

Note: modifying the alpha channel could have unintended consequences. Only use if you are confident in what you are doing.
pg|imgp5.Graphics|p5.Image(optional) The offscreen graphics buffer whose pixels should be manipulated.

Note: When using an offscreen graphics buffer, use the usual syntax pg.applyChromaticGrain(amount, shouldUpdateAlpha). Only in case p5.Graphics.applyChromaticGrain could not be registered, use the alternative syntax p5grain.applyChromaticGrain(amount, shouldUpdateAlpha, pg).

Note: When using an image, use the usual syntax img.applyChromaticGrain(amount, shouldUpdateAlpha). Only in case p5.Image.applyChromaticGrain could not be registered, use the alternative syntax p5grain.applyChromaticGrain(amount, shouldUpdateAlpha, img).

Go to top ⬆

tinkerPixels(callback, [shouldUpdate], [pg])

Loop through pixels and call the given callback function for every pixel. Pixels are manipulated depending on the given callback function, unless read-only mode is enabled.

The callback function provides two arguments:

  • index: the current pixel index
  • total: the total indexes count

Read-only mode: updating pixels can be by-passed by setting the shouldUpdate argument to false. It is however recommended to use loopPixels if you only want to loop through pixels.

ParameterTypeDescription
callbackFunctionThe callback function that should be called on every pixel.
shouldUpdateBoolean(optional) Specifies whether the pixels should be updated. (default: true)
pg|imgp5.Graphics|p5.Image(optional) The offscreen graphics buffer whose pixels should be manipulated.

Note: When using an offscreen graphics buffer, use the usual syntax pg.tinkerPixels(callback, shouldUpdate). Only in case p5.Graphics.tinkerPixels could not be registered, use the alternative syntax p5grain.tinkerPixels(callback, shouldUpdate, pg).

Note: When using an image, use the usual syntax img.tinkerPixels(callback, shouldUpdate). Only in case p5.Image.tinkerPixels could not be registered, use the alternative syntax p5grain.tinkerPixels(callback, shouldUpdate, img).

Go to top ⬆

loopPixels(callback, [pg])

Loop through pixels and call the given callback function for every pixel without updating them (read-only mode).

In contrast to the tinkerPixels function, no pixel manipulations are performed with loopPixels. In other words loopPixels has the same effect as using tinkerPixels in read-only mode.

The callback function provides two arguments:

  • index: the current pixel index
  • total: the total indexes count
ParameterTypeDescription
callbackFunctionThe callback function that should be called on every pixel.
pg|imgp5.Graphics|p5.Image(optional) The offscreen graphics buffer whose pixels should be manipulated.

Note: When using an offscreen graphics buffer, use the usual syntax pg.loopPixels(callback). Only in case p5.Graphics.loopPixels could not be registered, use the alternative syntax p5grain.loopPixels(callback, pg).

Note: When using an image, use the usual syntax img.loopPixels(callback). Only in case p5.Image.loopPixels could not be registered, use the alternative syntax p5grain.loopPixels(callback, img).

Go to top ⬆

textureOverlay(textureImage, [config], [pg])

Blend the given texture image onto the canvas.

The texture is repeated along the horizontal and vertical axes to cover the entire canvas (or context).

ParameterTypeDescription
texturep5.Image|p5.GraphicsThe texture image to blend over.
configObject(optional) Config object to configure the texture overlay.
config.widthNumber(optional) The width the texture image should have. (default: textureImage.width)
config.heightNumber(optional) The height the texture image should have. (default: textureImage.height)
config.modeConstant(optional) The blend mode that should be used to blend the texture over the canvas. Either BLEND, DARKEST, LIGHTEST, DIFFERENCE, MULTIPLY, EXCLUSION, SCREEN, REPLACE, OVERLAY, HARD_LIGHT, SOFT_LIGHT, DODGE, BURN, ADD or NORMAL. (default: MULTIPLY)
config.reflectBoolean(optional) Specifies whether the given texture image should reflect horizontally and vertically, in order to provide seamless continuity. (default: false)
config.animateBoolean| Object(optional) Specifies whether the given texture image should be animated. (default: false)
config.animate.atFrameNumber(optional) When animation is activated, the frame at which the texture should be shifted. When atFrame is not specified, the texture is shifted every 2nd frame. (default: 2)
config.animate.amountNumber(optional) When animation is activated, the maximum amount of pixels by which the texture should be shifted. The actual amount of pixels which the texture is shifted by is generated randomly. When no amount is specified, the minimum of the main canvas width or height is used. (default: min(width, height))
pgp5.Graphics(optional) The offscreen graphics buffer onto which the texture image should be drawn.

Note: When using an offscreen graphics buffer, use the usual syntax pg.textureOverlay(textureImage, config). Only in case p5.Graphics.textureOverlay could not be registered, use the alternative syntax p5grain.textureOverlay(textureImage, config, pg).

Go to top ⬆

textureAnimate(textureElement, [config])

Animate the given texture element by randomly shifting its background position.

ParameterTypeDescription
textureElementHTMLElement| SVGElement| p5.ElementThe texture element to be animated.
configObject(optional) Config object to configure the texture animation.
config.atFrameNumber(optional) The frame at which the texture should be shifted. When atFrame is not specified, the texture is shifted every 2nd frame. (default: 2)
config.amountNumber(optional) The maximum amount of pixels by which the texture should be shifted. The actual amount of pixels which the texture is shifted by is generated randomly. When no amount is specified, the minimum of the main canvas width or height is used. (default: min(width, height))

Go to top ⬆

Limitations

  • Safari: SVG element technique only works for browser window resolutions with less than 220 pixels (e.g. 1024 x 1024 pixels).
  • Safari: SVG URL-encoded technique is currently unsupported.

Support

If you need help or have questions about using p5.grain, you can find support through the following channels:

  • GitHub Discussions: Join the conversation and ask questions in the Q&A section
  • Direct Message on X (formerly Twitter): Feel free to DM @josephmiclaus

Contributing

Are you considering contributing to p5.grain? Check out our contributing guidelines.

License

p5.grain is MIT licensed.

Spread the Word

If you find p5.grain useful, we’d love for you to share it! Mentioning the library in your project description, tutorials, or social media posts helps others discover it and benefit from it. Thanks for spreading the word and showing your appreciation! 🙏

Keywords

p5

FAQs

Package last updated on 21 Jan 2026

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts