From db08f6d3d203d9147adc52249e33c32a37c0f56c Mon Sep 17 00:00:00 2001 From: JUNAID NAWAZ Date: Wed, 28 Jan 2026 01:32:24 +0530 Subject: [PATCH 1/4] docs(p5.strands): add smoothstep documentation --- src/strands/p5.strands.js | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/src/strands/p5.strands.js b/src/strands/p5.strands.js index 7d212c332d..6aa05ea47f 100644 --- a/src/strands/p5.strands.js +++ b/src/strands/p5.strands.js @@ -275,6 +275,45 @@ if (typeof p5 !== "undefined") { * */ +/** + * @method smoothstep + * @description + * A shader function that performs smooth Hermite interpolation between `0.0` + * and `1.0`. + * + * This function is equivalent to the GLSL built-in + * `smoothstep(edge0, edge1, x)` and is available inside p5.strands shader + * callbacks. It is commonly used to create soft transitions, smooth edges, + * fades, and anti-aliased effects. + * + * - Returns `0.0` when `x` is less than or equal to `edge0` + * - Returns `1.0` when `x` is greater than or equal to `edge1` + * - Smoothly interpolates between `0.0` and `1.0` when `x` is between them + * + * @param {Number} edge0 + * Lower edge of the transition + * @param {Number} edge1 + * Upper edge of the transition + * @param {Number} x + * Input value to interpolate + * + * @returns {Number} + * A value between `0.0` and `1.0` + * + * @example + *
+ * + * function material() { + * let t = uniformFloat(); + * combineColors.begin(); + * let fade = smoothstep(0.2, 0.8, sin(t * 0.001)); + * combineColors.opacity *= fade; + * combineColors.end(); + * } + * + *
+ */ + /** * @method beforeVertex * @private From dc10b0a9bd2f3a04d7ce19874468e26690f93a45 Mon Sep 17 00:00:00 2001 From: JUNAID NAWAZ Date: Wed, 28 Jan 2026 02:58:06 +0530 Subject: [PATCH 2/4] docs(p5.strands): improve smoothstep examples --- src/strands/p5.strands.js | 65 +++++++++++++++++++++++++++++++++++---- 1 file changed, 59 insertions(+), 6 deletions(-) diff --git a/src/strands/p5.strands.js b/src/strands/p5.strands.js index 6aa05ea47f..e3eda4cc2d 100644 --- a/src/strands/p5.strands.js +++ b/src/strands/p5.strands.js @@ -303,12 +303,65 @@ if (typeof p5 !== "undefined") { * @example *
* - * function material() { - * let t = uniformFloat(); - * combineColors.begin(); - * let fade = smoothstep(0.2, 0.8, sin(t * 0.001)); - * combineColors.opacity *= fade; - * combineColors.end(); + * // Example 1: Smooth color fade across the canvas (no uniforms) + * + * let fadeShader; + * + * function fadeCallback() { + * getFinalColor((color) => { + * // Normalize x position from 0 → 1 across the canvas + * let x = pixelInputs.position.x / canvasSize.x; + * + * // Smooth transition from black to red + * let t = smoothstep(0.2, 0.8, x); + * + * return [t, 0, 0, 1]; + * }); + * } + * + * function setup() { + * createCanvas(300, 200, WEBGL); + * fadeShader = baseColorShader().modify(fadeCallback); + * } + * + * function draw() { + * background(0); + * shader(fadeShader); + * rect(-width / 2, -height / 2, width, height); + * } + * + *
+ * + * @example + *
+ * + * // Example 2: Animate the smooth transition over time (uses a uniform) + * + * let animatedShader; + * + * function animatedFadeCallback() { + * const time = uniformFloat(() => millis() * 0.001); + * + * getFinalColor((color) => { + * let x = pixelInputs.position.x / canvasSize.x; + * + * // Move the smoothstep window over time + * let center = 0.5 + 0.3 * sin(time); + * let t = smoothstep(center - 0.1, center + 0.1, x); + * + * return [t, 0, 0, 1]; + * }); + * } + * + * function setup() { + * createCanvas(300, 200, WEBGL); + * animatedShader = baseColorShader().modify(animatedFadeCallback); + * } + * + * function draw() { + * background(0); + * shader(animatedShader); + * rect(-width / 2, -height / 2, width, height); * } * *
From 5dd9b2de4adf8f658f135f95d3ba12cb0872efe4 Mon Sep 17 00:00:00 2001 From: JUNAID NAWAZ Date: Wed, 28 Jan 2026 16:32:17 +0530 Subject: [PATCH 3/4] docs(p5.strands): fix smoothstep examples and add animated example --- src/strands/p5.strands.js | 72 +++++++++++++++++++++++---------------- 1 file changed, 42 insertions(+), 30 deletions(-) diff --git a/src/strands/p5.strands.js b/src/strands/p5.strands.js index e3eda4cc2d..145b50f5bd 100644 --- a/src/strands/p5.strands.js +++ b/src/strands/p5.strands.js @@ -30,7 +30,11 @@ function strands(p5, fn) { ////////////////////////////////////////////// // Global Runtime ////////////////////////////////////////////// - function initStrandsContext(ctx, backend, { active = false, renderer = null, baseShader = null } = {}) { + function initStrandsContext( + ctx, + backend, + { active = false, renderer = null, baseShader = null } = {}, + ) { ctx.dag = createDirectedAcyclicGraph(); ctx.cfg = createControlFlowGraph(); ctx.uniforms = []; @@ -78,11 +82,8 @@ function strands(p5, fn) { const prev = {}; for (const key of Object.getOwnPropertyNames(fn)) { - const descriptor = Object.getOwnPropertyDescriptor( - fn, - key - ); - if (descriptor && !descriptor.get && typeof fn[key] === 'function') { + const descriptor = Object.getOwnPropertyDescriptor(fn, key); + if (descriptor && !descriptor.get && typeof fn[key] === "function") { prev[key] = window[key]; window[key] = fn[key].bind(pInst); } @@ -104,7 +105,10 @@ function strands(p5, fn) { p5.Shader.prototype.modify = function (shaderModifier, scope = {}) { try { - if (shaderModifier instanceof Function || typeof shaderModifier === 'string') { + if ( + shaderModifier instanceof Function || + typeof shaderModifier === "string" + ) { // Reset the context object every time modify is called; // const backend = glslBackend; initStrandsContext(strandsContext, this._renderer.strandsBackend, { @@ -121,9 +125,10 @@ function strands(p5, fn) { if (options.parser) { // #7955 Wrap function declaration code in brackets so anonymous functions are not top level statements, which causes an error in acorn when parsing // https://github.com/acornjs/acorn/issues/1385 - const sourceString = typeof shaderModifier === 'string' - ? `(${shaderModifier})` - : `(${shaderModifier.toString()})`; + const sourceString = + typeof shaderModifier === "string" + ? `(${shaderModifier})` + : `(${shaderModifier.toString()})`; strandsCallback = transpileStrandsToJS( p5, sourceString, @@ -303,31 +308,36 @@ if (typeof p5 !== "undefined") { * @example *
* - * // Example 1: Smooth color fade across the canvas (no uniforms) + * // Example 1: Smooth fade across the canvas using coordinates (no uniforms) * * let fadeShader; * * function fadeCallback() { - * getFinalColor((color) => { - * // Normalize x position from 0 → 1 across the canvas - * let x = pixelInputs.position.x / canvasSize.x; + * getColor((inputs, canvasContent) => { + * // Normalized x coordinate (0 → 1 across the canvas) + * let x = inputs.texCoord.x; * - * // Smooth transition from black to red - * let t = smoothstep(0.2, 0.8, x); + * // Narrow smooth transition band + * let t = smoothstep(0.4, 0.6, x); * - * return [t, 0, 0, 1]; + * // Sample the original color + * let col = getTexture(canvasContent, inputs.texCoord); + * + * // Fade from black to the original image + * return [col.rgb * t, col.a]; * }); * } * * function setup() { * createCanvas(300, 200, WEBGL); - * fadeShader = baseColorShader().modify(fadeCallback); + * fadeShader = baseFilterShader().modify(fadeCallback); * } * * function draw() { * background(0); - * shader(fadeShader); - * rect(-width / 2, -height / 2, width, height); + * fill(255); + * rect(-100, -50, 200, 100); + * filter(fadeShader); * } * *
@@ -335,33 +345,35 @@ if (typeof p5 !== "undefined") { * @example *
* - * // Example 2: Animate the smooth transition over time (uses a uniform) + * // Example 2: Animate the smooth transition using a uniform * * let animatedShader; * * function animatedFadeCallback() { * const time = uniformFloat(() => millis() * 0.001); * - * getFinalColor((color) => { - * let x = pixelInputs.position.x / canvasSize.x; + * getColor((inputs, canvasContent) => { + * let x = inputs.texCoord.x; * - * // Move the smoothstep window over time - * let center = 0.5 + 0.3 * sin(time); - * let t = smoothstep(center - 0.1, center + 0.1, x); + * // Move the smoothstep band back and forth + * let center = 0.5 + 0.25 * sin(time); + * let t = smoothstep(center - 0.05, center + 0.05, x); * - * return [t, 0, 0, 1]; + * let col = getTexture(canvasContent, inputs.texCoord); + * return [col.rgb * t, col.a]; * }); * } * * function setup() { * createCanvas(300, 200, WEBGL); - * animatedShader = baseColorShader().modify(animatedFadeCallback); + * animatedShader = baseFilterShader().modify(animatedFadeCallback); * } * * function draw() { * background(0); - * shader(animatedShader); - * rect(-width / 2, -height / 2, width, height); + * fill(255); + * rect(-100, -50, 200, 100); + * filter(animatedShader); * } * *
From dbd942b1a6b71cf6862c0de45d68dd02b2cc1a3e Mon Sep 17 00:00:00 2001 From: JUNAID NAWAZ Date: Wed, 28 Jan 2026 19:14:48 +0530 Subject: [PATCH 4/4] docs(p5.strands): simplify smoothstep examples and reduce concepts --- src/strands/p5.strands.js | 32 ++++++++++++-------------------- 1 file changed, 12 insertions(+), 20 deletions(-) diff --git a/src/strands/p5.strands.js b/src/strands/p5.strands.js index 145b50f5bd..934bd0959a 100644 --- a/src/strands/p5.strands.js +++ b/src/strands/p5.strands.js @@ -306,25 +306,22 @@ if (typeof p5 !== "undefined") { * A value between `0.0` and `1.0` * * @example - *
+ *
* - * // Example 1: Smooth fade across the canvas using coordinates (no uniforms) + * // Example 1: A soft vertical fade using smoothstep (no uniforms) * * let fadeShader; * * function fadeCallback() { - * getColor((inputs, canvasContent) => { - * // Normalized x coordinate (0 → 1 across the canvas) + * getColor((inputs) => { + * // x goes from 0 → 1 across the canvas * let x = inputs.texCoord.x; * - * // Narrow smooth transition band - * let t = smoothstep(0.4, 0.6, x); - * - * // Sample the original color - * let col = getTexture(canvasContent, inputs.texCoord); + * // smoothstep creates a soft transition instead of a hard edge + * let t = smoothstep(0.45, 0.55, x); * - * // Fade from black to the original image - * return [col.rgb * t, col.a]; + * // Use t directly as brightness + * return [t, t, t, 1]; * }); * } * @@ -335,15 +332,13 @@ if (typeof p5 !== "undefined") { * * function draw() { * background(0); - * fill(255); - * rect(-100, -50, 200, 100); * filter(fadeShader); * } * *
* * @example - *
+ *
* * // Example 2: Animate the smooth transition using a uniform * @@ -352,15 +347,14 @@ if (typeof p5 !== "undefined") { * function animatedFadeCallback() { * const time = uniformFloat(() => millis() * 0.001); * - * getColor((inputs, canvasContent) => { + * getColor((inputs) => { * let x = inputs.texCoord.x; * - * // Move the smoothstep band back and forth + * // Move the smoothstep band back and forth over time * let center = 0.5 + 0.25 * sin(time); * let t = smoothstep(center - 0.05, center + 0.05, x); * - * let col = getTexture(canvasContent, inputs.texCoord); - * return [col.rgb * t, col.a]; + * return [t, t, t, 1]; * }); * } * @@ -371,8 +365,6 @@ if (typeof p5 !== "undefined") { * * function draw() { * background(0); - * fill(255); - * rect(-100, -50, 200, 100); * filter(animatedShader); * } *