WebGL Effects
Apply stunning WebGL shader effects to any element using vfx-js, with support for built-in shaders and custom shaders.
Installation
Usage
import { WebglEffects } from "@/components/pluto-ui/webgl-effects"<WebglEffects shader="glitch" overflow={100}>
<h1>Glitch Effect</h1>
</WebglEffects>Props
| Prop | Type | Default | Description |
|---|---|---|---|
children | ReactNode | - | Content to apply effects to |
shader | string | "glitch" | Shader to apply. Can be a built-in shader name (e.g., "glitch", "rgbShift", "rainbow", "halftone", "duotone", "slitScanTransition", "warpTransition", "pixelateTransition", "focusTransition") or custom shader GLSL code |
overflow | number | boolean | 100 | Overflow amount in pixels for the shader effect |
overlay | boolean | false | Whether to render as an overlay |
uniforms | VFXUniforms | - | Custom uniforms for the shader (object with uniform names as keys and functions/values as values) |
target | string | - | CSS selector for target elements. If not provided, applies to all direct children |
className | string | - | Additional CSS classes |
Examples
Basic Glitch Effect
Apply a simple glitch effect to any element:
<WebglEffects shader="glitch" overflow={100}>
<h1>Glitch Effect</h1>
</WebglEffects>Image Glitch
Apply glitch effects to images:
<WebglEffects shader="glitch" overflow={100} target="img">
<img id="img" src="/image.jpg" alt="Glitched image" />
</WebglEffects>RGB Shift
Apply an RGB color shift effect to images:
<WebglEffects shader="rgbShift" overflow={100} target="img">
<img id="img" src="/image.jpg" alt="RGB Shift" />
</WebglEffects>Rainbow
Apply a rainbow color effect:
<WebglEffects shader="rainbow" overflow={100}>
<div>Your content</div>
</WebglEffects>Halftone
Apply a halftone dot pattern effect:
<WebglEffects shader="halftone" overflow={100} target="img">
<img id="img" src="/image.jpg" alt="Halftone" />
</WebglEffects>Duotone
Apply a duotone effect with custom colors:
<WebglEffects
shader="duotone"
overflow={100}
uniforms={{
color1: [0, 0, 1, 1], // Blue
color2: [0, 1, 0, 1], // Green
speed: 0.2,
}}
>
<div>Your content</div>
</WebglEffects>Slit Scan Transition
Apply a slit scan transition effect:
<WebglEffects shader="slitScanTransition" overflow={100}>
<div>Your content</div>
</WebglEffects>Warp Transition
Apply a warp transition effect:
<WebglEffects shader="warpTransition" overflow={100}>
<div>Your content</div>
</WebglEffects>Pixelate Transition
Apply a pixelate transition effect:
<WebglEffects shader="pixelateTransition" overflow={100}>
<div>Your content</div>
</WebglEffects>Focus Transition
Apply a focus transition effect:
<WebglEffects shader="focusTransition" overflow={100}>
<div>Your content</div>
</WebglEffects>Custom Shaders
You can provide custom GLSL shader code as the shader prop. The shader should be a fragment shader that accepts the following uniforms:
vec2 resolution- The resolution of the effectvec2 offset- The offset positionfloat time- The current timesampler2D src- The source texture
Example custom shader:
const customShader = `
precision highp float;
uniform vec2 resolution;
uniform vec2 offset;
uniform float time;
uniform sampler2D src;
void main() {
vec2 uv = (gl_FragCoord.xy - offset) / resolution;
vec4 color = texture2D(src, uv);
// Your custom shader logic here
gl_FragColor = color;
}
`
<WebglEffects shader={customShader} overflow={100}>
<div>Your content</div>
</WebglEffects>Uniforms
Uniforms allow you to pass dynamic values to your shader. They can be:
- Static values: Numbers or arrays
- Functions: Functions that return values (useful for dynamic values)
uniforms={{
color1: [0, 0, 1, 1], // RGBA array
color2: [0, 1, 0, 1], // RGBA array
speed: 0.2, // number
intensity: () => Math.sin(Date.now() / 1000), // function
}}Features
- ✓ Built-in shader support (glitch, rgbShift, rainbow, halftone, duotone, and more)
- ✓ Custom GLSL shader support
- ✓ Dynamic uniforms with function support
- ✓ Overflow control for better visual effects
- ✓ Overlay rendering mode
- ✓ Target specific elements with CSS selectors
- ✓ Theme-aware (supports both light and dark themes)
- ✓ Fully typed with TypeScript
Notes
- The component uses WebGL through vfx-js, which requires a modern browser with WebGL support
- Custom shaders must be valid GLSL fragment shaders
- Uniforms are evaluated on each frame for functions, so keep them lightweight
- The component automatically cleans up WebGL resources on unmount
- For best performance, limit the number of elements with effects applied simultaneously
Credits
This component is built with vfx-js, a JavaScript library by Amagi that adds WebGL-powered effects to websites. vfx-js makes it easy to attach stunning visual effects to images, videos, and other HTML elements.
Learn more about vfx-js and its capabilities at https://amagi.dev/vfx-js/.