Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ remix:
URL: https://dorinetipo.vercel.app/
code:
- label: 2026 p5.strands translation
URL: https://github.com/processing/p5.js-website/tree/main/src/content/examples/en/11_3D/07_Filter_Shader_p5strands
URL: https://github.com/processing/p5.js-website/tree/main/src/content/examples/en/16_Shaders/01_Filter_Shader_p5strands

- collectivelyAttributedSince: 2026
---
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
featuredImage: "../../../images/featured/11_3D-04_Filter_Shader-thumbnail.png"
featuredImageAlt: A screenshot of a video of a city crosswalk, with offset colors.
title: Filter Shader (GLSL)
oneLineDescription: Manipulate imagery with a shader.
oneLineDescription: Manipulate imagery with a shader, using GLSL.

remix:
- description: Creared by
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ remix:
URL: https://dorinetipo.vercel.app/
code:
- label: 2026 p5.strands translation
URL: https://github.com/processing/p5.js-website/tree/main/src/content/examples/en/11_3D/08_Adjusting_Positions_With_A_Shader_p5strands
URL: https://github.com/processing/p5.js-website/tree/main/src/content/examples/en/16_Shaders/03_Adjusting_Positions_With_A_Shader_p5strands

- collectivelyAttributedSince: 2026
---
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
featuredImage: "../../../images/featured/11_3D-05_Adjusting_Positions_With_A_Shader-thumbnail.png"
featuredImageAlt: A red-to-blue waving ribbon on a white background.
title: Adjusting Positions with a Shader (GLSL)
oneLineDescription: Use a shader to adjust shape vertices.
oneLineDescription: Use a shader to adjust shape vertices, using GLSL.

remix:
- description: Created by
Expand Down
40 changes: 40 additions & 0 deletions src/content/examples/en/16_Shaders/05_Strands_Gradient/code.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
let gradientShader;
function setup() {
createCanvas(400, 400, WEBGL);
gradientShader = buildFilterShader(gradient);
}

