processing / processing/p5.js

[p5.strands] Detect references to outside variables and give helpful feedback

Open
#8,172 4 comments 0 reactions 1 assignee View on GitHub

@Aayushdev18 is already working on this.

Since Oct 24, 2025.

Area:WebGL Enhancement
Dominant language
JavaScript
Stars
24k
Forks
3.8k
Avg merge
3d 16h
Merged PRs (30d)
25

Description

Increasing access

There are a number of subtle ways you can use variables in p5.strands that give no errors but subtly don't work. We can improve the experience for users to give them next steps for debugging.

Most appropriate sub-area of p5.js?
  • Accessibility
  • Color
  • Core/Environment/Rendering
  • Data
  • DOM
  • Events
  • Image
  • IO
  • Math
  • Typography
  • Utilities
  • WebGL
  • Build process
  • Unit testing
  • Internationalization
  • Friendly errors
  • Other (specify if possible)
Feature enhancement details

@ksen0 created this example and noted that if you were to use if (mouseX/windowWidth < 0.3) { instead of if (value < 0.3) { then it stops working, but without any errors.

let testShader;
let pixelate;
let state_;


async function setup() {
  state_ = 0;
  createCanvas(windowWidth, windowHeight, WEBGL);
  testShader = baseMaterialShader().modify(() => {
    const value = uniformFloat(() => mouseX/windowWidth);
    const state = uniformFloat(() => state_);

    let time = uniformFloat(() => frameCount/5);
    getPixelInputs((inputs, canvasContent) => {
      let color = inputs.color;
      if (value < 0.3) {
        color = vec3(1.0, state*0.1, 0);
      } else if (value < 0.8) {
        color = vec3(state*0.1, 1, state*0.1);
      } else {
        color = vec3(state*0.1, 0, 1);
      }
      inputs.color = [color, 1.0];
      return inputs;
    });
  });
}

function draw() {
  background(0);
  shader(testShader);
  testShader.setUniform('value', mouseX/width)
  sphere(100);
}

function mousePressed(){
  state_ += 1;
  console.log(state_)
}

When something isn't a uniform, and isn't a value we specifically handle (see https://github.com/processing/p5.js/issues/8171; in the future we'll make mouseX and windowWidth available), it falls into one of two cases:

  • It's a dynamic value, and should be turned into a uniform, e.g.: const myValue = uniformFloat() + myShader.setUniform('myValue', something) after applying the shader

  • It's a static value, but it's a local variable that the strands callback can't access, and needs to be passed into an object as the second parameter of the modify function, e.g.:

    let myVal = 10
    const myShader = baseMaterialShader().modify(() => {
      getWorldInputs((inputs) => {
        inputs.position.x += myVal
        return inputs
      })
    }, { myVal }) // This is how to make a local variable accessible in strands
    

Maybe that second case isn't common enough to tell people about, so possibly just the first case is fine. Ideally we can detect usages of variables that aren't declared within the p5.strands callback, see if they're a known p5 global, and if not, output an example of making a uniform out of it?

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.