Skip to content

Add p5.strands translations for shader examples and rename original GLSL examples#1238

Open
MissTipo wants to merge 1 commit intoprocessing:2.0from
MissTipo:shader-translation-glsl-to-p5-strands-2.0
Open

Add p5.strands translations for shader examples and rename original GLSL examples#1238
MissTipo wants to merge 1 commit intoprocessing:2.0from
MissTipo:shader-translation-glsl-to-p5-strands-2.0

Conversation

@MissTipo
Copy link
Contributor

Summary

This PR adds p5.strands translations for three existing shader examples and keeps the original GLSL versions alongside them for comparison.

Changes

  • renamed the original examples:
    • Filter Shader
    • Adjusting Positions With A Shader
    • Shader As A Texture
  • added p5.strands translations for each of the above examples
  • updated and remixed the example descriptions to match the renamed originals and the new p5.strands versions

Notes

The goal was to preserve the original GLSL examples while adding equivalent p5.strands versions that are easier to compare side by side.

Testing

  • ran the examples locally in the web editor/site preview
  • verified that the new p5.strands examples render correctly
  • verified that the original examples remain available under their renamed versions

- rename original GLSL examples to preserve them alongside the new versions
- add p5.strands translations for Filter Shader, Adjusting Positions With A Shader, and Shader As A Texture
- remix example descriptions to reflect the new p5.strands versions

Signed-off-by: MissTipo <dorine.a.tipo@gmail.com>
@ksen0 ksen0 self-requested a review March 16, 2026 13:31
Copy link
Collaborator

@davepagurek davepagurek left a comment

Choose a reason for hiding this comment

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

Nice work converting these! This all works, so I just left some comments more about code style and using the most recent p5.strands features to simplify the code.

}

function shaderAsTextureCallback() {
const time = uniformFloat(() => millis() / 1000.0);
Copy link
Collaborator

Choose a reason for hiding this comment

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

As in the earlier example, this doesn't actually need to be a uniform any more, inside of pixelInputs you should be able to write const time = millis() / 1000).

Copy link
Collaborator

Choose a reason for hiding this comment

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

In p5.strands we also don't need the .0 on numbers, 1000 will be fine.


function shaderAsTextureCallback() {
const time = uniformFloat(() => millis() / 1000.0);
const size = uniformVec2(() => [width, height]);
Copy link
Collaborator

Choose a reason for hiding this comment

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

I believe we can also just use width and height directly now without uniforms too!

return (coord - 0.5) / amount + 0.5;
}

getColor((inputs, canvasContent) => {
Copy link
Collaborator

Choose a reason for hiding this comment

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

We've recently introduced a flatter p5.strands API that uses filterColor.begin() and filterColor.end() instead of getColor with a callback, since people have found the nested functions confusing. See some examples in these docs: https://beta.p5js.org/reference/p5/buildfiltershader/

Mind switching to that syntax in these examples? for most other get* hooks, the get part is just removed, e.g. getWorldInputs becomes just worldInputs.

}

function wiggleCallback() {
const time = uniformFloat(() => millis());
Copy link
Collaborator

Choose a reason for hiding this comment

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

I believe this doesn't actually need to be a uniform any more, you can just use millis() directly inside of a strands shader 🙂

function wiggleCallback() {
const time = uniformFloat(() => millis());

getObjectInputs((inputs) => {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Similar to before, can we use the flat API here?

function shaderAsTextureCallback() {
const time = uniformFloat(() => millis() / 1000.0);
const size = uniformVec2(() => [width, height]);
// Y is flipped to match gl_FragCoord's bottom-up axis.
Copy link
Collaborator

Choose a reason for hiding this comment

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

Partially a comment for @ksen0: do you think the main target audience of these examples is people looking to understand strands from a background of GLSL, or people just learning about strands who don't already know GLSL? For the latter, explaining how things translate to gl_FragCoord is introducing a point of reference that they aren't familiar with. If that's the goal, it might be better to just omit references to how gl_FragCoord worked in the old version of this?

const time = uniformFloat(() => millis() / 1000.0);
const size = uniformVec2(() => [width, height]);
// Y is flipped to match gl_FragCoord's bottom-up axis.
const mouse = uniformVec2(() => [mouseX, height - mouseY]);
Copy link
Collaborator

Choose a reason for hiding this comment

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

Similarly, I think mouseX and mouseY should work without a uniform too! const mouse = [mouseX, mouseY] in a shader hook block should work.

return floor(distance(st, radius) * res) / scale;
}

getCameraInputs((inputs) => {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Can we switch these to the begin/end syntax?

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.

2 participants