PluginBench
Skill
Pass
Audit score 90

pixijs-filters

pixijs/pixijs-skills

Apply visual effects to PixiJS v8 containers using built-in and custom filters with GLSL/WGSL shaders.

What is pixijs-filters?

Attach filters to PixiJS containers to apply visual effects like blur, color adjustment, displacement, and noise. Use built-in filters (BlurFilter, ColorMatrixFilter, etc.) for common effects, or create custom filters with Filter.from() using GLSL/WGSL fragment shaders. Configure resolution, padding, and filterArea for performance optimization.

  • Apply built-in filters: AlphaFilter, BlurFilter, ColorMatrixFilter, DisplacementFilter, NoiseFilter
  • Create custom filters with Filter.from() using GLSL/WGSL fragment shaders
  • Chain multiple filters on containers and sprites via the filters array
  • Configure filter options: resolution, padding, antialias, blendMode, and blendRequired
  • Optimize performance with filterArea bounds and resolution tuning
  • Access and animate uniform values in real-time via filter.resources

How to install pixijs-filters

npx skills add https://github.com/pixijs/pixijs-skills --skill pixijs-filters
Prerequisites
  • PixiJS v8 installed
  • Basic understanding of GLSL or WGSL for custom filters (optional for built-in filters)
  • For community filters: pixi-filters package installed
Claude Code
Cursor
Windsurf
Cline

How to use pixijs-filters

  1. 1.Import the filter class (built-in or from pixi-filters)
  2. 2.Create a filter instance with desired options (e.g., BlurFilter({ strength: 4 }))
  3. 3.Assign the filter to a container or sprite via container.filters = [filter] or container.filters = filter
  4. 4.For custom filters, use Filter.from() with a fragment shader and define uniforms in resources
  5. 5.Update uniform values each frame via filter.resources.{groupName}.uniforms.{name} if needed
  6. 6.Set filterArea on containers to optimize bounds measurement and performance

Use cases

Good for
  • Add blur and color adjustments to game sprites or UI elements
  • Create animated effects by updating shader uniforms each frame
  • Apply displacement maps for water ripples or distortion effects
  • Combine multiple filters for complex visual effects like glow with color grading
  • Use community pixi-filters package for advanced effects like AdjustmentFilter and GlowFilter
Who it's for
  • PixiJS game developers
  • Interactive graphics and animation developers
  • Web-based visual effects engineers
  • Developers building custom shaders for real-time rendering

pixijs-filters FAQ

What is the difference between Filter.from() and the Filter constructor?

Filter.from() is the recommended v8 approach for simple custom filters—it requires only a fragment shader and automatically provides a default vertex shader. The Filter constructor with options object is for advanced cases where you need full control via GlProgram/GpuProgram objects. The old v7 syntax (Filter(vertex, fragment, uniforms)) is no longer supported in v8.

How do I animate a filter effect?

Update uniform values in the app ticker. Access uniforms via filter.resources.{groupName}.uniforms.{name} and modify the value property each frame. For example: filter.resources.timeUniforms.uniforms.uTime += 0.04 * ticker.deltaTime.

What is filterArea and when should I use it?

filterArea is a Rectangle that defines the bounds of the filter effect, avoiding per-frame measurement. Set it when you know the filter's bounds in advance to improve performance. Example: container.filterArea = new Rectangle(0, 0, 800, 600).

Can I use @pixi/filter-* packages with PixiJS v8?

No. v8 uses the restructured pixi-filters package with imports like pixi-filters/adjustment. The old @pixi/filter-* packages are v7 only.

What does blendRequired do?

Set blendRequired: true when your custom filter shader samples uBackTexture (the previous render target). This enables the filter system to maintain a back buffer for blending operations, which is required for advanced blend modes.

Full instructions (SKILL.md)

Source of truth, from pixijs/pixijs-skills.


name: pixijs-filters description: "Use this skill when applying visual effects to PixiJS v8 containers via the filter pipeline. Covers built-in filters (AlphaFilter, BlurFilter, ColorMatrixFilter, DisplacementFilter, NoiseFilter), custom Filter.from() with GLSL/WGSL, options (resolution, padding, antialias, blendRequired), filterArea optimization, pixi-filters community package. Triggers on: filters, BlurFilter, ColorMatrixFilter, DisplacementFilter, NoiseFilter, Filter.from, GLSL filter, pixi-filters, filterArea." license: MIT

Attach visual effects by assigning one filter (or an array for chaining) to container.filters. Built-in filters cover blur, color matrix, displacement, alpha, and noise; custom filters wrap a GLSL/WGSL fragment shader via Filter.from(...).

Quick Start

const sprite = new Sprite(await Assets.load("hero.png"));
app.stage.addChild(sprite);

const blur = new BlurFilter({ strength: 4, quality: 4 });
const colorMatrix = new ColorMatrixFilter();
colorMatrix.brightness(1.2, false);

sprite.filters = [blur, colorMatrix];

const container = new Container();
container.filters = [new BlurFilter({ strength: 2 })];
container.filterArea = new Rectangle(0, 0, 800, 600);
app.stage.addChild(container);

