pixijs-filters

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.

Skill file

Preview skill file
---
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

```ts
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

```ts
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.

```ts
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:

```ts
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

```ts
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)

```ts
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.

```ts
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:

```ts
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:

```ts
import { Filter } from "pixi.js";

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

Correct:

```ts
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:

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

Correct:

```ts
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:

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

Correct:

```ts
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:

```ts
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:

```ts
import { Rectangle } from "pixi.js";

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


## API Reference

- [Filter](https://pixijs.download/release/docs/filters.Filter.html.md)
- [AlphaFilter](https://pixijs.download/release/docs/filters.AlphaFilter.html.md)
- [BlurFilter](https://pixijs.download/release/docs/filters.BlurFilter.html.md)
- [BlurFilterPass](https://pixijs.download/release/docs/filters.BlurFilterPass.html.md)
- [ColorMatrixFilter](https://pixijs.download/release/docs/filters.ColorMatrixFilter.html.md)
- [DisplacementFilter](https://pixijs.download/release/docs/filters.DisplacementFilter.html.md)
- [NoiseFilter](https://pixijs.download/release/docs/filters.NoiseFilter.html.md)
- [FilterSystem](https://pixijs.download/release/docs/rendering.FilterSystem.html.md)

Source

Creator's repository · pixijs/pixijs-skills

View on GitHub

License: MIT

Security

Security checks in progress
Results will appear here once audits complete
What this skill can do
Reads your filesConnects to the internetRuns code on your machine
Checked by 3 independent security firms
Does it try to trick the AI?Not yet checkedPending · Gen Agent Trust Hub
Does it sneak in hidden code?Not yet checkedPending · Socket
Does it have known bugs?Not yet checkedPending · Snyk