Skip to content

Add p5strands color tutorial. - #1592

Draft
ilithya wants to merge 4 commits into
processing:mainfrom
ilithya:tutorials/p5strands-color
Draft

Add p5strands color tutorial.#1592
ilithya wants to merge 4 commits into
processing:mainfrom
ilithya:tutorials/p5strands-color

Conversation

@ilithya

@ilithya ilithya commented Sep 2, 2026

Copy link
Copy Markdown

No description provided.

@ksen0

ksen0 commented Sep 2, 2026

Copy link
Copy Markdown
Member

Context for website stewards: this is a WIP micrograntee work

@ksen0 ksen0 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for all your work so far @ilithya ! I've left a few minor comments. Looking forward to the next iteration!

Comment thread src/content/tutorials/en/hello-color-world-p5-strands.mdx Outdated
Comment thread src/content/tutorials/en/hello-color-world-p5-strands.mdx

#### sketch with GLSL
<EditableSketch code={`
let shaderCanvas;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you think about making this one scrollable with a fixed width? I introduced a component to that recently #1469 could get it merged shortly if it would be useful. This one in particular was very long. Or do you think it's helpful to always show in full?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, thanks! I was going to ask for an accordion type component, as the GLSL sketches will be very long. I briefly looked into the tailwind components , but didn't find anything I could use. I'll use yours.

<Callout title="What is p5.strands?">
p5.strands is a new way of writing shaders using JavaScript in p5.js.
- [Writing shaders in JavaScript](https://www.davepagurek.com/blog/writing-shaders-in-js/), Dave Pagurek's blog
- [Introduction to shaders](/tutorials/intro-to-p5-strands)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i almost thought the link will point to glsl tutorial, should we add "p5 strands" in the link text?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I basically took the blog post names for text links and removed "p5.strands" as I thought of maybe being repetitive, as this callout is about p5.strands. Do you think it will not be redundant?

I'll add it in the next commit, and you can compare, see if it feels redundant or not.

Btw. I do have a link to the GLSL tutorial in the shader box definition.

I'm trying to link all the current strands documentation in my info boxes, slowly, maximum 2 links per callout box.

</ Callout>

With p5.strands we can modify the color of a shader and have the benefit of using several color notations and models that we already know from p5.js, since it translates them for us into the GLSL specific one with hooks (e.g. `finalColor`).

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

callout defining hooks might be helpful.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're reading the future. Yes! See it on the next commit.

I have one now, as the tutorial progresses. That's my idea, to feed this info boxes slowly with important theory about strands/shaders.

Comment on lines +87 to +93
function setup() {
createCanvas(300, 300, WEBGL);
pixelDensity(1);

shaderCanvas = buildColorShader(colorCanvas);
shaderPrimitive = buildMaterialShader(colorPrimitive);
}

@skyyash skyyash Sep 8, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

im not sure about draw, but i think keeping setup before strands callbacks is a better code pattern and easily understandable + p5 users are already familiar to these functions.

pixelInputs.end();
}

async function setup() {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why setup is async function here?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ups. I think it came from when I had an image in another sketch. Please browse my code every commit, as I might have typos after copy-pasting sketches and just editing hooks and so on, as I don't write p5.js as often as all of you. Thanks!

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, maybe it's a left over from one of my examples where I was testing WEBGPU/WEBGL renderers

Comment on lines +184 to +187
<Callout title="What is a shader?">
A set of code implementing algorithms to get the pixels of a mesh rendered on the screen. In WebGL shaders are written in GLSL, and there are two types: vertex and fragment.
- [Introduction to GLSL](https://p5js.org/tutorials/intro-to-glsl/)
</ Callout>

@skyyash skyyash Sep 8, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i think we should put this before the callout defining fragment shader at line 41 for maintaining a logical flow.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll move it in the next commit. I edited (simplified) this definition now.

Btw. I can't take all the credit of putting strands and glsl code side by side. I think Kit mentioned this first when we were brainstorming my ideas at a café for the tutorial to compare advantages of using strands. 😁

@skyyash

skyyash commented Sep 8, 2026

Copy link
Copy Markdown
Contributor

kudos @ilithya, good idea putting strands and glsl code side by side.

@ksen0 ksen0 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for your notes re: cheatsheet, I'll work on that! Here are some comments. Do you have a sense for how this will conclude? Maybe a short reflection on something like, if you're excited to learn shaders, here's 2 reasons to learn p5.strands as a next step (and maybe a link to one of the existing strands resources, even if its a repetition; and/or maybe a link to https://openprocessing.org/curation/90883 with invitation to submit work and experimentation with strands there) and 2 reasons to learn GLSL as a next step.

Or something like that, showing that either is an option, its totally up to them and either would be usable with p5.js.

posible p5strands reasons:

possible GLSL reasons:

  • extensive existing resources and community (link some favorites) for learning and sharing
  • GLSL skills carry over to three.js, shadertoy, and lots of webGL projects outside p5.js and the web including TouchDesigner and Unity
  • GLSL snippets can be used alongside p5.strands; so you can get the control of GLSL but reduced boilerplate + builtins of p5.strands

If you include the above pros of GLSL I think it's good to mention that * if you learn p5.strands, it works with WEBGPU as well as with WebGL. So your strands code is translated by p5 not only to GLSL, but also to WGSL, so compute shaders can be used (eg https://processingfoundation.org/blog/whats-new-in-p5js-230/ ). WebGPU increasingly used, rather than WebGL, and learning p5.strands covers both

<Callout title="What is p5.strands?">
It's a new way of writing shaders using JavaScript in p5.js.
- [p5.strands: Writing shaders in JavaScript](https://www.davepagurek.com/blog/writing-shaders-in-js/), Dave Pagurek's blog
- [p5.strands: Introduction to shaders](/tutorials/intro-to-p5-strands)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe "p5.strands: Introduction to shaders, tutorial by Luke Plowden"? I understand why specified Dave's blog post as being not on the website but for consistency I think it makes sense to provide the attribution note the same way in both (or neither)

- [p5.strands: Introduction to shaders](/tutorials/intro-to-p5-strands)
</ Callout>

To understand the advantages that p5.strands brings to us when dealing with shaders, we'll look at each technique through examples with variations of creating a p5 sketch together with p5.strands vs. GLSL (shader language).

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor, "the advantages that p5.strands brings" -> "what advantages using p5.strands"

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also minor: "vs." --> "compared to". Also I think rather than parenthesis, a seperate sentence would be easier to scan, like "...GLSL (shader language)." --> "... GLSL. Although GLSL can be used alongside JavaScript in a p5.js sketch, it is a separate shader language that shaders require. With p5.strands, the GLSL step is managed by p5.js, so as a user you only need to use JavaScript." Probably shorter, but I think just (shader language) in parenthesis isn't really self-explanatory. But it's fine to omit this and just link to an existing resource instead of summarizing!

- [Introduction to GLSL](https://p5js.org/tutorials/intro-to-glsl/)
</ Callout>

Let's start from simple to complex, like having a x-course meal, by first dipping our toes into an appetizer.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"X" here and in. title will be replaced by a number?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I wasn't sure how many techniques to write in the beginning. But seeing time left, and also content already written, I think I'm gonna settle with these 3. And next, wrap up the conclusion with a bit more general info about strands advantages.


<div class="mt-18"></div>

### 01. Solid Colors

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I dont think there's any existing tutorial that uses 0-padded numbers; if you'd like to number the sections I think this style works better, of having "Step 1:...." 2 and 3 to keep it as simple as possible

We'll begin by simply painting the canvas of our sketch and one 3D primitive.

<Callout title="What is a fragment shader?">
A shader in charge of outputting the color of each pixel on the screen, using RGBA values from 0.0 to 1.0.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: "A shader in charge of outputting" --> "A fragment shader sets"


<Callout title="What is a fragment shader?">
A shader in charge of outputting the color of each pixel on the screen, using RGBA values from 0.0 to 1.0.
- [RGBA color](https://hughsk.io/fragment-foundry/chapters/03-rgb.html), self-guided workshop on fragment shaders by Hugh Kennedy

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall, I really like the callouts and the resources!


function setup() {
createCanvas(300, 300, WEBGL);
pixelDensity(1);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe in one of the last sketches, there can be a callout explaining this? IT's there because for retina displays, like on a macbook, it makes the shaders run fasted because by default the pixelDensity is 2. You can set it lower thn one (try 0.1) and see how the render resolution drops, and a slow sketch speeds up. It is a helpful trick for prototyping or debugging a shader in p5. If this callout is added, linking to https://p5js.org/reference/p5/pixelDensity/ ref page may be helpful as well

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll think of how to do that in the next round. I was also thinking of adding a callout to explain a uniform, as I started talking more about them in the last examples, seeing how easier is to access them with strands.


<Callout title="What is chromatic aberration?">
It's a color distortion that occurs when the colors of light don't focus on the same point. The RGB channels appear to be separated, making the colors of an image appear shifted.
- [Chromatic aberration](https://en.wikipedia.org/wiki/Chromatic_aberration), wikipedia

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe worth adding our existing chromatic aberration examples? these are also avialbale in strands comapred to glsl: https://p5js.org/examples/3D-Filter-Shader-p5strands/ https://beta.p5js.org/examples/3D-Filter-Shader/


function draw() {
// Add image to canvas
image(img, width/-2, height/-2, width, height);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

minor: this line wraps in the narrow column as well


// Amount of color displacement
const offsetX = (0.5 - mouseX / width) * 0.5;
const offsetY = (0.5 - mouseY / height) * 0.5;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

minor: this line wraps

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you! I just was editing the last sketch and some stuff before I saw this. I'll go ahead and take all this feedback pointers.

@aashu2006 aashu2006 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ilithya I really like the side-by-side strands vs GLSL format, it makes the difference easy to see at a glance. The callouts feeding in theory gradually is a nice touch too.

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.

4 participants