Related skills: pixijs-custom-rendering (shader internals, uniform types), pixijs-blend-modes (composing with filters), pixijs-performance (filter tuning, filterArea).

Core Patterns

Built-in filters

import {
  AlphaFilter,
  BlurFilter,
  ColorMatrixFilter,
  DisplacementFilter,
  NoiseFilter,
  Assets,
  Sprite,
} from "pixi.js";

// Alpha (uniform transparency without per-child layering)
const alpha = new AlphaFilter({ alpha: 0.5 });

// Blur — strength/quality are uniform; strengthX/strengthY split axes;
// kernelSize must be odd (5, 7, 9, ... 15); repeatEdgePixels avoids transparent edges
const blur = new BlurFilter({
  strength: 4,
  quality: 4,
  kernelSize: 5,
  repeatEdgePixels: false,
});

// Color matrix — brightness is one of many presets. Others: tint, hue,
// contrast, saturate, desaturate, greyscale/grayscale, blackAndWhite,
// negative, sepia, technicolor, polaroid, kodachrome, browni, vintage,
// colorTone, night, predator, lsd, reset. Direct access via
// `colorMatrix.matrix` (20-element array) and `colorMatrix.alpha` (blend
// between original and transformed).
const colorMatrix = new ColorMatrixFilter();
colorMatrix.brightness(1.5, false);
colorMatrix.contrast(0.5, true); // multiply stacks on top of existing matrix
colorMatrix.alpha = 0.7; // blend at 70% strength

// Displacement — scale is a number or PointData
const displacementTexture = await Assets.load("displacement_map.png");
const displacementSprite = new Sprite(displacementTexture);
const displacement = new DisplacementFilter({
  sprite: displacementSprite,
  scale: { x: 20, y: 10 },
});

// Noise — seed is an arbitrary number that determines the noise pattern; same seed reproduces the same pattern
const noise = new NoiseFilter({ noise: 0.5, seed: Math.random() });

sprite.filters = [blur, colorMatrix];

Custom filter with Filter.from()

The simplest way to create a custom filter. Only a fragment shader is needed; PixiJS provides a default vertex shader.

import { Filter } from "pixi.js";

const filter = Filter.from({
  gl: {
    fragment: `
            in vec2 vTextureCoord;
            out vec4 finalColor;
            uniform sampler2D uTexture;
            uniform float uTime;

            void main() {
                vec2 uv = vTextureCoord;
                uv.x += sin(uv.y * 10.0 + uTime) * 0.02;
                finalColor = texture(uTexture, uv);
            }
        `,
  },
  resources: {
    timeUniforms: {
      uTime: { value: 0, type: "f32" },
    },
  },
});

sprite.filters = filter;

app.ticker.add((ticker) => {
  filter.resources.timeUniforms.uniforms.uTime += 0.04 * ticker.deltaTime;
});

For more control, construct GlProgram/GpuProgram objects directly:

import { Filter, GlProgram } from "pixi.js";

const glProgram = GlProgram.from({ fragment: fragmentSrc, vertex: vertexSrc });

const filter = new Filter({
  glProgram,
  resources: {
    timeUniforms: {
      uTime: { value: 0, type: "f32" },
    },
  },
});

Key points:

  • Use out vec4 finalColor in fragment shaders, not gl_FragColor (GLSL ES 3.0).
  • Use texture() to sample, not texture2D.
  • glProgram for WebGL, gpuProgram for WebGPU. Omitting one skips that renderer.
  • Textures go in resources, not uniforms. The filter system auto-provides uTexture (the input).
  • Access uniform values via filter.resources.{groupName}.uniforms.{name}.

Filter options

import { Filter, GlProgram, Rectangle } from "pixi.js";

const filter = new Filter({
  glProgram: GlProgram.from({ fragment }),
  resources: {},
  resolution: 0.5, // default 1. Lower = faster, blurrier. 'inherit' matches the render target resolution
  padding: 10, // default 0. Extra pixels for effects that extend bounds
  antialias: "off", // default 'off'. 'on' | 'off' | 'inherit'
  blendMode: "normal", // default 'normal'
  blendRequired: false, // default false. true if shader samples uBackTexture
  clipToViewport: true, // default true
});

// Optimization: set known bounds to avoid per-frame measurement
container.filterArea = new Rectangle(0, 0, 800, 600);

// Toggle without rebuilding the filter array
filter.enabled = false;

// Share one filter instance across many display objects
sprite1.filters = [filter];
sprite2.filters = [filter];

Community filters (pixi-filters)

import { AdjustmentFilter } from "pixi-filters/adjustment";
import { GlowFilter } from "pixi-filters/glow";

sprite.filters = [
  new AdjustmentFilter({ brightness: 1.2, contrast: 1.1 }),
  new GlowFilter({ distance: 15, outerStrength: 2 }),
];

For v8, community filters use pixi-filters/{name} imports, not the old @pixi/filter-* packages.

Advanced blend modes

Advanced blend modes (color-burn, overlay, hard-light, etc.) are powered by the filter system and must be imported before use. They also require useBackBuffer: true on WebGL; see the pixijs-blend-modes skill for the full list.

