glsh.js Documentation
WebGL shader effects library — v1.5.3.
Zero dependencies. Real-time GPU effects for images and video in any modern browser.
Installation
Include the script directly in your HTML:
<!-- Via CDN / local file --> <script src="glsh.js"></script> <!-- Via npm --> npm install glsh
When loaded via a <script> tag, glsh is available as a global. With a bundler, import it:
import glsh from 'glsh'; // or const glsh = require('glsh');
Overview
glsh.js exposes four functions:
| Function | Purpose |
|---|---|
| glsl() | Run any custom GLSL fragment shader on a canvas |
| effects() | Apply a named built-in shader effect |
| imgsrc() | Load an image and return an HTMLImageElement for use as a texture |
| videosrc() | Load a video and return an HTMLVideoElement for use as a live texture |
All rendering runs in a requestAnimationFrame loop. Both glsl() and effects() return an instance object with stop(), destroy(), and other control methods.
Core API
glsl(target, fragSrc, options?) function
Compiles and runs a custom GLSL fragment shader. The vertex shader and quad geometry are managed internally. The following uniforms are automatically injected into every shader:
| Uniform | Type | Description |
|---|---|---|
| u_time | float | Elapsed time in seconds since rendering started |
| u_resolution | vec2 | Canvas width and height in pixels |
| u_texture | sampler2D | Bound texture (if provided via options.texture) |
Parameters:
| Parameter | Type | Description |
|---|---|---|
| target | string | HTMLCanvasElement | CSS selector string or canvas element. If a selector points to a non-canvas element, a canvas is inserted after it. |
| fragSrc | string | GLSL ES 1.00 fragment shader source code |
| options | object | Optional configuration (see below) |
Options:
| Key | Type | Default | Description |
|---|---|---|---|
| width | number | 512 | Canvas width in pixels |
| height | number | 512 | Canvas height in pixels |
| texture | HTMLImageElement | HTMLVideoElement | HTMLCanvasElement | — | Source bound to u_texture |
| uniforms | object | {} | Additional uniforms: { myFloat: 1.0, myVec2: [0.5, 0.5] } |
| canvas | HTMLCanvasElement | The rendering canvas |
| gl | WebGLRenderingContext | Raw WebGL context |
| program | WebGLProgram | Compiled shader program |
| stop() | void | Cancels the animation frame loop |
| setUniform(name, value) | void | Update a uniform value at runtime |
| destroy() | void | Stops rendering and frees GPU resources |
const frag = ` precision mediump float; uniform float u_time; uniform vec2 u_resolution; varying vec2 v_texCoord; void main() { vec2 uv = v_texCoord; vec3 col = 0.5 + 0.5 * cos(u_time + uv.xyx + vec3(0,2,4)); gl_FragColor = vec4(col, 1.0); } `; const inst = glsh.glsl('#my-canvas', frag, { width: 800, height: 450 }); // Stop after 5 seconds setTimeout(() => inst.stop(), 5000);
effects(target, effectName, options?) function
Applies a named built-in effect. All effects accept a texture (image or video source) plus effect-specific parameters. Transition effects additionally accept texture2.
Parameters:
| Parameter | Type | Description |
|---|---|---|
| target | string | HTMLCanvasElement | CSS selector or canvas element |
| effectName | string | One of the built-in effect names (see below) |
| options | object | Configuration including texture and effect parameters |
Common options (all effects):
| Key | Type | Description |
|---|---|---|
| texture | HTMLImageElement | HTMLVideoElement | HTMLCanvasElement | Primary texture source |
| texture2 | HTMLImageElement | HTMLCanvasElement | Secondary texture (transition effects only) |
| width | number | Canvas width in pixels (default: 512) |
| height | number | Canvas height in pixels (default: 512) |
| canvas | HTMLCanvasElement | The rendering canvas |
| stop() | void | Cancels the animation frame loop |
| setProgress(p) | void | Set transition progress 0–1 (transition effects) |
| updateTexture(src) | void | Swap the primary texture at runtime |
| destroy() | void | Stops rendering and frees GPU resources |
imgsrc(src, callback) function
Loads an image from a URL and returns an HTMLImageElement ready for use as a WebGL texture. Cross-origin images are handled automatically (crossOrigin = 'anonymous').
| Parameter | Type | Description |
|---|---|---|
| src | string | URL of the image to load |
| callback | function(err, img) | Called when load completes. err is null on success, an Error on failure. img is the HTMLImageElement. |
glsh.imgsrc('photo.jpg', function(err, img) { if (err) { console.error(err); return; } glsh.effects('#canvas', 'duotone', { texture: img, colorA: [0.05, 0.0, 0.3], colorB: [1.0, 0.85, 0.1] }); });
videosrc(src, options?, callback) function
Loads a video and returns an HTMLVideoElement for use as a live-updating texture. The video texture is re-uploaded to the GPU each frame.
| Parameter | Type | Description |
|---|---|---|
| src | string | URL of the video |
| options | object | Optional: loop (true), muted (true), autoplay (true) |
| callback | function(err, video) | Called when the video is ready to play |
glsh.videosrc('clip.mp4', { loop: true, muted: true }, function(err, video) { if (err) { console.error(err); return; } glsh.effects('#canvas', 'glitch', { texture: video, intensity: 0.06 }); });
Built-in Effects
All effect names are passed as strings to effects(). The parameters below are set as keys in the options object alongside texture.
customShader
Runs an arbitrary GLSL fragment shader through the effects() pipeline (texture binding, animation loop, etc.).
| Option | Type | Default | Description |
|---|---|---|---|
| shader | string | passthrough | GLSL ES 1.00 fragment shader source |
glsh.effects('#canvas', 'customShader', { texture: img, shader: ` precision mediump float; uniform sampler2D u_texture; uniform float u_time; varying vec2 v_texCoord; void main() { vec2 uv = v_texCoord; uv.x += sin(uv.y * 10.0 + u_time) * 0.05; gl_FragColor = texture2D(u_texture, uv); }` });
hue
Continuously rotates the hue of the image using an RGB rotation matrix. The rotation angle advances with u_time, so the image cycles through all hues automatically.
| Option | Type | Default | Description |
|---|---|---|---|
| angle | number | 0.0 | Base hue offset in radians. Added to the animated time component. |
glsh.effects('#canvas', 'hue', { texture: img, angle: 1.57 });
saturation
Scales the distance of each pixel's color from its luminance (greyscale) equivalent. Static — does not animate.
| Option | Type | Default | Description |
|---|---|---|---|
| amount | number | 1.5 | Saturation multiplier. 0 = greyscale, 1 = original, 2+ = oversaturated. |
glsh.effects('#canvas', 'saturation', { texture: img, amount: 2.0 });
rgbSplit
Samples the red and blue channels from horizontally offset UV coordinates while keeping green centered. Produces a chromatic aberration effect.
| Option | Type | Default | Description |
|---|---|---|---|
| amount | number | 0.01 | Channel offset in UV units (0–0.05 is typical). |
glsh.effects('#canvas', 'rgbSplit', { texture: img, amount: 0.02 });
glitch
Applies randomised scanline horizontal displacement and RGB channel splitting, both keyed to time — producing a VHS/data-corruption aesthetic.
| Option | Type | Default | Description |
|---|---|---|---|
| intensity | number | 0.05 | Controls frequency of glitch events (0–0.5 range). |
glsh.effects('#canvas', 'glitch', { texture: img, intensity: 0.1 });
bloom
Blurs bright regions and adds them on top of the original image, simulating lens flare / light bleed from luminous areas.
| Option | Type | Default | Description |
|---|---|---|---|
| threshold | number | 0.7 | Luminance value above which bloom is applied (0–1). |
| intensity | number | 1.5 | Bloom brightness multiplier. |
glsh.effects('#canvas', 'bloom', { texture: img, threshold: 0.6, intensity: 2.0 });
GaussBlur
9×9 Gaussian kernel blur computed per-pixel. Radius is a multiplier on the per-pixel sample spacing.
| Option | Type | Default | Description |
|---|---|---|---|
| radius | number | 2.0 | Blur spread multiplier. 1 = minimal, 10 = heavy. |
glsh.effects('#canvas', 'GaussBlur', { texture: img, radius: 4.0 });
wave
Displaces UV coordinates along both axes using animated sine functions, creating a fluid warping motion.
| Option | Type | Default | Description |
|---|---|---|---|
| amplitude | number | 0.03 | Maximum UV displacement (0.01–0.1 typical). |
| frequency | number | 10.0 | Spatial frequency of the waves. |
glsh.effects('#canvas', 'wave', { texture: img, amplitude: 0.04, frequency: 8.0 });
rippleDistort
Ripple emanates radially from the image center. Modulates the distance to center with a sine wave, displacing each pixel outward or inward.
| Option | Type | Default | Description |
|---|---|---|---|
| strength | number | 0.05 | Maximum radial displacement amount. |
| speed | number | 3.0 | Wave propagation speed multiplier. |
glsh.effects('#canvas', 'rippleDistort', { texture: img, strength: 0.08, speed: 5.0 });
rippleTransition
Blends between two textures using a radial ripple warp on the transition boundary. Drive setProgress() externally to animate the transition.
| Option | Type | Default | Description |
|---|---|---|---|
| texture | image/canvas | — | From texture (source A) |
| texture2 | image/canvas | — | To texture (source B) |
const inst = glsh.effects('#canvas', 'rippleTransition', { texture: imgA, texture2: imgB }); // Animate progress 0 → 1 over 1 second let t = 0; function tick() { t += 0.01; inst.setProgress(t); if (t < 1.0) requestAnimationFrame(tick); } requestAnimationFrame(tick);
cubeTransition
Simulates a 3D cube flip between two textures using perspective projection shortening. Drive setProgress() from 0 to 1 to complete the transition.
| Option | Type | Default | Description |
|---|---|---|---|
| texture | image/canvas | — | From texture (source A) |
| texture2 | image/canvas | — | To texture (source B) |
const inst = glsh.effects('#canvas', 'cubeTransition', { texture: imgA, texture2: imgB }); inst.setProgress(0.5); // Paused mid-flip
halftone
Replaces the image with a dot-matrix halftone pattern. Each dot's radius is proportional to the local luminance. Black background is rendered for negative space.
| Option | Type | Default | Description |
|---|---|---|---|
| dotSize | number | 6.0 | Grid resolution (cells per axis). Higher = finer, more dots. |
glsh.effects('#canvas', 'halftone', { texture: img, dotSize: 60 });
rainbow
Blends a UV-gradient hue cycle over the image, weighted by the image's luminance channel so highlights receive more rainbow color.
| Option | Type | Default | Description |
|---|---|---|---|
| speed | number | 0.5 | Hue cycle animation speed. |
glsh.effects('#canvas', 'rainbow', { texture: img, speed: 0.3 });
kaleidoScope
Divides the image into segments angular slices from the center and mirrors them symmetrically. The pattern slowly rotates over time.
| Option | Type | Default | Description |
|---|---|---|---|
| segments | number | 8.0 | Number of mirror facets. Typical values: 4, 6, 8, 12. |
glsh.effects('#canvas', 'kaleidoScope', { texture: img, segments: 12 });
swirl
Applies a rotation twist that is strongest at the center and falls off with distance. The twist angle also animates with time.
| Option | Type | Default | Description |
|---|---|---|---|
| angle | number | 3.0 | Maximum twist angle in radians at center. |
| radius | number | 0.5 | Falloff radius in UV units (0–1). Beyond this, no twist is applied. |
glsh.effects('#canvas', 'swirl', { texture: img, angle: 5.0, radius: 0.6 });
shear
Applies animated UV shear displacement: X coordinates are shifted by a function of Y, and Y by X, using animated sine/cosine coefficients. Areas outside the UV [0,1] boundary are rendered black.
| Option | Type | Default | Description |
|---|---|---|---|
| amountX | number | 0.2 | Shear intensity along the X axis. |
| amountY | number | 0.0 | Shear intensity along the Y axis. |
glsh.effects('#canvas', 'shear', { texture: img, amountX: 0.4, amountY: 0.1 });
duotone
Maps pixel luminance to a linear interpolation between two colors. Shadows map to colorA, highlights to colorB. Static — does not animate.
| Option | Type | Default | Description |
|---|---|---|---|
| colorA | [r, g, b] | [0.1, 0.0, 0.5] | Shadow color (RGB, each 0–1) |
| colorB | [r, g, b] | [1.0, 0.8, 0.0] | Highlight color (RGB, each 0–1) |
glsh.effects('#canvas', 'duotone', { texture: img, colorA: [0.05, 0.0, 0.3], colorB: [1.0, 0.85, 0.0] });
tritone
Three-point tone map that divides luminance into shadows (0–0.5) and highlights (0.5–1) and linearly interpolates through three custom colors. Static — does not animate.
| Option | Type | Default | Description |
|---|---|---|---|
| shadow | [r, g, b] | [0.0, 0.0, 0.2] | Color at luminance 0 |
| mid | [r, g, b] | [0.5, 0.0, 0.5] | Color at luminance 0.5 |
| highlight | [r, g, b] | [1.0, 0.9, 0.5] | Color at luminance 1 |
glsh.effects('#canvas', 'tritone', { texture: img, shadow: [0.0, 0.0, 0.15], mid: [0.6, 0.1, 0.4], highlight: [1.0, 1.0, 0.6] });
Browser Compatibility
glsh.js requires WebGL 1.0 support. All modern browsers (Chrome 56+, Firefox 51+, Safari 15+, Edge 79+) and most mobile browsers support WebGL. The library falls back gracefully with an error if WebGL is unavailable.
imgsrc() or passing image elements as textures, the image server must include appropriate CORS headers (Access-Control-Allow-Origin). glsh.js sets crossOrigin = 'anonymous' automatically on elements it creates, but elements created outside the library must have this set manually before the src attribute.
muted: true in videosrc() options for reliable autoplay behavior.