p5
Version:
[](https://www.npmjs.com/package/p5)
1,615 lines (1,600 loc) • 79.1 kB
TypeScript
// 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