Pixijs Filters

作者 pixijs83760c6f5346MIT346 個星標收錄於 2026年10月8日更新於 2026年10月8日儲存庫7 天前更新

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.

AI 產生的概覽

指導透過濾鏡管線為 PixiJS v8 套用視覺效果,涵蓋內建濾鏡與自訂著色器濾鏡。

功能
說明如何將 AlphaFilter、BlurFilter、ColorMatrixFilter、DisplacementFilter 和 NoiseFilter 等 PixiJS v8 內建濾鏡掛載到容器上,以及如何使用 Filter.from() 搭配 GLSL 或 WGSL 片段著色器建立自訂濾鏡。內容也涵蓋 resolution、padding、antialias 等濾鏡選項、filterArea 最佳化,以及 pixi-filters 社群套件。產出為參考說明與程式碼範例,而非產生的檔案。
適用情境
適用於需要透過濾鏡為 PixiJS v8 顯示物件或容器加入視覺效果的情境。也適合撰寫以著色器為基礎的自訂濾鏡、調整濾鏡效能,或從舊版 PixiJS 濾鏡 API 移轉時使用。
執行需求
需要 PixiJS v8 專案;自訂濾鏡需要 GLSL 或 WGSL 著色器知識。社群濾鏡可選用 pixi-filters 套件。不包含指令碼。

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 edgesconst 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 matrixcolorMatrix.alpha = 0.7; // blend at 70% strength
// Displacement — scale is a number or PointDataconst 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 patternconst 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 measurementcontainer.filterArea = new Rectangle(0, 0, 800, 600);
// Toggle without rebuilding the filter arrayfilter.enabled = false;
// Share one filter instance across many display objectssprite1.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

來源與署名

來源:pixijs/pixijs-skills位於skills/pixijs-filters提交83760c6

授權條款: MIT

內容歸原作者所有。SourceWeft 從公開儲存庫中收錄這些內容。

檢舉或申請下架