Pluto UIpluto/ui
Components

WebGL Effects

Apply stunning WebGL shader effects to any element using vfx-js, with support for built-in shaders and custom shaders.

Glitch Effect

// Code for webgl-effects/basic

Installation

Loading installation instructions...

Usage

import { WebglEffects } from "@/components/pluto-ui/webgl-effects"
<WebglEffects shader="glitch" overflow={100}>
  <h1>Glitch Effect</h1>
</WebglEffects>

Props

PropTypeDefaultDescription
childrenReactNode-Content to apply effects to
shaderstring"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
overflownumber | boolean100Overflow amount in pixels for the shader effect
overlaybooleanfalseWhether to render as an overlay
uniformsVFXUniforms-Custom uniforms for the shader (object with uniform names as keys and functions/values as values)
targetstring-CSS selector for target elements. If not provided, applies to all direct children
classNamestring-Additional CSS classes

Examples

Basic Glitch Effect

Glitch Effect

// Code for webgl-effects/basic

Apply a simple glitch effect to any element:

<WebglEffects shader="glitch" overflow={100}>
  <h1>Glitch Effect</h1>
</WebglEffects>

Image Glitch

Glitched
// Code for webgl-effects/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

RGB Shift
// Code for webgl-effects/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

Rainbow Effect

// Code for webgl-effects/rainbow

Apply a rainbow color effect:

<WebglEffects shader="rainbow" overflow={100}>
  <div>Your content</div>
</WebglEffects>

Halftone

Halftone
// Code for webgl-effects/halftone

Apply a halftone dot pattern effect:

<WebglEffects shader="halftone" overflow={100} target="img">
  <img id="img" src="/image.jpg" alt="Halftone" />
</WebglEffects>

Duotone

Duotone

// Code for webgl-effects/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

Slit Scan

// Code for webgl-effects/slit-scan

Apply a slit scan transition effect:

<WebglEffects shader="slitScanTransition" overflow={100}>
  <div>Your content</div>
</WebglEffects>

Warp Transition

Warp Transition

// Code for webgl-effects/warp-transition

Apply a warp transition effect:

<WebglEffects shader="warpTransition" overflow={100}>
  <div>Your content</div>
</WebglEffects>

Pixelate Transition

Pixelate

// Code for webgl-effects/pixelate-transition

Apply a pixelate transition effect:

<WebglEffects shader="pixelateTransition" overflow={100}>
  <div>Your content</div>
</WebglEffects>

Focus Transition

Focus

// Code for webgl-effects/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 effect
  • vec2 offset - The offset position
  • float time - The current time
  • sampler2D 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/.