📕 canvas-sketch-util → Documentation → shader
A utility to quickly bootstrap a full-screen GLSL quad shader, similar to ShaderToy but with only minimal features.
This uses REGL under the hood.
💡 This utility is best used alongside canvas-sketch and its CLI, although it should also work in other environments.
A typical example with canvas-sketch will look like this:
const canvasSketch = require('canvas-sketch');
const createShader = require('canvas-sketch-util/shader');
// Setup our sketch
const settings = {
dimensions: [ 512, 512 ],
context: 'webgl',
animate: true
};
// Your glsl code
const frag = `
precision highp float;
uniform float time;
varying vec2 vUv;
void main () {
float anim = sin(time) * 0.5 + 0.5;
gl_FragColor = vec4(vec3(vUv.x * anim), 1.0);
}
`;
// Your sketch, which simply returns the shader
const sketch = ({ gl }) => {
// Create the shader and return it. It will be rendered by regl.
return createShader({
// Pass along WebGL context
gl,
// Specify fragment and/or vertex shader strings
frag,
// Specify additional uniforms to pass down to the shaders
uniforms: {
// Expose props from canvas-sketch
time: ({ time }) => time
}
});
};
canvasSketch(sketch, settings);
Also see Advanced Example.
Creates a full-screen GLSL shader renderer with opt
settings (rendered by regl). The following options can be used:
gl
(required) the WebGL context to render tofrag
the fragment shader string, or a function that returns a stringvert
the vertex shader string, or a function that returns a stringclearColor
a color string or[ r, g, b ]
array (in 0..1 floats) of the clear color-
if
false
then no clear will be applied before rendering -
defaults to black, i.e.
[ 0, 0, 0 ]
-
clearAlpha
a number for the clear color alpha (if clearing), defaults to1.0
uniforms
a map of named uniforms-
You can specify a constant value like
{ alpha: 0.5 }
(float) or{ position: [ 0, 0.5 ] }
(vec2) -
If you want to use a
sampler2D
, you should pass an image-like object, such as a<image>
tag, ndarray, regl texture object descriptor, or Canvas. -
Or, you can specify a function to derive a value from the current
props
, such as({ time }) => time
-
extensions
a list of WebGL extensions to enable for this shaderoptionalExtensions
a list of optional WebGL extensions to attempt to enable for this shaderblend
(default true) enable blending with background, set tofalse
to disable entirelyscissor
if true, scissor testing will be enabled and the propsscissorX, scissorY, scissorWidth, scissorHeight
will be expected to be passed through to the render function
The default frag
and vert
will use a simple black shader, which passes along the UV coordinates as varying vec2 vUv
.
The returned render(props)
function can be used to draw the shader to the context, or unload()
can be used to destroy the shader.
The resulting shader has a render()
function which will poll the GL state, clear the backbuffer (if needed), draw a full-screen quad, and then flush the GL state.
Destroys the shader and any GL memory associated with it.
This is a low-level function that will draw the full-screen quad. This does not do any GL polling/flushing or buffer clearing. This can be used, for example, to implement tiled rendering when scissor
is enabled, by passing { scissorX, scissorY, scissorWidth, scissorHeight }
props.
Returns the underlying regl
instance that was created for use with this shader.
The default values when no frag
and/or vert
strings are passed.
precision highp float;
attribute vec3 position;
varying vec2 vUv;
void main () {
gl_Position = vec4(position.xyz, 1.0);
vUv = gl_Position.xy * 0.5 + 0.5;
}
precision highp float;
void main () {
gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);
}
Another example without directly returning the shader result, and also showing image loading.
const canvasSketch = require('canvas-sketch');
const createShader = require('canvas-sketch-util/shader');
const loadAsset = require('load-asset');
// Require a GLSL file for nicer editor syntax highlighting
const frag = require('./mouse.glsl');
// Setup our sketch
const settings = {
context: 'webgl',
animate: true
};
const sketch = async ({ gl }) => {
const image = await loadAsset('image.png');
const mouse = [ 0, 0 ];
// Create a mouse listener
const move = ev => {
mouse[0] = ev.clientX / window.innerWidth;
mouse[1] = (window.innerHeight - ev.clientY - 1) / window.innerHeight;
};
window.addEventListener('mousemove', move);
// Create the shader and return it
const shader = createShader({
// Pass along WebGL context
gl,
// Specify fragment and/or vertex shader strings
frag,
// Specify additional uniforms to pass down to the shaders
uniforms: {
// Pass down a sampler2D image
map: image,
// Expose props from canvas-sketch
time: ({ time }) => time,
// Expose additional mouse uniform
// Use an array here to ensure it picks up the new values each render
mouse: () => mouse
}
});
return {
render (props) {
// Render shader
shader.render(props);
},
unload () {
// Cleanup shader and mouse event
shader.unload();
window.removeEventListener('mousemove', move);
}
}
};
canvasSketch(sketch, settings);