Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/paper-design/shaders/llms.txt

Use this file to discover all available pages before exploring further.

This guide will help you create your first animated shader. We’ll build a beautiful mesh gradient background in both React and vanilla JavaScript.

React Quick Start

1

Install the package

If you haven’t already, install the React package:
npm install @paper-design/shaders-react
2

Import and use a shader component

Import any shader component and add it to your React component:
App.jsx
import { MeshGradient } from '@paper-design/shaders-react';

function App() {
  return (
    <div style={{ position: 'relative', width: '100vw', height: '100vh' }}>
      <MeshGradient
        colors={['#5100ff', '#00ff80', '#ffcc00', '#ea00ff']}
        distortion={1}
        swirl={0.8}
        speed={0.2}
        style={{ width: '100%', height: '100%' }}
      />
    </div>
  );
}

export default App;
3

Customize your shader

Adjust the parameters to customize the appearance:
<MeshGradient
  colors={['#e0eaff', '#241d9a', '#f75092', '#9f50d3']}
  distortion={0.5}  // Lower distortion for smoother shapes
  swirl={0.1}       // Reduce swirl effect
  speed={1}         // Faster animation
  grainMixer={0.2}  // Add grain texture
  style={{ width: '100%', height: '100%' }}
/>
The shader automatically creates a <canvas> element that matches the dimensions of its parent container.

Vanilla JavaScript Quick Start

1

Install the package

Install the vanilla JavaScript package:
npm install @paper-design/shaders
2

Create a container element

Add a container element in your HTML:
index.html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Paper Shaders Demo</title>
  <style>
    body {
      margin: 0;
      padding: 0;
    }
    #shader-container {
      position: relative;
      width: 100vw;
      height: 100vh;
    }
  </style>
</head>
<body>
  <div id="shader-container"></div>
  <script type="module" src="./main.js"></script>
</body>
</html>
3

Initialize the shader

Create a shader using the ShaderMount class:
main.js
import {
  ShaderMount,
  meshGradientFragmentShader,
  getShaderColorFromString,
  ShaderFitOptions,
  defaultObjectSizing
} from '@paper-design/shaders';

// Get the container element
const container = document.getElementById('shader-container');

// Define your shader uniforms
const uniforms = {
  // Color configuration
  u_colors: [
    '#5100ff',
    '#00ff80',
    '#ffcc00',
    '#ea00ff'
  ].map(getShaderColorFromString),
  u_colorsCount: 4,
  
  // Visual parameters
  u_distortion: 1,
  u_swirl: 0.8,
  u_grainMixer: 0,
  u_grainOverlay: 0,
  
  // Sizing parameters
  u_fit: ShaderFitOptions[defaultObjectSizing.fit],
  u_rotation: 0,
  u_scale: 1,
  u_offsetX: 0,
  u_offsetY: 0,
  u_originX: 0.5,
  u_originY: 0.5,
  u_worldWidth: 1000,
  u_worldHeight: 1000,
};

// Create the shader mount
const shader = new ShaderMount(
  container,
  meshGradientFragmentShader,
  uniforms,
  {}, // WebGL context attributes
  0.2, // speed
  0    // starting frame
);

// Clean up when done (e.g., on page navigation)
// shader.dispose();
4

Update shader parameters (optional)

You can dynamically update shader parameters:
// Update colors
shader.setUniforms({
  u_colors: [
    '#e0eaff',
    '#241d9a',
    '#f75092',
    '#9f50d3'
  ].map(getShaderColorFromString),
  u_distortion: 0.5,
});

// Change animation speed
shader.setSpeed(1);

// Pause animation
shader.setSpeed(0);

Try Other Shaders

Paper Shaders includes many different effects. Here are some popular ones:
import { DotOrbit } from '@paper-design/shaders-react';

<DotOrbit
  colors={['#d2822d', '#0c3b7e', '#b31a57', '#37a066']}
  colorBack={'#000000'}
  scale={0.3}
  speed={0.5}
  style={{ width: '100%', height: '100%' }}
/>

Common Patterns

Full-Page Background

import { MeshGradient } from '@paper-design/shaders-react';

function Layout({ children }) {
  return (
    <div style={{ position: 'relative', minHeight: '100vh' }}>
      {/* Background shader */}
      <MeshGradient
        colors={['#5100ff', '#00ff80', '#ffcc00', '#ea00ff']}
        distortion={1}
        swirl={0.8}
        speed={0.2}
        style={{
          position: 'fixed',
          top: 0,
          left: 0,
          width: '100%',
          height: '100%',
          zIndex: -1,
        }}
      />
      
      {/* Content on top */}
      <div style={{ position: 'relative', zIndex: 1 }}>
        {children}
      </div>
    </div>
  );
}

Static Shader (No Animation)

For better performance, set speed={0} to disable animation:
<MeshGradient
  colors={['#5100ff', '#00ff80', '#ffcc00', '#ea00ff']}
  distortion={1}
  swirl={0.8}
  speed={0}  // No animation, zero performance cost
  frame={42} // Frozen at a specific frame
  style={{ width: '100%', height: '100%' }}
/>

Card Background

function Card({ children }) {
  return (
    <div style={{
      position: 'relative',
      width: 300,
      height: 200,
      borderRadius: 16,
      overflow: 'hidden',
      boxShadow: '0 4px 6px rgba(0, 0, 0, 0.1)',
    }}>
      <MeshGradient
        colors={['#667eea', '#764ba2']}
        distortion={0.5}
        swirl={0.2}
        speed={0.1}
        style={{ width: '100%', height: '100%' }}
      />
      <div style={{
        position: 'absolute',
        inset: 0,
        padding: 24,
        color: 'white',
      }}>
        {children}
      </div>
    </div>
  );
}

Masked with Text

function HeroText() {
  return (
    <div style={{ position: 'relative', display: 'inline-block' }}>
      <h1 style={{
        fontSize: 120,
        fontWeight: 900,
        margin: 0,
        background: 'linear-gradient(to bottom, #000, #000)',
        backgroundClip: 'text',
        WebkitBackgroundClip: 'text',
        color: 'transparent',
        position: 'relative',
        zIndex: 2,
        mixBlendMode: 'multiply',
      }}>
        HELLO
      </h1>
      <MeshGradient
        colors={['#5100ff', '#00ff80', '#ffcc00', '#ea00ff']}
        distortion={1}
        swirl={0.8}
        speed={0.3}
        style={{
          position: 'absolute',
          top: 0,
          left: 0,
          width: '100%',
          height: '100%',
          zIndex: 1,
        }}
      />
    </div>
  );
}

Performance Tips

Set speed={0} for static shaders to completely eliminate animation overhead and achieve zero ongoing performance cost.
The shader automatically limits resolution based on device capabilities. You can adjust minPixelRatio and maxPixelCount props for fine-tuning.
Shaders pause automatically when the browser tab is hidden to save resources.

Next Steps

React Guide

Learn about all React shader components and their props

Vanilla JS Guide

Deep dive into the ShaderMount API for vanilla JavaScript

Shader Gallery

Explore all available shaders with live examples

API Reference

Complete API documentation and type definitions

Common Issues

Make sure the parent container has a defined width and height. The shader canvas matches its parent’s dimensions.
{/* ❌ Parent has no height */}
<div>
  <MeshGradient colors={['#ff0000', '#0000ff']} />
</div>

{/* ✅ Parent has explicit height */}
<div style={{ width: 400, height: 300 }}>
  <MeshGradient colors={['#ff0000', '#0000ff']} />
</div>
Paper Shaders requires WebGL2 support. Ensure you’re testing in a modern browser:
  • Chrome 56+
  • Firefox 51+
  • Safari 15+
  • Edge 79+
Try these optimizations:
  1. Set speed={0} if animation isn’t needed
  2. Reduce the shader size using CSS
  3. Lower the minPixelRatio prop (default is 2)
  4. Set a lower maxPixelCount to cap resolution
<MeshGradient
  colors={['#ff0000', '#0000ff']}
  minPixelRatio={1}  // Lower quality but better performance
  maxPixelCount={1920 * 1080}  // Cap at 1080p
/>
Colors should be provided as CSS color strings. Valid formats:
  • Hex: '#ff0000' or '#f00'
  • RGB: 'rgb(255, 0, 0)'
  • RGBA: 'rgba(255, 0, 0, 0.5)'
  • Named: 'red'
{/* ✅ Valid */}
<MeshGradient colors={['#ff0000', 'rgba(0, 255, 0, 0.8)', 'blue']} />

{/* ❌ Invalid */}
<MeshGradient colors={[0xff0000, [255, 0, 0]]} />