npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

pixi-shader-effect

v0.1.5

Published

Manifest-driven PIXI.js mesh shader player that follows display objects

Readme

pixi-shader-effect

Manifest-driven PIXI.js mesh shader player. Attach animated GLSL effects to display objects, drive uniforms from a JSON manifest, and let the effect follow targets as the scene moves or resizes.

Peer dependency: pixi.js ^7.4.0 (your app must install it).

Install

npm install pixi-shader-effect pixi.js

Quick start

import { ShaderEffect } from 'pixi-shader-effect';
import manifest from './myEffect.json';
import fragShader from './myEffect.frag.js';

const effect = new ShaderEffect({
  manifest,
  fragShader,
  getSize: () => ({ width: app.renderer.width, height: app.renderer.height }),
  getTarget: () => mySprite,
  zIndex: 3,
});

effect.resize(); // attach, build meshes, start ticker

On window resize:

effect.resize();

On teardown:

effect.destroy();

What you provide

This package is the player only. It does not ship shader presets. You pass in:

| You provide | Format | |-------------|--------| | manifest | JSON with a shader layer and shaderSettings | | fragShader | GLSL source string (e.g. export default from a .js file) |

The manifest and fragment shader must match — same effect type and uniforms. For example, a manifest with "shaderLayerDistortionType": "lava-crack" expects a lava-crack GLSL shader that declares uniforms like lavaColor, crackScale, etc.

Manifest keys like shaderLayerGlowColor map to GLSL uniforms (glowColor). Hex colors are converted to vec3 RGB automatically.

Manifest

The manifest is a JSON object with at least one visible shader layer:

{
  "name": "My Effect",
  "layers": [
    {
      "type": "shader",
      "visible": true,
      "shaderSettings": {
        "shaderRectWidth": 200,
        "shaderRectHeight": 100,
        "shaderLayerGlowSpread": 0.02,
        "shaderLayerGlowColor": "#ffad1f",
        "shaderLayerFlowSpeed": 0.5
      }
    }
  ]
}

Lifecycle

Typical integration pattern:

// 1. Create (does not render until resize/start)
const effect = new ShaderEffect({ manifest, fragShader, getSize, getTarget, zIndex: 3 });

// 2. Attach + build meshes + start ticker
effect.resize();

// 3. Call again on window resize or when layout changes
effect.resize();

// 4. Clean up when removing the effect
effect.destroy();

getTarget is always required, even for background or fixed-position layouts — return the display object whose parent should host the effect (or use the parent option to attach elsewhere).

resize() is idempotent: safe to call on init and on every layout pass. Use destroy() before discarding; call stop() only if you want to halt updates but keep the instance.

The effect exposes effect.container (a PIXI Container) if you need direct access to the display object tree.

Settings overrides

Override manifest values at construction or at runtime. Overrides use the same keys as shaderSettings and always win over the manifest.

At construction — pass settings to replace or tweak manifest defaults:

const effect = new ShaderEffect({
  manifest,
  fragShader,
  getSize: () => ({ width: app.renderer.width, height: app.renderer.height }),
  getTarget: () => mySprite,
  settings: {
    shaderLayerGlowColor: '#ff0000',
    shaderLayerFlowSpeed: 1.2,
    shaderLayerGlowSpread: 0.05,
  },
});

At runtime — call setSettings() to merge new values and refresh layout/uniforms:

// dim the glow
effect.setSettings({ shaderLayerGlowIntensity: 0.5 });

// switch palette on a state change
effect.setSettings({
  shaderLayerGlowColor: '#00ccff',
  shaderLayerCoreColor: '#ffffff',
});

Animate with GSAP

GSAP is not a dependency of this package. Tween a plain object and call setSettings() on each update to push manifest values into the shader:

import gsap from 'gsap';
import { ShaderEffect } from 'pixi-shader-effect';

const effect = new ShaderEffect({ manifest, fragShader, getSize, getTarget });
effect.resize();

const tweenState = {
  shaderLayerGlowIntensity: 1.25,
  shaderLayerFlowSpeed: 0.5,
};

gsap.to(tweenState, {
  shaderLayerGlowIntensity: 2,
  shaderLayerFlowSpeed: 1.5,
  duration: 0.8,
  ease: 'power2.out',
  onUpdate: () => effect.setSettings(tweenState),
});

Pulse loop:

gsap.to(tweenState, {
  shaderLayerGlowIntensity: 2,
  duration: 1,
  yoyo: true,
  repeat: -1,
  ease: 'sine.inOut',
  onUpdate: () => effect.setSettings(tweenState),
});

Fade opacityalpha lives on the effect instance (not manifest); the ticker picks it up each frame:

effect.alpha = 0;

gsap.to(effect, {
  alpha: 1,
  duration: 0.6,
  ease: 'power2.out',
});

Speed up / slow down the built-in time uniform the same way via timeScale:

gsap.to(effect, { timeScale: 0, duration: 0.5 }); // freeze
gsap.to(effect, { timeScale: 1, duration: 0.5 }); // resume normal speed

Constructor options

| Option | Required | Default | Description | |--------|----------|---------|-------------| | manifest | yes | — | Shader manifest JSON | | fragShader | yes | — | Fragment shader GLSL source | | getSize | yes | — | () => ({ width, height }) screen size | | getTarget | yes | — | () => displayObject object to follow | | parent | no | target's parent | Fixed container to render into | | getTargetSize | no | target bounds | () => ({ width, height }) override | | settings | no | {} | Runtime overrides (win over manifest) | | shaderScale | no | 1 | Geometry size multiplier | | pixiScale | no | 1 | Mesh transform scale | | anchor | no | { x: 0.5, y: 0.5 } | Follow point on target (0–1) | | outlineAlign | no | 1 | Outline stroke: 0 outside, 0.5 center, 1 inside | | strokeAlign | no | — | Alias for outlineAlign | | alpha | no | 1 | Opacity multiplier | | time | no | 1 | Animation speed (1 = real time) | | blendMode | no | add | normal, add, multiply, screen, or PIXI constant | | zIndex | no | 1 | Draw order in parent | | fps | no | 0 | Update cap (0 = every frame) | | name | no | 'ShaderEffect' | Debug name on container |

Methods

  • resize() — Re-attach if needed, refresh layout and geometry.
  • start() — Start ticker updates (also called via resize() when not running).
  • setSettings(settings) — Merge runtime settings and refresh layout.
  • stop() — Stop ticker and destroy meshes.
  • destroy() — Full cleanup (call when removing the effect).

Layout modes

  • Follow target — Default when getTarget() returns a sized display object.
  • Background — Set shaderSourceType: "background" in manifest settings for full-screen.
  • Fixed position — Use shaderRectWidth / shaderRectHeight and optional emitterX / emitterY (percent) when no target layout applies.
  • Rect outline — Set shaderRectMode: "outline" and shaderRectAsLines: true for four-edge stroke rendering.

Advanced exports

Lower-level uniform helpers are also exported:

import {
  ShaderEffect,
  syncUniforms,
  resolveSettings,
  parseFragUniforms,
  hexToRgb,
} from 'pixi-shader-effect';

License

MIT