Skip to content

[p5.strands] Bridging p5.strands and p5.js functions #7849

Open
1 of 2 issues completed
Open
Feature
1 of 2 issues completed
@lukeplowden

Description

@lukeplowden

Increasing access

By aiming to make the learning curve for p5.strands (therefore shaders) as easy as possible when coming from p5.js. As much as possible, p5.js functions should work in p5.strands, unless there is good reason for them not to.

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

Currently, some p5.js functions will not work properly in p5.strands. This issue aims to improve compatiblity, reduce confusion, and make it easier to mix standard p5.js code in with p5.strands shaders.

Background

p5.strands ports a large number of GLSL's built in functions. For example:

  • trigonometric functions: sin, cos, etc
  • maths functions: abs and mix
    In some cases, these are duplicates of p5.js functions. The p5.strands compiler temporarily overrides duplicates, so they can be used with p5.strands objects.

p5.strands operates a bit differently than the rest of the library. In a way, it emulates namespacing by overriding p5.js functions, but it does so implicitly. The compiler lets use use JavaScript values like Numbers and Arrays, but internally they are converted to objects representing nodes in a kind of Abstract Syntax tree (e.g. FunctionCallNode, VectorNode, etc). So when we try to use p5.js functions, they can fail if we pass these nodes as objects. At the same time, p5.strands currently disables the Friendly Error System, which further obfuscates the problem.

(Note: the disabling of FES is a separate Issue which I will post soon and update the link to soon)

Apart from documentation and other learning materials, some work is needed to improve the interoperability of p5.js and p5.strands functions. The aim is to keep the node based abstraction hidden, and provide more analogues for p5.js functions. This should make p5.strands more integrated with the rest of the library, making it more accessible.

p5.js Math functions

p5.js' math functions, such as map, don't always work as expected in p5.js. Take the following code for example:

  a = baseColorShader().modify(()=> {
    const time = uniformFloat(()=> millis());
    getWorldInputs(inputs => {
      let r = 1;
      let b = r / 0.2;
      let g = map(50, 0, 100, sin(time), 1);
      inputs.color = [r, 0, g, 1];
      return inputs;
    });
  });

This currently throws a generic JS 'NaN' error, as map expects a number but receives a FunctionCallNode object. This should be allowed behaviour, and p5.js functions should as much as possible be usable within p5.strands to reduce the mental load of remembering what can and can't be done.

There may be cases apart from the Math functions, but that's the most obvious example. This part of the issue requires some discussion about what should be ported to p5.strands, and how it could be implemented.

Mix / lerp

There is a special case for mix, which is GLSL's version of lerp in p5.js. There has been some discussion about creating an analogue for lerp in p5.strands, so that either of the following would be possible:

myShader = baseColorShader().modify(() => {
	getFinalColor(col => {
		let red = [1, 0, 0, 1];
		let blue = [0, 0, 1, 1];
		
		// Currently possible:
		col = mix(red, blue, 0.5);
		
		// Not currently possible:
		col = lerp(red, blue, 0.5);
	})
})

In this case, it's a small amount of code to fix, and could be done separately.

Sub-issues

Metadata

Metadata

Assignees

No one assigned

    Projects

    Status

    Open for Discussion

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions