ShaderMount is the foundational vanilla JavaScript class in Paper Shaders. It creates a <canvas> element inside a parent <div>, compiles and runs a WebGL2 fragment shader, and keeps the canvas sized to match the container via ResizeObserver.
Every higher-level component — whether a named shader like MeshGradient or the React ShaderMount wrapper — is built on top of this class.
Constructor
The
<div> element to mount the shader into. A <canvas> is prepended into this element and sized to fill it. Must be a valid DOM element — the constructor throws if it is not.The GLSL ES 3.0 fragment shader source. Every built-in shader (e.g.
meshGradientFragmentShader) is a plain string you can pass here.An object of uniform values to pass to the shader. Values can be
boolean, number, number[], number[][], or HTMLImageElement. undefined values are skipped (useful for SSR).Optional attributes forwarded to
canvas.getContext('webgl2', ...). Use this to control things like premultipliedAlpha or preserveDrawingBuffer.Animation speed multiplier applied to delta time each frame.
1 is normal speed, 0 stops animation entirely and cancels the requestAnimationFrame loop (no recurring cost), negative values play in reverse.Starting offset for
u_time in milliseconds. Use this to give the shader a deterministic starting frame — useful for snapshots, SSR, and testing.The minimum pixel ratio to render at. Defaults to
2 so shaders are rendered at 2× even on 1× screens, which improves antialiasing. Reduce for performance, increase (paired with maxPixelCount) for quality.The maximum number of physical pixels to render. Defaults to
1920 × 1080 × 4 (≈ 8.3 million pixels). The canvas can be larger in CSS, but rendering is capped here to prevent GPU overload.Names of texture uniforms that should have mipmaps generated. Mipmaps improve quality when the texture is displayed at a smaller size than its natural resolution.
Automatic canvas sizing
When constructed,ShaderMount prepends a <canvas> into the parent element and attaches a ResizeObserver to it. Whenever the container changes size, the canvas dimensions are updated and u_resolution and u_pixelRatio uniforms are refreshed automatically.
The class also listens to visualViewport resize events to react correctly to pinch zoom and browser zoom changes.
Public methods
setUniforms(newUniforms)
setSpeed(newSpeed)
0 cancels the requestAnimationFrame loop so there is no recurring performance cost.
setFrame(newFrame)
setMaxPixelCount(newMaxPixelCount?)
8,294,400.
setMinPixelRatio(newMinPixelRatio?)
2.
getCurrentFrame()
dispose()
ResizeObserver, removes event listeners, and removes the <canvas> from the DOM. Always call this when you’re done with the shader to avoid memory leaks.
The PaperShaderElement interface
When ShaderMount is constructed, it marks the parent <div> in two ways:
- Sets the
data-paper-shaderattribute (used by the bundled CSS reset to position the canvas). - Attaches the
ShaderMountinstance toparentElement.paperShaderMountfor easy programmatic access.
isPaperShaderElement helper narrows an HTMLElement to PaperShaderElement so TypeScript understands the paperShaderMount property.
Vanilla JS example
React wrapper
The ReactShaderMount from @paper-design/shaders-react wraps the vanilla class in a forwardRef component. It:
- Initialises the vanilla
ShaderMountin auseEffect. - Calls
setUniforms,setSpeed,setFrame,setMaxPixelCount, andsetMinPixelRatiovia effects whenever the corresponding props change. - Accepts string values for image uniforms and automatically fetches and loads them as
HTMLImageElementobjects. - Forwards a
refto the parentPaperShaderElementdiv.
<MeshGradient> rather than <ShaderMount> directly. Named components handle the uniform mapping for you.