mcpField
P
pixijs-filters

pixijs-filters

github.com/pixijs开发3585.9k 次安装4 周前更新
代码仓库

关于 pixijs-filters

面向 PixiJS 开发者的技能,介绍如何为场景对象应用内置及自定义视觉滤镜。内容涵盖滤镜配置、着色器扩展,以及渲染与性能注意事项。

主要功能

  1. 01内置模糊、色彩和噪声滤镜
  2. 02自定义 GLSL 与 WGSL 滤镜
  3. 03在容器上串联滤镜
  4. 04滤镜分辨率与边距选项
  5. 05性能与 WebGL 后缓冲指导

适用场景

  1. 01为精灵应用模糊或色彩调整
  2. 02构建着色器视觉效果
  3. 03在容器上统一应用效果而非逐个处理子对象
  4. 04调整滤镜边界和分辨率

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/pixijs/pixijs-skills --skill pixijs-filters

安装后在 Claude Code 中输入/pixijs-filters确认已加载。

详细介绍

通过将一个滤镜(或用于串联的数组)赋给 container.filters,即可添加视觉效果。内置滤镜涵盖模糊、颜色矩阵、位移、透明度和噪声;自定义滤镜则通过 Filter.from(...) 封装 GLSL/WGSL 片段着色器。

快速入门

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);

相关技能: pixijs-custom-rendering(着色器内部机制、uniform 类型)、pixijs-blend-modes(与滤镜组合)、pixijs-performance(滤镜调优、filterArea)。

核心模式

内置滤镜
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];
使用 Filter.from() 创建自定义滤镜

这是创建自定义滤镜最简单的方法。只需提供片段着色器;PixiJS 会提供默认顶点着色器。

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;
});

如需更多控制,可直接构造 GlProgram/GpuProgram 对象:

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" },
    },
  },
});

要点:

  • 在片段着色器中使用 out vec4 finalColor,而不是 gl_FragColor(GLSL ES 3.0)。
  • 使用 texture() 采样,而不是 texture2D。
  • WebGL 使用 glProgram,WebGPU 使用 gpuProgram。省略其中一个会跳过对应的渲染器。
  • 纹理应放在 resources 中,而不是 uniforms 中。滤镜系统会自动提供 uTexture(输入)。
  • 通过 filter.resources.{groupName}.uniforms.{name} 访问 uniform 值。
滤镜选项
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];
社区滤镜(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 }),
];

对于 v8,社区滤镜使用 pixi-filters/{name} 导入,而不是旧版 @pixi/filter-* 包。

高级混合模式

高级混合模式(color-burn、overlay、hard-light 等)由滤镜系统提供,使用前必须导入。在 WebGL 上还需要设置 useBackBuffer: true;完整列表请参见 pixijs-blend-modes 技能。

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

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

高级混合模式基于滤镜,因此会继承 Filter.defaultOptions,其 resolution 默认值为 1。在高 DPI 渲染目标上,这可能导致混合模式看起来被裁切、缩放或仅部分生效。创建受影响的对象前,将 Filter.defaultOptions.resolution = 'inherit' 设为渲染目标分辨率,以提高内存和运行时开销为代价:

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

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

常见错误

[CRITICAL] 使用旧版 Filter 构造函数(vertex、fragment、uniforms)

错误:

import { Filter } from "pixi.js";

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

正确:

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

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

v8 使用选项对象。着色器必须封装在 GlProgram.from() 或 GpuProgram.from() 中。Uniforms 按组放在 resources 中,并显式指定类型。纹理是资源,而不是 uniforms。

[HIGH] 在 v8 中使用 @pixi/filter-* 包

错误:

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

正确:

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

@pixi/filter-* 包仅适用于 v7。对于 v8,社区滤镜包已重组为 pixi-filters/{name}。

[HIGH] 使用过多滤镜但未使用容器

每次应用滤镜都需要切换帧缓冲区、测量边界,并执行一次渲染到纹理的过程。将一个滤镜应用于父容器,远比将相同滤镜应用于每个子项开销低。

错误:

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

正确:

container.filters = [new BlurFilter({ strength: 4 })];
[HIGH] 在 WebGL 上使用 blendRequired 滤镜但未设置 useBackBuffer

设置了 blendRequired: true 的自定义滤镜和大多数高级社区滤镜都会采样后备缓冲区。在 WebGL 上,只有在初始化渲染器时设置了 useBackBuffer: true 才能正常工作;否则 PixiJS 会记录警告,滤镜会静默回退:

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

WebGPU 始终启用后备缓冲区,因此这只影响 WebGL。

[MEDIUM] 未为尺寸已知的容器设置 filterArea

未设置 filterArea 时,PixiJS 每帧都会通过 getGlobalBounds() 测量容器边界,该方法会递归遍历所有子项。对于尺寸已知的容器,设置 filterArea 可避免这项开销:

import { Rectangle } from "pixi.js";

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

API Reference

评论

支持 Markdown