import "pixi.js/advanced-blend-modes";

await app.init({ useBackBuffer: true });
sprite.blendMode = "color-burn";

Advanced blend modes are filter-based, so they inherit Filter.defaultOptions, whose resolution defaults to 1. On high-DPI render targets this can make a blend mode look clipped, scaled, or only partially applied. Set Filter.defaultOptions.resolution = 'inherit' before creating the affected objects to render at the render target resolution, at higher memory and runtime cost:

import { Filter } from "pixi.js";
import "pixi.js/advanced-blend-modes";

Filter.defaultOptions.resolution = "inherit";
sprite.blendMode = "overlay";

Common Mistakes

[CRITICAL] Using old Filter constructor (vertex, fragment, uniforms)

Wrong:

import { Filter } from "pixi.js";

const filter = new Filter(vertex, fragment, { uTime: 0 });

Correct:

import { Filter, GlProgram } from "pixi.js";

const filter = new Filter({
  glProgram: GlProgram.from({ fragment, vertex }),
  resources: {
    timeUniforms: { uTime: { value: 0, type: "f32" } },
  },
});

v8 uses an options object. Shaders must be wrapped in GlProgram.from() or GpuProgram.from(). Uniforms are grouped in resources with explicit types. Textures are resources, not uniforms.

[HIGH] Using @pixi/filter-* packages for v8

Wrong:

import { AdjustmentFilter } from "@pixi/filter-adjustment";

Correct:

import { AdjustmentFilter } from "pixi-filters/adjustment";

@pixi/filter-* packages are v7 only. For v8, the community filters package restructured to pixi-filters/{name}.

[HIGH] Using too many filters without containerizing

Each filter application requires a framebuffer switch, bounds measurement, and render-to-texture pass. One filter on a parent container is much cheaper than the same filter on each child.

Wrong:

for (const child of container.children) {
  child.filters = [new BlurFilter({ strength: 4 })];
}

Correct:

container.filters = [new BlurFilter({ strength: 4 })];

[HIGH] Using a blendRequired filter without useBackBuffer on WebGL

Custom filters and most advanced community filters that set blendRequired: true sample the back buffer. On WebGL that only works if the renderer was initialized with useBackBuffer: true; otherwise PixiJS logs a warning and the filter silently falls back:

await app.init({ useBackBuffer: true });

WebGPU enables the back buffer unconditionally, so this only affects WebGL.

[MEDIUM] Not setting filterArea for known-size containers

Without filterArea, PixiJS measures the container bounds every frame via getGlobalBounds(), which recursively walks all children. For containers with known dimensions, set filterArea to avoid this cost:

import { Rectangle } from "pixi.js";

container.filterArea = new Rectangle(0, 0, 800, 600);
container.filters = [someFilter];

API Reference

Related skills

More from pixijs/pixijs-skills and the wider catalog.

PIpixijs-html-source logo

pixijs-html-source

pixijs/pixijs-skills

Use this skill when rendering live HTML/DOM elements (or frozen snapshots of them) as PixiJS v8 textures via the EXPERIMENTAL HTML-in-Canvas browser APIs. Covers the pixi.js/html-source side-effect import, feature-detection with canvas.requestPaint, HTMLSource for a live, repainting element kept interactive in the browser (autoLayout/autoUpdate/autoRequestPaint, requestPaint, isReady, the direct-child-of-canvas + layoutsubtree requirement), ElementImageSource for an immutable captureElementImage() snapshot (autoClose, ready immediately), using the source on a Sprite/Texture/Mesh, fallback-only auto-detection via Texture.from at priority -10, and destroy/cleanup. Triggers on: HTMLSource, ElementImageSource, pixi.js/html-source, requestPaint, captureElementImage, ElementImage, layoutsubtree, autoRequestPaint, autoUpdate, autoClose, HTML in canvas, render DOM to texture, HTMLSourceOptions, ElementImageSourceOptions, HTMLSourceCanvas, experimental.

773 installsAudited
PIpixijs-math logo

pixijs-math

pixijs/pixijs-skills

PixiJS v8 math primitives: points, matrices, shapes, hit testing, and coordinate transforms.

2.0k installsAudited
PIpixijs-migration-v8 logo

pixijs-migration-v8

pixijs/pixijs-skills

Migrate PixiJS v7 code to v8: async init, new Graphics API, single package, shader rework.

1.7k installsAudited
PIpixijs-performance logo

pixijs-performance

pixijs/pixijs-skills

Profile and optimize PixiJS v8 apps for FPS, draw calls, and GPU memory with targeted patterns.

2.0k installsAudited
PIpixijs-scene-container logo

pixijs-scene-container

pixijs/pixijs-skills

Group, position, and transform display objects in PixiJS v8 scenes.

2.0k installsAudited
PIpixijs-scene-core-concepts logo

pixijs-scene-core-concepts

pixijs/pixijs-skills

Understand PixiJS v8 scene graph architecture: containers, leaves, transforms, and render order.

2.0k installsAudited