UNPKG

p5

Version:

[![npm version](https://badge.fury.io/js/p5.svg)](https://www.npmjs.com/package/p5)

1,615 lines (1,600 loc) 79.1 kB
// This file is auto-generated from JSDoc documentation import p5 from 'p5'; import { Color } from '../color/p5.Color'; declare module 'p5' { /** * Loads vertex and fragment shaders to create a * p5.Shader object.Shaders are programs that run on the graphics processing unit (GPU). They * can process many pixels at the same time, making them fast for many * graphics tasks. They’re written in a language called * GLSL * and run along with the rest of the code in a sketch.Once the p5.Shader object is created, it can be * used with the shader() function, as in * `shader(myShader)`. A shader program consists of two files, a vertex shader * and a fragment shader. The vertex shader affects where 3D geometry is drawn * on the screen and the fragment shader affects color.`loadShader()` loads the vertex and fragment shaders from their `.vert` and * `.frag` files. For example, calling * `loadShader('assets/shader.vert', 'assets/shader.frag')` loads both * required shaders and returns a p5.Shader object.The third parameter, `successCallback`, is optional. If a function is * passed, it will be called once the shader has loaded. The callback function * can use the new p5.Shader object as its * parameter. The return value of the `successCallback()` function will be used * as the final return value of `loadShader()`.The fourth parameter, `failureCallback`, is also optional. If a function is * passed, it will be called if the shader fails to load. The callback * function can use the event error as its parameter. The return value of the ` * failureCallback()` function will be used as the final return value of `loadShader()`.This function returns a `Promise` and should be used in an `async` setup with * `await`. See the examples for the usage syntax.Note: Shaders can only be used in WebGL mode. * * @param path of the vertex shader to be loaded. * @param path of the fragment shader to be loaded. * @param function to call once the shader is loaded. Can be passed the * <a href="#/p5.Shader">p5.Shader</a> object. * @param function to call if the shader fails to load. Can be passed an * `Error` event object. * @return new shader created from the vertex and fragment shader files. * @example <div modernizr='webgl'> * <code> * // Note: A "uniform" is a global variable within a shader program. * * let mandelbrot; * * // Load the shader and create a p5.Shader object. * async function setup() { * mandelbrot = await loadShader('assets/shader.vert', 'assets/shader.frag'); * * createCanvas(100, 100, WEBGL); * * // Compile and apply the p5.Shader object. * shader(mandelbrot); * * // Set the shader uniform p to an array. * mandelbrot.setUniform('p', [-0.74364388703, 0.13182590421]); * * // Set the shader uniform r to the value 1.5. * mandelbrot.setUniform('r', 1.5); * * // Add a quad as a display surface for the shader. * quad(-1, -1, 1, -1, 1, 1, -1, 1); * * describe('A black fractal image on a magenta background.'); * } * </code> * </div> * * <div> * <code> * // Note: A "uniform" is a global variable within a shader program. * * let mandelbrot; * * // Load the shader and create a p5.Shader object. * async function setup() { * mandelbrot = await loadShader('assets/shader.vert', 'assets/shader.frag'); * * createCanvas(100, 100, WEBGL); * * // Use the p5.Shader object. * shader(mandelbrot); * * // Set the shader uniform p to an array. * mandelbrot.setUniform('p', [-0.74364388703, 0.13182590421]); * * describe('A fractal image zooms in and out of focus.'); * } * * function draw() { * // Set the shader uniform r to a value that oscillates between 0 and 2. * mandelbrot.setUniform('r', sin(frameCount * 0.01) + 1); * * // Add a quad as a display surface for the shader. * quad(-1, -1, 1, -1, 1, 1, -1, 1); * } * </code> * </div> */ function loadShader(vertFilename: string | Request, fragFilename: string | Request, successCallback?: Function, failureCallback?: Function): Promise<p5.Shader>; /** * Creates a new p5.Shader object.Shaders are programs that run on the graphics processing unit (GPU). They * can process many pixels at the same time, making them fast for many * graphics tasks. They’re written in a language called * GLSL * and run along with the rest of the code in a sketch.Once the p5.Shader object is created, it can be * used with the shader() function, as in * `shader(myShader)`. A shader program consists of two parts, a vertex shader * and a fragment shader. The vertex shader affects where 3D geometry is drawn * on the screen and the fragment shader affects color.The first parameter, `vertSrc`, sets the vertex shader. It’s a string that * contains the vertex shader program written in GLSL.The second parameter, `fragSrc`, sets the fragment shader. It’s a string * that contains the fragment shader program written in GLSL.A shader can optionally describe which are functions in GLSL that * users may choose to provide to customize the behavior of the shader using the * `modify()` method of `p5.Shader`. These are added by * describing the hooks in a third parameter, `options`, and referencing the hooks in * your `vertSrc` or `fragSrc`. Hooks for the vertex or fragment shader are described under * the `vertex` and `fragment` keys of `options`. Each one is an object. where each key is * the type and name of a hook function, and each value is a string with the * parameter list and default implementation of the hook. For example, to let users * optionally run code at the start of the vertex shader, the options object could * include:`{ * vertex: { * 'void beforeVertex': '() {}' * } * }`Then, in your vertex shader source, you can run a hook by calling a function * with the same name prefixed by `HOOK_`. If you want to check if the default * hook has been replaced, maybe to avoid extra overhead, you can check if the * same name prefixed by `AUGMENTED_HOOK_` has been defined:`void main() { * // In most cases, just calling the hook is fine: * HOOK_beforeVertex(); * * // Alternatively, for more efficiency: * #ifdef AUGMENTED_HOOK_beforeVertex * HOOK_beforeVertex(); * #endif * * // Add the rest of your shader code here! * }`Note: Only filter shaders can be used in 2D mode. All shaders can be used * in WebGL mode. * * @param source code for the vertex shader. * @param source code for the fragment shader. * @param An optional object describing how this shader can * be augmented with hooks. It can include: * - `vertex`: An object describing the available vertex shader hooks. * - `fragment`: An object describing the available frament shader hooks. * @returns new shader object created from the * vertex and fragment shaders. * @example <div modernizr='webgl'> * <code> * // Note: A "uniform" is a global variable within a shader program. * * // Create a string with the vertex shader program. * // The vertex shader is called for each vertex. * let vertSrc = ` * precision highp float; * uniform mat4 uModelViewMatrix; * uniform mat4 uProjectionMatrix; * attribute vec3 aPosition; * attribute vec2 aTexCoord; * varying vec2 vTexCoord; * * void main() { * vTexCoord = aTexCoord; * vec4 positionVec4 = vec4(aPosition, 1.0); * gl_Position = uProjectionMatrix * uModelViewMatrix * positionVec4; * } * `; * * // Create a string with the fragment shader program. * // The fragment shader is called for each pixel. * let fragSrc = ` * precision highp float; * * void main() { * // Set each pixel's RGBA value to yellow. * gl_FragColor = vec4(1.0, 1.0, 0.0, 1.0); * } * `; * * function setup() { * createCanvas(100, 100, WEBGL); * * // Create a p5.Shader object. * let shaderProgram = createShader(vertSrc, fragSrc); * * // Compile and apply the p5.Shader object. * shader(shaderProgram); * * // Style the drawing surface. * noStroke(); * * // Add a plane as a drawing surface. * plane(100, 100); * * describe('A yellow square.'); * } * </code> * </div> * * <div> * <code> * // Note: A "uniform" is a global variable within a shader program. * * // Create a string with the vertex shader program. * // The vertex shader is called for each vertex. * let vertSrc = ` * precision highp float; * uniform mat4 uModelViewMatrix; * uniform mat4 uProjectionMatrix; * attribute vec3 aPosition; * attribute vec2 aTexCoord; * varying vec2 vTexCoord; * * void main() { * vTexCoord = aTexCoord; * vec4 positionVec4 = vec4(aPosition, 1.0); * gl_Position = uProjectionMatrix * uModelViewMatrix * positionVec4; * } * `; * * // Create a string with the fragment shader program. * // The fragment shader is called for each pixel. * let fragSrc = ` * precision highp float; * uniform vec2 p; * uniform float r; * const int numIterations = 500; * varying vec2 vTexCoord; * * void main() { * vec2 c = p + gl_FragCoord.xy * r; * vec2 z = c; * float n = 0.0; * * for (int i = numIterations; i > 0; i--) { * if (z.x * z.x + z.y * z.y > 4.0) { * n = float(i) / float(numIterations); * break; * } * z = vec2(z.x * z.x - z.y * z.y, 2.0 * z.x * z.y) + c; * } * * gl_FragColor = vec4( * 0.5 - cos(n * 17.0) / 2.0, * 0.5 - cos(n * 13.0) / 2.0, * 0.5 - cos(n * 23.0) / 2.0, * 1.0 * ); * } * `; * * function setup() { * createCanvas(100, 100, WEBGL); * * // Create a p5.Shader object. * let mandelbrot = createShader(vertSrc, fragSrc); * * // Compile and apply the p5.Shader object. * shader(mandelbrot); * * // Set the shader uniform p to an array. * // p is the center point of the Mandelbrot image. * mandelbrot.setUniform('p', [-0.74364388703, 0.13182590421]); * * // Set the shader uniform r to 0.005. * // r is the size of the image in Mandelbrot-space. * mandelbrot.setUniform('r', 0.005); * * // Style the drawing surface. * noStroke(); * * // Add a plane as a drawing surface. * plane(100, 100); * * describe('A black fractal image on a magenta background.'); * } * </code> * </div> * * <div> * <code> * // Note: A "uniform" is a global variable within a shader program. * * // Create a string with the vertex shader program. * // The vertex shader is called for each vertex. * let vertSrc = ` * precision highp float; * uniform mat4 uModelViewMatrix; * uniform mat4 uProjectionMatrix; * * attribute vec3 aPosition; * attribute vec2 aTexCoord; * varying vec2 vTexCoord; * * void main() { * vTexCoord = aTexCoord; * vec4 positionVec4 = vec4(aPosition, 1.0); * gl_Position = uProjectionMatrix * uModelViewMatrix * positionVec4; * } * `; * * // Create a string with the fragment shader program. * // The fragment shader is called for each pixel. * let fragSrc = ` * precision highp float; * uniform vec2 p; * uniform float r; * const int numIterations = 500; * varying vec2 vTexCoord; * * void main() { * vec2 c = p + gl_FragCoord.xy * r; * vec2 z = c; * float n = 0.0; * * for (int i = numIterations; i > 0; i--) { * if (z.x * z.x + z.y * z.y > 4.0) { * n = float(i) / float(numIterations); * break; * } * * z = vec2(z.x * z.x - z.y * z.y, 2.0 * z.x * z.y) + c; * } * * gl_FragColor = vec4( * 0.5 - cos(n * 17.0) / 2.0, * 0.5 - cos(n * 13.0) / 2.0, * 0.5 - cos(n * 23.0) / 2.0, * 1.0 * ); * } * `; * * let mandelbrot; * * function setup() { * createCanvas(100, 100, WEBGL); * * // Create a p5.Shader object. * mandelbrot = createShader(vertSrc, fragSrc); * * // Apply the p5.Shader object. * shader(mandelbrot); * * // Set the shader uniform p to an array. * // p is the center point of the Mandelbrot image. * mandelbrot.setUniform('p', [-0.74364388703, 0.13182590421]); * * describe('A fractal image zooms in and out of focus.'); * } * * function draw() { * // Set the shader uniform r to a value that oscillates * // between 0 and 0.005. * // r is the size of the image in Mandelbrot-space. * let radius = 0.005 * (sin(frameCount * 0.01) + 1); * mandelbrot.setUniform('r', radius); * * // Style the drawing surface. * noStroke(); * * // Add a plane as a drawing surface. * plane(100, 100); * } * </code> * </div> * * <div> * <code> * // A shader with hooks. * let myShader; * * // A shader with modified hooks. * let modifiedShader; * * // Create a string with the vertex shader program. * // The vertex shader is called for each vertex. * let vertSrc = ` * precision highp float; * uniform mat4 uModelViewMatrix; * uniform mat4 uProjectionMatrix; * * attribute vec3 aPosition; * attribute vec2 aTexCoord; * * void main() { * vec4 positionVec4 = vec4(aPosition, 1.0); * gl_Position = uProjectionMatrix * uModelViewMatrix * positionVec4; * } * `; * * // Create a fragment shader that uses a hook. * let fragSrc = ` * precision highp float; * void main() { * // Let users override the color * gl_FragColor = HOOK_getColor(vec4(1., 0., 0., 1.)); * } * `; * * function setup() { * createCanvas(50, 50, WEBGL); * * // Create a shader with hooks * myShader = createShader(vertSrc, fragSrc, { * fragment: { * 'vec4 getColor': '(vec4 color) { return color; }' * } * }); * * // Make a version of the shader with a hook overridden * modifiedShader = myShader.modify({ * 'vec4 getColor': `(vec4 color) { * return vec4(0., 0., 1., 1.); * }` * }); * } * * function draw() { * noStroke(); * * push(); * shader(myShader); * translate(-width/3, 0); * sphere(10); * pop(); * * push(); * shader(modifiedShader); * translate(width/3, 0); * sphere(10); * pop(); * } * </code> * </div> */ function createShader(vertSrc: string, fragSrc: string, options?: object): p5.Shader; /** * Creates and loads a filter shader from an external file. * * @param path to the fragment shader file * @param callback to be called once the shader is * loaded. Will be passed the * <a href="#/p5.Shader">p5.Shader</a> object. * @param callback to be called if there is an error * loading the shader. Will be passed the * error event. * @return a promise that resolves with a shader object * @example <div modernizr='webgl'> * <code> * let myShader; * * async function setup() { * myShader = await loadFilterShader('assets/basic.frag'); * createCanvas(100, 100, WEBGL); * noStroke(); * } * * function draw() { * // shader() sets the active shader with our shader * shader(myShader); * * // rect gives us some geometry on the screen * rect(-50, -50, width, height); * } * </code> * </div> * @alt A rectangle with a shader applied to it. */ function loadFilterShader(fragFilename: string, successCallback?: Function, failureCallback?: Function): Promise<p5.Shader>; /** * Creates a p5.Shader object to be used with the * filter() function.`createFilterShader()` works like * createShader() but has a default vertex * shader included. `createFilterShader()` is intended to be used along with * filter() for filtering the contents of a canvas. * A filter shader will be applied to the whole canvas instead of just * p5.Geometry objects.The parameter, `fragSrc`, sets the fragment shader. It’s a string that * contains the fragment shader program written in * GLSL.The p5.Shader object that's created has some * uniforms that can be set:The p5.Shader that's created also provides * `varying vec2 vTexCoord`, a coordinate with values between 0 and 1. * `vTexCoord` describes where on the canvas the pixel will be drawn.For more info about filters and shaders, see Adam Ferriss' repo of shader examples * or the Introduction to Shaders tutorial. * * @param source code for the fragment shader. * @returns new shader object created from the fragment shader. * @example <div modernizr='webgl'> * <code> * function setup() { * let fragSrc = `precision highp float; * void main() { * gl_FragColor = vec4(1.0, 1.0, 0.0, 1.0); * }`; * * createCanvas(100, 100, WEBGL); * let s = createFilterShader(fragSrc); * filter(s); * describe('a yellow canvas'); * } * </code> * </div> * * <div modernizr='webgl'> * <code> * let img, s; * async function setup() { * img = await loadImage('assets/bricks.jpg'); * let fragSrc = `precision highp float; * * // x,y coordinates, given from the vertex shader * varying vec2 vTexCoord; * * // the canvas contents, given from filter() * uniform sampler2D tex0; * // other useful information from the canvas * uniform vec2 texelSize; * uniform vec2 canvasSize; * // a custom variable from this sketch * uniform float darkness; * * void main() { * // get the color at current pixel * vec4 color = texture2D(tex0, vTexCoord); * // set the output color * color.b = 1.0; * color *= darkness; * gl_FragColor = vec4(color.rgb, 1.0); * }`; * * createCanvas(100, 100, WEBGL); * s = createFilterShader(fragSrc); * } * * function draw() { * image(img, -50, -50); * s.setUniform('darkness', 0.5); * filter(s); * describe('a image of bricks tinted dark blue'); * } * </code> * </div> */ function createFilterShader(fragSrc: string): p5.Shader; /** * Sets the p5.Shader object to apply while drawing.Shaders are programs that run on the graphics processing unit (GPU). They * can process many pixels or vertices at the same time, making them fast for * many graphics tasks. They’re written in a language called * GLSL * and run along with the rest of the code in a sketch. * p5.Shader objects can be created using the * createShader() and * loadShader() functions.The parameter, `s`, is the p5.Shader object to * apply. For example, calling `shader(myShader)` applies `myShader` to * process each pixel on the canvas. This only changes the fill (the inner part of shapes), * but does not affect the outlines (strokes) or any images drawn using the `image()` function. * The source code from a p5.Shader object's * fragment and vertex shaders will be compiled the first time it's passed to * `shader()`. See * MDN * for more information about compiling shaders.Calling resetShader() restores a sketch’s * default shaders.Note: Shaders can only be used in WebGL mode.If you want to apply shaders to strokes or images, use the following methods: * * @param <a href="#/p5.Shader">p5.Shader</a> object * to apply. * @example <div modernizr='webgl'> * <code> * let fillShader; * * let vertSrc = ` * precision highp float; * attribute vec3 aPosition; * uniform mat4 uModelViewMatrix; * uniform mat4 uProjectionMatrix; * varying vec3 vPosition; * * void main() { * vPosition = aPosition; * gl_Position = uProjectionMatrix * uModelViewMatrix * vec4(aPosition, 1.0); * } * `; * * let fragSrc = ` * precision highp float; * uniform vec3 uLightDir; * varying vec3 vPosition; * * void main() { * vec3 lightDir = normalize(uLightDir); * float brightness = dot(lightDir, normalize(vPosition)); * brightness = clamp(brightness, 0.4, 1.0); * vec3 color = vec3(0.3, 0.5, 1.0); * color = color * brightness * 3.0; * gl_FragColor = vec4(color, 1.0); * } * `; * * function setup() { * createCanvas(200, 200, WEBGL); * fillShader = createShader(vertSrc, fragSrc); * noStroke(); * describe('A rotating torus with simulated directional lighting.'); * } * * function draw() { * background(20, 20, 40); * let lightDir = [0.5, 0.5, -1.0]; * fillShader.setUniform('uLightDir', lightDir); * shader(fillShader); * rotateY(frameCount * 0.02); * rotateX(frameCount * 0.02); * //lights(); * torus(25, 10, 30, 30); * } * </code> * </div> * @example <div modernizr='webgl'> * <code> * let fillShader; * * let vertSrc = ` * precision highp float; * attribute vec3 aPosition; * uniform mat4 uProjectionMatrix; * uniform mat4 uModelViewMatrix; * varying vec3 vPosition; * void main() { * vPosition = aPosition; * gl_Position = uProjectionMatrix * uModelViewMatrix * vec4(aPosition, 1.0); * } * `; * * let fragSrc = ` * precision highp float; * uniform vec3 uLightPos; * uniform vec3 uFillColor; * varying vec3 vPosition; * void main() { * float brightness = dot(normalize(uLightPos), normalize(vPosition)); * brightness = clamp(brightness, 0.0, 1.0); * vec3 color = uFillColor * brightness; * gl_FragColor = vec4(color, 1.0); * } * `; * * function setup() { * createCanvas(200, 200, WEBGL); * fillShader = createShader(vertSrc, fragSrc); * shader(fillShader); * noStroke(); * describe('A square affected by both fill color and lighting, with lights controlled by mouse.'); * } * * function draw() { * let lightPos = [(mouseX - width / 2) / width, * (mouseY - height / 2) / height, 1.0]; * fillShader.setUniform('uLightPos', lightPos); * let fillColor = [map(mouseX, 0, width, 0, 1), * map(mouseY, 0, height, 0, 1), 0.5]; * fillShader.setUniform('uFillColor', fillColor); * plane(100, 100); * } * </code> * </div> * @example <div modernizr='webgl'> * <code> * let myShader; * * function setup() { * createCanvas(200, 200, WEBGL); * * myShader = baseMaterialShader().modify({ * declarations: 'uniform float time;', * 'vec4 getFinalColor': `(vec4 color) { * float r = 0.2 + 0.5 * abs(sin(time + 0.0)); * float g = 0.2 + 0.5 * abs(sin(time + 1.0)); * float b = 0.2 + 0.5 * abs(sin(time + 2.0)); * color.rgb = vec3(r, g, b); * return color; * }` * }); * * noStroke(); * describe('A 3D cube with dynamically changing colors on a beige background.'); * } * * function draw() { * background(245, 245, 220); * shader(myShader); * myShader.setUniform('time', millis() / 1000.0); * * box(50); * } * </code> * </div> */ function shader(s: p5.Shader): void; /** * Sets the p5.Shader object to apply for strokes.This method applies the given shader to strokes, allowing customization of * how lines and outlines are drawn in 3D space. The shader will be used for * strokes until resetShader() is called or another * strokeShader is applied.The shader will be used for:To further customize its behavior, refer to the various hooks provided by * the baseStrokeShader() method, which allow * control over stroke weight, vertex positions, colors, and more. * * @param <a href="#/p5.Shader">p5.Shader</a> object * to apply for strokes. * @example <div modernizr='webgl'> * <code> * let animatedStrokeShader; * * let vertSrc = ` * precision mediump int; * * uniform mat4 uModelViewMatrix; * uniform mat4 uProjectionMatrix; * uniform float uStrokeWeight; * * uniform bool uUseLineColor; * uniform vec4 uMaterialColor; * * uniform vec4 uViewport; * uniform int uPerspective; * uniform int uStrokeJoin; * * attribute vec4 aPosition; * attribute vec3 aTangentIn; * attribute vec3 aTangentOut; * attribute float aSide; * attribute vec4 aVertexColor; * * void main() { * vec4 posp = uModelViewMatrix * aPosition; * vec4 posqIn = uModelViewMatrix * (aPosition + vec4(aTangentIn, 0)); * vec4 posqOut = uModelViewMatrix * (aPosition + vec4(aTangentOut, 0)); * * float facingCamera = pow( * abs(normalize(posqIn-posp).z), * 0.25 * ); * * float scale = mix(1., 0.995, facingCamera); * * posp.xyz = posp.xyz * scale; * posqIn.xyz = posqIn.xyz * scale; * posqOut.xyz = posqOut.xyz * scale; * * vec4 p = uProjectionMatrix * posp; * vec4 qIn = uProjectionMatrix * posqIn; * vec4 qOut = uProjectionMatrix * posqOut; * * vec2 tangentIn = normalize((qIn.xy*p.w - p.xy*qIn.w) * uViewport.zw); * vec2 tangentOut = normalize((qOut.xy*p.w - p.xy*qOut.w) * uViewport.zw); * * vec2 curPerspScale; * if(uPerspective == 1) { * curPerspScale = (uProjectionMatrix * vec4(1, sign(uProjectionMatrix[1][1]), 0, 0)).xy; * } else { * curPerspScale = p.w / (0.5 * uViewport.zw); * } * * vec2 offset; * vec2 tangent = aTangentIn == vec3(0.) ? tangentOut : tangentIn; * vec2 normal = vec2(-tangent.y, tangent.x); * float normalOffset = sign(aSide); * float tangentOffset = abs(aSide) - 1.; * offset = (normal * normalOffset + tangent * tangentOffset) * * uStrokeWeight * 0.5; * * gl_Position.xy = p.xy + offset.xy * curPerspScale; * gl_Position.zw = p.zw; * } * `; * * let fragSrc = ` * precision mediump float; * uniform float uTime; * * void main() { * float wave = sin(gl_FragCoord.x * 0.1 + uTime) * 0.5 + 0.5; * gl_FragColor = vec4(wave, 0.5, 1.0, 1.0); // Animated color based on time * } * `; * * function setup() { * createCanvas(200, 200, WEBGL); * animatedStrokeShader = createShader(vertSrc, fragSrc); * strokeShader(animatedStrokeShader); * strokeWeight(4); * * describe('A hollow cube rotating continuously with its stroke colors changing dynamically over time against a static gray background.'); * } * * function draw() { * animatedStrokeShader.setUniform('uTime', millis() / 1000.0); * background(250); * rotateY(frameCount * 0.02); * noFill(); * orbitControl(); * box(50); * } * </code> * </div> * @example <div modernizr='webgl'> * <code> * let myShader; * * function setup() { * createCanvas(200, 200, WEBGL); * myShader = baseStrokeShader().modify({ * 'float random': `(vec2 p) { * vec3 p3 = fract(vec3(p.xyx) * .1471); * p3 += dot(p3, p3.yzx + 32.33); * return fract((p3.x + p3.y) * p3.z); * }`, * 'Inputs getPixelInputs': `(Inputs inputs) { * // Modify alpha with dithering effect * float a = inputs.color.a; * inputs.color.a = 1.0; * inputs.color *= random(inputs.position.xy) > a ? 0.0 : 1.0; * return inputs; * }` * }); * } * * function draw() { * background(255); * strokeShader(myShader); * strokeWeight(12); * beginShape(); * for (let i = 0; i <= 50; i++) { * stroke( * map(i, 0, 50, 150, 255), * 100 + 155 * sin(i / 5), * 255 * map(i, 0, 50, 1, 0) * ); * vertex( * map(i, 0, 50, 1, -1) * width / 3, * 50 * cos(i / 10 + frameCount / 80) * ); * } * endShape(); * } * </code> * </div> */ function strokeShader(s: p5.Shader): void; /** * Sets the p5.Shader object to apply for images.This method allows the user to apply a custom shader to images, enabling * advanced visual effects such as pixel manipulation, color adjustments, * or dynamic behavior. The shader will be applied to the image drawn using * the image() function.The shader will be used exclusively for: * * @param <a href="#/p5.Shader">p5.Shader</a> object * to apply for images. * @example <div modernizr='webgl'> * <code> * let img; * let imgShader; * * async function setup() { * img = await loadImage('assets/outdoor_image.jpg'); * * createCanvas(200, 200, WEBGL); * noStroke(); * * imgShader = createShader(` * precision mediump float; * attribute vec3 aPosition; * attribute vec2 aTexCoord; * varying vec2 vTexCoord; * uniform mat4 uModelViewMatrix; * uniform mat4 uProjectionMatrix; * * void main() { * vTexCoord = aTexCoord; * gl_Position = uProjectionMatrix * uModelViewMatrix * vec4(aPosition, 1.0); * } * `, ` * precision mediump float; * varying vec2 vTexCoord; * uniform sampler2D uTexture; * uniform vec2 uMousePos; * * void main() { * vec4 texColor = texture2D(uTexture, vTexCoord); * // Adjust the color based on mouse position * float r = uMousePos.x * texColor.r; * float g = uMousePos.y * texColor.g; * gl_FragColor = vec4(r, g, texColor.b, texColor.a); * } * `); * * describe( * 'An image on a gray background where the colors change based on the mouse position.' * ); * } * * function draw() { * background(220); * * imageShader(imgShader); * * // Map the mouse position to a range between 0 and 1 * let mousePosX = map(mouseX, 0, width, 0, 1); * let mousePosY = map(mouseY, 0, height, 0, 1); * * // Pass the mouse position to the shader as a uniform * imgShader.setUniform('uMousePos', [mousePosX, mousePosY]); * * // Bind the image texture to the shader * imgShader.setUniform('uTexture', img); * * image(img, -width / 2, -height / 2, width, height); * } * * </code> * </div> * @example <div modernizr='webgl'> * <code> * let img; * let imgShader; * * async function setup() { * img = await loadImage('assets/outdoor_image.jpg'); * * createCanvas(200, 200, WEBGL); * noStroke(); * * imgShader = createShader(` * precision mediump float; * attribute vec3 aPosition; * attribute vec2 aTexCoord; * varying vec2 vTexCoord; * uniform mat4 uModelViewMatrix; * uniform mat4 uProjectionMatrix; * * void main() { * vTexCoord = aTexCoord; * gl_Position = uProjectionMatrix * uModelViewMatrix * vec4(aPosition, 1.0); * } * `, ` * precision mediump float; * varying vec2 vTexCoord; * uniform sampler2D uTexture; * uniform vec2 uMousePos; * * void main() { * // Distance from the current pixel to the mouse * float distFromMouse = distance(vTexCoord, uMousePos); * * // Adjust pixelation based on distance (closer = more detail, farther = blockier) * float pixelSize = mix(0.002, 0.05, distFromMouse); * vec2 pixelatedCoord = vec2(floor(vTexCoord.x / pixelSize) * pixelSize, * floor(vTexCoord.y / pixelSize) * pixelSize); * * vec4 texColor = texture2D(uTexture, pixelatedCoord); * gl_FragColor = texColor; * } * `); * * describe('A static image with a grid-like, pixelated effect created by the shader. Each cell in the grid alternates visibility, producing a dithered visual effect.'); * } * * function draw() { * background(220); * imageShader(imgShader); * * let mousePosX = map(mouseX, 0, width, 0, 1); * let mousePosY = map(mouseY, 0, height, 0, 1); * * imgShader.setUniform('uMousePos', [mousePosX, mousePosY]); * imgShader.setUniform('uTexture', img); * image(img, -width / 2, -height / 2, width, height); * } * </code> * </div> */ function imageShader(s: p5.Shader): void; /** * Get the default shader used with lights, materials, * and textures.You can call `baseMaterialShader().modify()` * and change any of the following hooks:`void beforeVertex`Called at the start of the vertex shader.`Vertex getObjectInputs`Update the vertex data of the model being drawn before any positioning has been applied. It takes in a `Vertex` struct, which includes:`Vertex getWorldInputs`Update the vertex data of the model being drawn after transformations such as `translate()` and `scale()` have been applied, but before the camera has been applied. It takes in a `Vertex` struct like, in the `getObjectInputs` hook above, that can be modified and returned.`Vertex getCameraInputs`Update the vertex data of the model being drawn as they appear relative to the camera. It takes in a `Vertex` struct like, in the `getObjectInputs` hook above, that can be modified and returned.`void afterVertex`Called at the end of the vertex shader.`void beforeFragment`Called at the start of the fragment shader.`Inputs getPixelInputs`Update the per-pixel inputs of the material. It takes in an `Inputs` struct, which includes:`vec4 combineColors`Take in a `ColorComponents` struct containing all the different components of light, and combining them into * a single final color. The struct contains:`vec4 getFinalColor`Update the final color after mixing. It takes in a `vec4 color` and must return a modified version.`void afterFragment`Called at the end of the fragment shader.Most of the time, you will need to write your hooks in GLSL ES version 300. If you * are using WebGL 1 instead of 2, write your hooks in GLSL ES 100 instead.Call `baseMaterialShader().inspectHooks()` to see all the possible hooks and * their default implementations. * * @returns The material shader * @example <div modernizr='webgl'> * <code> * let myShader; * * function setup() { * createCanvas(200, 200, WEBGL); * myShader = baseMaterialShader().modify(() => { * let time = uniformFloat(() => millis()); * getWorldInputs((inputs) => { * inputs.position.y += * 20 * sin(time * 0.001 + inputs.position.x * 0.05); * return inputs; * }); * }); * } * * function draw() { * background(255); * shader(myShader); * lights(); * noStroke(); * fill('red'); * sphere(50); * } * </code> * </div> * @example <div modernizr='webgl'> * <code> * let myShader; * * function setup() { * createCanvas(200, 200, WEBGL); * myShader = baseMaterialShader().modify({ * declarations: 'vec3 myNormal;', * 'Inputs getPixelInputs': `(Inputs inputs) { * myNormal = inputs.normal; * return inputs; * }`, * 'vec4 getFinalColor': `(vec4 color) { * return mix( * vec4(1.0, 1.0, 1.0, 1.0), * color, * abs(dot(myNormal, vec3(0.0, 0.0, 1.0))) * ); * }` * }); * } * * function draw() { * background(255); * rotateY(millis() * 0.001); * shader(myShader); * lights(); * noStroke(); * fill('red'); * torus(30); * } * </code> * </div> * @example <div modernizr='webgl'> * <code> * let myShader; * let environment; * * async function setup() { * environment = await loadImage('assets/outdoor_spheremap.jpg'); * * createCanvas(200, 200, WEBGL); * myShader = baseMaterialShader().modify(() => { * getPixelInputs((inputs) => { * let factor = sin( * TWO_PI * (inputs.texCoord.x + inputs.texCoord.y) * ); * inputs.shininess = mix(1, 100, factor); * inputs.metalness = factor; * return inputs; * }) * }); * } * * function draw() { * panorama(environment); * ambientLight(100); * imageLight(environment); * rotateY(millis() * 0.001); * shader(myShader); * noStroke(); * fill(255); * specularMaterial(150); * sphere(50); * } * </code> * </div> * @example <div modernizr='webgl'> * <code> * let myShader; * * function setup() { * createCanvas(200, 200, WEBGL); * myShader = baseMaterialShader().modify(() => { * getPixelInputs((inputs) => { * inputs.normal.x += 0.2 * sin( * sin(TWO_PI * dot(inputs.texCoord.yx, vec2(10, 25))) * ); * inputs.normal.y += 0.2 * sin( * sin(TWO_PI * dot(inputs.texCoord, vec2(10, 25))) * ); * inputs.normal = normalize(inputs.normal); * return inputs; * }); * }); * } * * function draw() { * background(255); * shader(myShader); * ambientLight(150); * pointLight( * 255, 255, 255, * 100*cos(frameCount*0.04), -50, 100*sin(frameCount*0.04) * ); * noStroke(); * fill('red'); * shininess(200); * specularMaterial(255); * sphere(50); * } * </code> * </div> */ function baseMaterialShader(): p5.Shader; /** * Get the base shader for filters.You can then call `baseFilterShader().modify()` * and change the following hook:`vec4 getColor`Output the final color for the current pixel. It takes in two parameters: * `FilterInputs inputs`, and `in sampler2D canvasContent`, and must return a color * as a `vec4`.`FilterInputs inputs` is a scruct with the following properties:`in sampler2D canvasContent` is a texture with the contents of the sketch, pre-filter. Call * `getTexture(canvasContent, someCoordinate)` to retrieve the color of the sketch at that coordinate, * with coordinate values between 0 and 1.Most of the time, you will need to write your hooks in GLSL ES version 300. If you * are using WebGL 1, write your hooks in GLSL ES 100 instead. * * @returns The filter shader * @example <div modernizr='webgl'> * <code> * let img; * let myShader; * * async function setup() { * img = await loadImage('assets/bricks.jpg'); * createCanvas(100, 100, WEBGL); * myShader = baseFilterShader().modify(() => { * let time = uniformFloat(() => millis()); * getColor((inputs, canvasContent) => { * inputs.texCoord.y += * 0.02 * sin(time * 0.001 + inputs.texCoord.x * 5); * return texture(canvasContent, inputs.texCoord); * }); * }); * } * * function draw() { * image(img, -50, -50); * filter(myShader); * describe('an image of bricks, distorting over time'); * } * </code> * </div> */ function baseFilterShader(): p5.Shader; /** * Get the shader used by `normalMaterial()`.You can call `baseNormalShader().modify()` * and change any of the following hooks:`void beforeVertex`Called at the start of the vertex shader.`Vertex getObjectInputs`Update the vertex data of the model being drawn before any positioning has been applied. It takes in a `Vertex` struct, which includes:`Vertex getWorldInputs`Update the vertex data of the model being drawn after transformations such as `translate()` and `scale()` have been applied, but before the camera has been applied. It takes in a `Vertex` struct like, in the `getObjectInputs` hook above, that can be modified and returned.`Vertex getCameraInputs`Update the vertex data of the model being drawn as they appear relative to the camera. It takes in a `Vertex` struct like, in the `getObjectInputs` hook above, that can be modified and returned.`void afterVertex`Called at the end of the vertex shader.`void beforeFragment`Called at the start of the fragment shader.`vec4 getFinalColor`Update the final color after mixing. It takes in a `vec4 color` and must return a modified version.`void afterFragment`Called at the end of the fragment shader.Most of the time, you will need to write your hooks in GLSL ES version 300. If you * are using WebGL 1 instead of 2, write your hooks in GLSL ES 100 instead.Call `baseNormalShader().inspectHooks()` to see all the possible hooks and * their default implementations. * * @returns The `normalMaterial` shader * @example <div modernizr='webgl'> * <code> * let myShader; * * function setup() { * createCanvas(200, 200, WEBGL); * myShader = baseNormalShader().modify({ * uniforms: { * 'float time': () => millis() * }, * 'Vertex getWorldInputs': `(Vertex inputs) { * inputs.position.y += * 20. * sin(time * 0.001 + inputs.position.x * 0.05); * return inputs; * }` * }); * } * * function draw() { * background(255); * shader(myShader); * noStroke(); * sphere(50); * } * </code> * </div> * @example <div modernizr='webgl'> * <code> * let myShader; * * function setup() { * createCanvas(200, 200, WEBGL); * myShader = baseNormalShader().modify({ * 'Vertex getCameraInputs': `(Vertex inputs) { * inputs.normal = abs(inputs.normal); * return inputs; * }`, * 'vec4 getFinalColor': `(vec4 color) { * // Map the r, g, and b values of the old normal to new colors * // instead of just red, green, and blue: * vec3 newColor = * color.r * vec3(89.0, 240.0, 232.0) / 255.0 + * color.g * vec3(240.0, 237.0, 89.0) / 255.0 + * color.b * vec3(205.0, 55.0, 222.0) / 255.0; * newColor = newColor / (color.r + color.g + color.b); * return vec4(newColor, 1.0) * color.a; * }` * }); * } * * function draw() { * background(255); * shader(myShader); * noStroke(); * rotateX(frameCount * 0.01); * rotateY(frameCount * 0.015); * box(100); * } * </code> * </div> */ function baseNormalShader(): p5.Shader; /** * Get the shader used when no lights or materials are applied.You can call `baseColorShader().modify()` * and change any of the following hooks:`void beforeVertex`Called at the start of the vertex shader.`Vertex getObjectInputs`Update the vertex data of the model being drawn before any positioning has been applied. It takes in a `Vertex` struct, which includes:`Vertex getWorldInputs`Update the vertex data of the model being drawn after transformations such as `translate()` and `scale()` have been applied, but before the camera has been applied. It takes in a `Vertex` struct like, in the `getObjectInputs` hook above, that can be modified and returned.`Vertex getCameraInputs`Update the vertex data of the model being drawn as they appear relative to the camera. It takes in a `Vertex` struct like, in the `getObjectInputs` hook above, that can be modified and returned.`void afterVertex`Called at the end of the vertex shader.`void beforeFragment`Called at the start of the fragment shader.`vec4 getFinalColor`Update the final color after mixing. It takes in a `vec4 color` and must return a modified version.`void afterFragment`Called at the end of the fragment shader.Most of the time, you will need to write your hooks in GLSL ES version 300. If you * are using WebGL 1 instead of 2, write your hooks in GLSL ES 100 instead.Call `baseColorShader().inspectHooks()` to see all the possible hooks and * their default implementations. * * @returns The color shader * @example <div modernizr='webgl'> * <code> * let myShader; * * function setup() { * createCanvas(200, 200, WEBGL); * myShader = baseColorShader().modify({ * uniforms: { * 'float time': () => millis() * }, * 'Vertex getWorldInputs': `(Vertex inputs) { * inputs.position.y += * 20. * sin(time * 0.001 + inputs.position.x * 0.05); * return inputs; * }` * }); * } * * function draw() { * background(255); * shader(myShader); * noStroke(); * fill('red'); * circle(0, 0, 50); * } * </code> * </div> */ function baseColorShader(): p5.Shader; /** * Get the shader used when drawing the strokes of shapes.You can call `baseStrokeShader().modify()` * and change any of the following hooks:`void beforeVertex`Called at the start of the vertex shader.`StrokeVertex getObjectInputs`Update the vertex data of the stroke being drawn before any positioning has been applied. It takes in a `StrokeVertex` struct, which includes:`StrokeVertex getWorldInputs`Update the vertex data of the model being drawn after transformations such as `translate()` and `scale()` have been applied, but before the camera has been applied. It takes in a `StrokeVertex` struct like, in the `getObjectInputs` hook above, that can be modified and returned.`StrokeVertex getCameraInputs`Update the vertex data of the model being drawn as they appear relative to the camera. It takes in a `StrokeVertex` struct like, in the `getObjectInputs` hook above, that can be modified and returned.`void afterVertex`Called at the end of the vertex shader.`void beforeFragment`Called at the start of the fragment shader.`Inputs getPixelInputs`Update the inputs to the shader. It takes in a struct `Inputs inputs`, which includes:`bool shouldDiscard`Caps and joins are made by discarded pixels in the fragment shader to carve away unwanted areas. Use this to change this logic. It takes in a `bool willDiscard` and must return a modified version.`vec4 getFinalColor`Update the final color after mixing. It takes in a `vec4 color` and must return a modified version.`void afterFragment`Called at the end of the fragment shader.Most of the time, you will need to write your hooks in GLSL ES version 300. If you * are using WebGL 1 instead of 2, write your hooks in GLSL ES 100 instead.Call `baseStrokeShader().inspectHooks()` to see all the possible hooks and * their default implementations. * * @returns The stroke shader * @example <div modernizr='webgl'> * <code> * let myShader; * * function setup() { * createCanvas(200, 200, WEBGL); * myShader = baseStrokeShader().modify({ * 'Inputs getPixelInputs': `(Inputs inputs) { * float opacity = 1.0 - smoothstep( * 0.0, * 15.0, * length(inputs.position - inputs.center) * ); * inputs.color *= opacity; * return inputs; * }` * }); * } * * function draw() { * background(255); * strokeShader(myShader); * strokeWeight(30); * line( * -width/3, * sin(millis()*0.001) * height/4, * width/3, * sin(millis()*0.001 + 1) * height/4 * ); * } * </code> * </div> * @example <div modernizr='webgl'> * <code> * let myShader; * * function setup() { * createCanvas(200, 200, WEBGL); * myShader = baseStrokeShader().modify({ * uniforms: { * 'float time': () => millis() * }, * 'StrokeVertex getWorldInputs': `(StrokeVertex inputs) { * // Add a somewhat random offset to the weight * // that varies based on position and time * float scale = 0.8 + 0.2*sin(10.0 * sin( * floor(time/250.) + * inputs.position.x*0.01 + * inputs.position.y*0.01 * )); * inputs.weight *= scale; * return inputs; * }` * }); * } * * function draw() { * background(255); * strokeShader(myShader); * myShader.setUniform('time', millis()); * strokeWeight(10); * beginShape(); * for (let i = 0; i <= 50; i++) { * let r = map(i, 0, 50, 0, width/3); * let x = r*cos(i*0.2); * let y = r*sin(i*0.2); * vertex(x, y); * } * endShape(); * } * </code> * </div> * @example <div modernizr='webgl'> * <code> * let myShader; * * function setup() { * createCanvas(200, 200, WEBGL); * myShader = baseStrokeShader().modify({ * 'float random': `(vec2 p) { * vec3 p3 = fract(vec3(p.xyx) * .1031); * p3 += dot(p3, p3.yzx + 33.33); * return fract((p3.x + p3.y) * p3.z); * }`, * 'Inputs getPixelInputs': `(Inputs inputs) { * // Replace alpha in the color with dithering by * // randomly setting pixel colors to 0 based on opacity * float a = inputs.color.a; * inputs.color.a = 1.0; * inputs.color *= random(inputs.position.xy) > a ? 0.0 : 1.0; * return inputs; * }` * }); * } * * function draw() { * background(255); * strokeShader(myShader); * strokeWeight(10); * beginShape(); * for (let i = 0; i <= 50; i++) { * stroke( * 0, * 255 * * map(i, 0, 20, 0, 1, true) * * map(i, 30, 50, 1, 0, true) * ); * vertex( * map(i, 0, 50, -1, 1) * width/3, * 50 * sin(i/10 + frameCount/100) * ); * } * endShape(); * } * </code> * </div> */ function baseStrokeShader(): p5.Shader; /** * Restores the default shaders.`resetShader()` deactivates any shaders previously applied by * shader(), strokeShader(), * or imageShader().Note: Shaders can only be used in WebGL mode. * * @example <div> * <code> * // Create a string with the vertex shader program. * // The vertex shader is called for each vertex. * let vertSrc = ` * attribute vec3 aPosition; * attribute vec2 aTexCoord; * uniform mat4 uProjectionMatrix; * uniform mat4 uModelViewMatrix; * varying vec2 vTexCoord; * * void main() { * vTexCoord = aTexCoord; * vec4 position = vec4(aPosition, 1.0); * gl_Position = uProjectionMatrix * uModelViewMatrix * position; * } * `; * * // Create a string with the fragment shader program. * // The fragment shader is called for each pixel. * let fragSrc = ` * precision mediump float; * varying vec2 vTexCoord; * * void main() { * vec2 uv = vTexCoord; * vec3 color = vec3(uv.x, uv.y, min(uv.x + uv.y, 1.0)); * gl_FragColor = vec4(color, 1.0); * } * `; * * let myShader; * * function setup() { * createCanvas(100, 100, WEBGL); * * // Create a p5.Shader object. * myShader = createShader(vertSrc, fragSrc); * * describe( * 'Two rotating cubes on a gray background. The left one has a blue-purple gradient on each face. The right one is red.' * ); * } * * function draw() { * background(200); * * // Draw a box using the p5.Shader. * // shader() sets the active shader to myShader. * shader(myShader); * push(); * translate(-25, 0, 0); * rotateX(frameCount * 0.01); * rotateY(frameCount * 0.01); * box(width / 4); * pop(); * * // Draw a box using the default fill shader. * // resetShader() restores the default fill shader. * resetShader(); * fill(255, 0, 0); * push(); * translate(25, 0, 0); * rotateX(frameCount * 0.01); * rotateY(frameCount * 0.01); * box(width / 4); * pop(); * } * </code> * </div> */ function resetShader(): void; /** * Sets the texture that will be used on shapes.A texture is like a skin that wraps around a shape. `texture()` works with * built-in shapes, such as square() and * sphere(), and custom shapes created with * functions such as buildGeometry(). To * texture a geometry created with beginShape(), * uv coordinates must be passed to each * vertex() call.The parameter, `tex`, is the texture to apply. `texture()` can use a range * of sources including images, videos, and offscreen renderers such as * p5.Graphics and * p5.Framebuffer objects.To texture a geometry created with beginShape(), * you will need to specify uv coordinates in vertex().Note: `texture()` can only be used in WebGL mode. * * @param media to use as the texture. * @example <div> * <code> * let img; * * async function setup() { * // Load an image and create a p5.Image object. * img = await loadImage('assets/laDefense.jpg'); * * createCanvas(100, 100, WEBGL); * * describe('A spinning cube with an image of a ceiling on each face.'); * } * * function draw() { * background(0); * * // Rotate around the x-, y-, and z-axes. * rotateZ(frameCount * 0.01); * rotateX(frameCount * 0.01); * rotateY(frameCount * 0.01); * * // Apply the image as a texture. * texture(img); * * // Draw the box. * box(50); * } * </code> * </div> * * <div> * <code> * let pg; * * function setup() { * createCanvas(100, 100, WEBGL); * * // Create a p5.Graphics object. * pg = createGraphics(100, 100); * * // Draw a circle to the p5.Graphics object. * pg.background(200); * pg.circle(50, 50, 30); * * describe('A spinning cube with circle at the center of each face.'); * } * * function draw() { * background(0); * * // Rotate around the x-, y-, and z-axes. * rotateZ(frameCount * 0.01); * rotateX(frameCount * 0.01); * rotateY(frameCount * 0.01); * * // Apply the p5.Graphics object as a texture. * texture(pg); * * // Draw the box. * box(50); * } * </code> * </div> * * <div> * <code> * let vid; * * function setup() { * // Load a video and create a p5.MediaElement object. * vid = createVideo('assets/fingers.mov'); * * createCanvas(100, 100, WEBGL); * * // Hide the video. * vid.hide(); * * // Set the video to loop. * vid.loop(); * * describe('A rectangle with video as texture'); * } * * function draw() { * background(0); * * // Rotate around the y-axis. * rotateY(frameCount * 0.01); * * // Apply the video as a texture. * texture(vid); * * // Draw the rectangle. * rect(-40, -40, 80, 80); * } * </code> * </div> * * <div> * <code> * let vid; * * function setup() { * // Load a video and create a p5.MediaElement object. * vid = createVideo('assets/fingers.mov'); * * createCanvas(100, 100, WEBGL); * * // Hide the video. * vid.hide(); * * // Set the video to loop. * vid.loop(); * * describe('A rectangle with video as texture'); * } * * function draw() { * background(0); * * // Rotate around the y-axis. * rotateY(frameCount * 0.01); * * // Set the texture mode. * textureMode(NORMAL); * * // Apply the video as a text