// This function is p5.strands code: it's like JavaScript, but
// where you can write vectors as arrays and use math oeprators on them
function gradient() {

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 think it would be helpful to add some comments (same for all them) that demonstrate how we talk abotu p5.sstrands eg: the code inside gradient() is p5.strands code, which is not quite normal JavaScript: here GLSL can be used as well as p5.js, and these define shades. filterColor is a hook, and is used to define shader behavior. Tiny notes about that.

// filterColor is an example of a *hook* in a strands shader, which
// lets you control different parts of the shader's job
filterColor.begin();
// Texture coordinates like filterColor.texCoord go from [0,0] in the
// top left to [1,1] in the bottom right
let start = [0.1, 0.1];
// Convert mouse coords to texture coordinate range by dividing
// by canvas size
let end = [mouseX, mouseY] / [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.

Every place where the sketch author needs to switch to [0,1] range logic could also use a comment imo

let startToPixel = length(filterColor.texCoord - start);
let startToEnd = length(end - start);
let gradientProgress = map(
startToPixel,
0,
startToEnd,
0,
1,
true
);
let outColor = lerpColor(
color('#F00'),
color('#0214f3'),
gradientProgress
);
filterColor.set(outColor);
filterColor.end();
}

function draw() {
filter(gradientShader);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
---
featuredImage: "../../../images/featured/11_3D_09_gradient.png"
featuredImageAlt: A gradient from red to blue.
title: Gradient (p5.strands)
oneLineDescription: Draw a radial gradient between two points in p5.strands.
featured: false

remix:
- description: Created by
attribution:
- name: Dave Pagurek
URL: https://www.davepagurek.com/
code:
- label: Code
URL: https://github.com/processing/p5.js-website/tree/main/src/content/examples/en/16_Shaders/05_Strands_Gradient
- collectivelyAttributedSince: 2026
---

This demonstrates a radial gradient, `lerp`ing between two colors, based on two points. It runs in a full-screen filter shader.
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
let ditherGradientShader;
function setup() {
createCanvas(400, 400, WEBGL);
ditherGradientShader = buildFilterShader(ditherGradient);
}

// This function is p5.strands code: it's like JavaScript, but
// where you can write vectors as arrays and use math oeprators on them
function ditherGradient() {
// filterColor is an example of a *hook* in a strands shader, which
// lets you control different parts of the shader's job
filterColor.begin();
randomSeed(0); // Comment out for a flickery output
// Or use the one below to use a low frame rate flicker
// randomSeed(floor(frameCount / 5))

// Texture coordinates like filterColor.texCoord go from [0,0] in the
// top left to [1,1] in the bottom right
let start = [0.1, 0.1];
// Convert mouse coords to texture coordinate range by dividing
// by canvas size
let end = [mouseX, mouseY] / [width, height];
let startToPixel = length(filterColor.texCoord - start);

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.

explaining what texCoord here is, maybe spelling out "tex" is for "texture" in the comment?

let startToEnd = length(end - start);
let gradientProgress = map(
startToPixel,
0,
startToEnd,
0,
1,
true
);
let outColor = color('#F00');
if (gradientProgress + random(-0.3, 0.3) > 0.5) {
outColor = color('#0214f3');
}
filterColor.set(outColor);
filterColor.end();
}

function draw() {
filter(ditherGradientShader);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
---
featuredImage: "../../../images/featured/11_3D_10_dithered_gradient.png"
featuredImageAlt: A dithered gradient from red to blue.
title: Dithered Gradient (p5.strands)
oneLineDescription: Draw a dithered radial gradient between two points in p5.strands.
featured: false

remix:
- description: Created by
attribution:
- name: Dave Pagurek
URL: https://www.davepagurek.com/
code:
- label: Code
URL: https://github.com/processing/p5.js-website/tree/main/src/content/examples/en/16_Shaders/06_Dithered_Strands_Gradient
- collectivelyAttributedSince: 2026
---

This demonstrates a radial gradient based on two points, but where it picks one color or the other without mixing between them. It runs in a full-screen filter shader.
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
let layer;
let blur;

function setup() {
createCanvas(windowWidth, windowHeight, WEBGL);
angleMode(DEGREES);
noStroke();

// Create framebuffer and shader objects
layer = createFramebuffer();
blur = buildFilterShader(blurCallback);

describe(
'A row of five spheres rotating in front of the camera. The closest and farthest spheres from the camera appear blurred.'
);
}

// This function is p5.strands code: it's like JavaScript, but
// where you can write vectors as arrays and use math oeprators on them
function blurCallback() {
// In draw, the depth info is passed in with setUniform
let depth = uniformTexture('depth');

// A helper function to tell us how blurry something a given
// distance away should be
function howBlurry(d) {
// Blur more the farther away we go from the

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 - naming: getTexture (strands, special) and getBlurriness (udf, arbitrary) are super different but kind of look/sound similar and are near each other. I know its clunky but maybe myBlurFunction instead of getBlurriness while a mouthful would highlight that this is not a special term of art, its just a sketch udf?

// focal point at depth=0.909
return min(abs(d - 0.909) * 200, 4);
}

function maxBlurDistance(blurriness) {
return blurriness * 0.01;
}

// filterColor is an example of a *hook* in a strands shader, which
// lets you control different parts of the shader's job
filterColor.begin();
let coord = filterColor.texCoord;
let color = getTexture(filterColor.canvasContent, coord);
let samples = 1;
let centerDepth = getTexture(depth, coord).r;
let blurriness = howBlurry(centerDepth);

for (let i = 0; i < 20; i++) {
// Sample nearby pixels in a spiral going out from the
// current pixel
let angle = i;
let distance = (i / 20) * maxBlurDistance(blurriness);
let offset = [cos(angle), sin(angle)] * distance;

// How close is the object at the nearby pixel?
let sampleDepth = getTexture(depth, coord + offset).r;

// How far should its blur reach?
let sampleBlurDistance = maxBlurDistance(getBlurriness(sampleDepth));

// If it's in front of the current pixel, or its blur overlaps
// with the current pixel, add its color to the average
if (sampleDepth >= centerDepth || sampleBlurDistance >= distance) {
color += getTexture(filterColor.canvasContent, coord + offset);
samples++;
}
}

filterColor.set(color / samples);
filterColor.end();
}

function draw() {
// Start drawing to framebuffer
layer.begin();
background(255);
ambientLight(100);
directionalLight(255, 255, 255, -1, 1, -1);
ambientMaterial(255, 0, 0);
fill(255, 255, 100);
specularMaterial(255);
shininess(150);

// Rotate 1° per frame
rotateY(frameCount);

// Place 5 spheres across canvas at equal distance
let sphereDistance = width / 4;
for (let x = -width / 2; x <= width / 2; x += sphereDistance) {
push();
translate(x, 0, 0);
sphere(width / 16);
pop();
}

// Stop drawing to framebuffer
layer.end();

// Draw the framebuffer to the canvas, then blur the canvas using
// the framebuffer's depth information
imageMode(CENTER);
image(layer, 0, 0);
blur.setUniform('depth', layer.depth);
filter(blur);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
---
featuredImage: "../../../images/featured/11_3D-06_Framebuffer_Blur-thumbnail.png"
featuredImageAlt: A row of five orange spheres. The closest and farthest spheres from the camera appear blurred.
title: Depth Blur (p5.strands)
oneLineDescription: Simulate a camera's depth of field, with a shader written in p5.strands.

remix:
- description: Created by
attribution:
- name: Dave Pagurek
URL: https://www.davepagurek.com/
code:
- label: pre-2023 example
URL: https://github.com/processing/p5.js-website-legacy/blob/main/src/data/examples/en/20_3D/12_framebuffer_blur.js

- description: Revised by
attribution:
- name: Caleb Foss
URL: https://github.com/calebfoss
code:
- label: 2023 code
URL: https://github.com/processing/p5.js-example/tree/main/examples/11_3D/06_Framebuffer_Blur

- description: Remixed by
attribution:
- name: Dave Pagurek
URL: https://www.davepagurek.com/
code:
- label: 2026 p5.strands translation
URL: https://github.com/processing/p5.js-website/tree/main/src/content/examples/en/16_Shaders/07_Framebuffer_Blur_p5strands

- collectivelyAttributedSince: 2026
---

The
<a href="https://www.khronos.org/opengl/wiki/Shader" target="_blank">shader</a>
in this example uses depth information from a
<a href="https://p5js.org/reference/p5/p5.Framebuffer" target="_blank">p5.Framebuffer</a>
to apply a blur. On a real camera, objects appear blurred if they
are closer or farther than the lens's focus. This simulates that
effect. First, the sketch renders five spheres to the framebuffer.
Then, it renders the framebuffer to the canvas and applies the blur
shader, which is written in p5.strands.
Original file line number Diff line number Diff line change
@@ -1,17 +1,23 @@
---
featuredImage: "../../../images/featured/11_3D-06_Framebuffer_Blur-thumbnail.png"
featuredImageAlt: A row of five orange spheres. The closest and farthest spheres from the camera appear blurred.
title: Framebuffer Blur
oneLineDescription: Simulate a camera's depth of field.
title: Depth Blur (GLSL)
oneLineDescription: Simulate a camera's depth of field, written in GLSL.

remix:
- description: Created by
attribution:
- name: Dave Pagurek
URL: https://www.davepagurek.com/
code:
- label: pre-2023 example
URL: https://github.com/processing/p5.js-website-legacy/blob/main/src/data/examples/en/20_3D/12_framebuffer_blur.js

- description: Revised by
attribution:
- name: Caleb Foss
URL: https://github.com/calebfoss
code:
- label: pre-2023 example
URL: https://github.com/processing/p5.js-website-legacy/blob/main/src/data/examples/en/20_3D/12_framebuffer_blur.js
- label: 2023 code
URL: https://github.com/processing/p5.js-example/tree/main/examples/11_3D/06_Framebuffer_Blur
---
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
let video;
let blurShader;
function setup() {
createCanvas(400, 400, WEBGL);
video = createVideo(
'/assets/DiagonalCrosswalkYongeDundas.mp4'
);
video.volume(0);
video.hide();
video.loop();
blurShader = buildFilterShader(myBlur);
}

// This function is p5.strands code: it's like JavaScript, but
// where you can write vectors as arrays and use math oeprators on them
function myBlur() {
// filterColor is an example of a *hook* in a strands shader, which
// lets you control different parts of the shader's job
filterColor.begin();
// The range of texture coordinates is [0,0] in the top left to [1,1] in
// the bottom right. These are the units shaders use to tell you where you
// are on the canvas for filter shaders, or on a shape for a material shader.
let coord = filterColor.texCoord;
let distFromCenter = length(coord - [0.5, 0.5]);
// Map distance from center to blurriness, also in texture coordinate units.
// Since the whole canvas is only 1 unit across, a max blurriness of 0.1 is
// actually pretty blurry (10% of the canvas size!)
let blurAmount = map(distFromCenter, 0.2, 1, 0, 0.1, true);
coord += blurAmount * [random(-1, 1), random(-1, 1)];
filterColor.set(getTexture(filterColor.canvasContent, coord));
filterColor.end();
}

function draw() {
imageMode(CENTER);
image(video, 0, 0, width, height, 0, 0, video.width, video.height, COVER);
filter(blurShader);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
---
featuredImage: "../../../images/featured/11_3D_11_variable_blur.jpg"
featuredImageAlt: A city scene blurred around the edges of the frame
title: Variable Blur (p5.strands)
oneLineDescription: Create a blur shader with a different amount of blur at different parts of the canvas.
featured: false

remix:
- description: Created by
attribution:
- name: Dave Pagurek
URL: https://www.davepagurek.com/
code:
- label: Code
URL: https://github.com/processing/p5.js-website/tree/main/src/content/examples/en/16_Shaders/09_Strands_Variable_Blur
- collectivelyAttributedSince: 2026
---

This demonstrates a custom blur shader in p5.strands. The blur is accomplished by adding a random offset to the coordinate at which the texture is sampled. By using only one sample, the blur ends up noisy. Try averaging a few samples to get a smoother blur!
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading