Skip to content

feat(strands): add color() support for beginner-friendly color inputs#8822

Open
LalitNarayanYadav wants to merge 4 commits into
processing:dev-2.0from
LalitNarayanYadav:color-support-strands
Open

feat(strands): add color() support for beginner-friendly color inputs#8822
LalitNarayanYadav wants to merge 4 commits into
processing:dev-2.0from
LalitNarayanYadav:color-support-strands

Conversation

@LalitNarayanYadav
Copy link
Copy Markdown
Contributor

@LalitNarayanYadav LalitNarayanYadav commented May 22, 2026

Part of the Open Source Software Microgrant: beginner-friendly p5.strands API for more p5-like color support.

Changes

Adds beginner-friendly p5.js-style color support inside the strands context, so users can work with familiar color APIs in shaders instead of raw vec4 literals.

color() - parse any p5.js color input into a vec4

Previously, calling color() inside a modify() block returned a p5.Color object, unusable in a GPU shader context. This PR overrides color() in strands_api.js to return a vec4 strands node instead.

Supported input formats (all handled by p5's existing colorjs.io parser):

  • Hex strings: color('#ff0000'), color('#f00')
  • CSS named colors: color('red'), color('cornflowerblue')
  • rgb()/rgba() strings: color('rgb(255, 0, 0)')
  • Numeric args: color(255, 0, 0), color(128) (grayscale)

How it works:

  1. Calls the original p5.color() to parse the input, no new parsing logic
  2. Calls ._getRGBA() on the result to get [r, g, b, a] normalized to 0–1
  3. Builds a vec4 strands node via primitiveConstructorNode

lerpColor(c1, c2, amt) - interpolate between two colors

Maps directly to GLSL mix() in the strands context, since colors are vec4s. Falls through to normal p5 behavior outside strands.

red(), green(), blue(), alpha() - component accessors

Extract scalar RGBA channels from a vec4 color node via .x/.y/.z/.w swizzles.

hue(), saturation(), brightness(), lightness() - HSL/HSB accessors

Inject GLSL helper functions (_p5_rgb2hsb, _p5_rgb2hsl) into the shader declarations on first use, then extract the relevant channel from the converted vec3. Helpers are injected into vertex, fragment, and compute declarations.

Outside a strands context, all functions fall through to normal p5 behavior.

Example

myShader = baseMaterialShader().modify(() => {
  getFinalColor((color) => {
    // hex string → vec4(1.0, 0.0, 0.0, 1.0)
    let c = color('#ff0000');

    // interpolate two colors
    let mid = lerpColor(c, color('blue'), 0.5);

    // extract channels
    let r = red(c);       // 1.0
    let h = hue(c);       // 0.0 (red hue)
    let b = brightness(c); // 1.0

    return color;
  });
});

Screenshots

N/A - shader/transpiler change with no visual diff.

PR Checklist

  • npm run lint passes
  • Inline reference is included / updated
  • Unit tests are included / updated

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant