diff --git a/src/strands/p5.strands.js b/src/strands/p5.strands.js index 7d212c332d..28d3ba13b7 100644 --- a/src/strands/p5.strands.js +++ b/src/strands/p5.strands.js @@ -709,3 +709,131 @@ if (typeof p5 !== "undefined") { * @method getCameraInputs * @param {Function} callback */ + +/** + * Performs linear interpolation between two values. + * + * The `mix()` function linearly interpolates between two values based on a third + * parameter. It's a GLSL built-in function available in p5.strands shaders. + * + * The function computes: `x * (1 - a) + y * a` + * + * When `a` is 0.0, the function returns `x`. When `a` is 1.0, it returns `y`. + * Values between 0.0 and 1.0 produce a linear blend between the two values. + * + * This function works with scalars, vectors (vec2, vec3, vec4), and can also + * accept a boolean for the third parameter to select between the two values. + * + * Note: This function is only available inside shader code created with + * buildMaterialShader(), + * buildColorShader(), or similar functions. + * For regular p5.js code, use lerp() instead. + * + * @method mix + * @param {Number|p5.Vector} x first value to interpolate from. + * @param {Number|p5.Vector} y second value to interpolate to. + * @param {Number|Boolean} a interpolation amount (0.0-1.0) or boolean selector. + * @return {Number|p5.Vector} interpolated value. + * + * @example + *
+ * let myShader;
+ *
+ * function setup() {
+ * createCanvas(200, 200, WEBGL);
+ * myShader = buildMaterialShader(applyMix);
+ * describe('A sphere that transitions smoothly between red and blue.');
+ * }
+ *
+ * function applyMix() {
+ * let factor = uniformFloat();
+ *
+ * pixelInputs.begin();
+ * // Mix between red and blue based on factor
+ * let red = vec3(1, 0, 0);
+ * let blue = vec3(0, 0, 1);
+ * pixelInputs.color = vec4(mix(red, blue, factor), 1);
+ * pixelInputs.end();
+ * }
+ *
+ * function draw() {
+ * background(255);
+ * shader(myShader);
+ * // Oscillate factor between 0 and 1
+ * let factor = (sin(frameCount * 0.02) + 1) / 2;
+ * myShader.setUniform('factor', factor);
+ * noStroke();
+ * sphere(80);
+ * }
+ *
+ *
+ * let myShader;
+ *
+ * function setup() {
+ * createCanvas(200, 200, WEBGL);
+ * myShader = buildMaterialShader(positionMix);
+ * describe('A sphere with vertices that blend between two positions.');
+ * }
+ *
+ * function positionMix() {
+ * let time = uniformFloat();
+ *
+ * worldInputs.begin();
+ * // Blend vertex position between original and modified
+ * let originalPos = worldInputs.position;
+ * let modifiedPos = originalPos + vec3(0, sin(time * 0.001) * 20, 0);
+ * let factor = (sin(worldInputs.position.x * 0.1) + 1) / 2;
+ * worldInputs.position = mix(originalPos, modifiedPos, factor);
+ * worldInputs.end();
+ * }
+ *
+ * function draw() {
+ * background(220);
+ * shader(myShader);
+ * myShader.setUniform('time', millis());
+ * lights();
+ * noStroke();
+ * fill('red');
+ * sphere(70);
+ * }
+ *
+ *
+ * let myShader;
+ *
+ * function setup() {
+ * createCanvas(200, 200, WEBGL);
+ * myShader = buildMaterialShader(gradientMix);
+ * describe('A torus with a color gradient created using mix().');
+ * }
+ *
+ * function gradientMix() {
+ * pixelInputs.begin();
+ * // Create a gradient based on texture coordinates
+ * let gradient = pixelInputs.uv.x;
+ * let color1 = vec3(1, 0.5, 0); // Orange
+ * let color2 = vec3(0.5, 0, 1); // Purple
+ * pixelInputs.color = vec4(mix(color1, color2, gradient), 1);
+ * pixelInputs.end();
+ * }
+ *
+ * function draw() {
+ * background(200);
+ * shader(myShader);
+ * lights();
+ * noStroke();
+ * rotateX(frameCount * 0.01);
+ * rotateY(frameCount * 0.01);
+ * torus(60, 20);
+ * }
+ *
+ *