mcpField
P
pixijs-filters

pixijs-filters

github.com/pixijs開発3585.9k 回インストール4 週間前に更新
リポジトリ

pixijs-filters について

PixiJS 開発者向けに、組み込みおよびカスタムのビジュアルフィルターをシーンオブジェクトへ適用する方法を解説するスキルです。設定、シェーダー拡張、レンダリングとパフォーマンスの注意点を扱います。

主な機能

  1. 01組み込みのぼかし・色調・ノイズフィルター
  2. 02GLSL と 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 にフィルターを1つ(または連鎖させるための配列)割り当てて適用します。組み込みフィルターは、ぼかし、カラーマトリックス、ディスプレイスメント、アルファ、ノイズをカバーします。カスタムフィルターは、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(シェーダーの内部構造、ユニフォームの型)、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" },
    },
  },
});

要点:

  • フラグメントシェーダーでは gl_FragColor ではなく out vec4 finalColor を使用します(GLSL ES 3.0)。
  • サンプリングには texture() を使用し、texture2D は使用しません。
  • WebGL では glProgram、WebGPU では gpuProgram を使用します。どちらかを省略すると、そのレンダラーではスキップされます。
  • テクスチャはユニフォームではなく、resources に配置します。フィルターシステムは uTexture(入力)を自動的に提供します。
  • filter.resources.{groupName}.uniforms.{name} を介してユニフォームの値にアクセスします。
フィルターのオプション
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/filter-* パッケージではなく、pixi-filters/{name} をインポートします。

高度なブレンドモード

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

高度なブレンドモードはフィルターベースのため、resolution のデフォルト値が 1 である Filter.defaultOptions を継承します。高 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() でラップする必要があります。ユニフォームは明示的な型を指定して resources にグループ化します。テクスチャはユニフォームではなく、リソースです。

[HIGH] v8 で @pixi/filter-* パッケージを使用する

誤り:

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

正しい例:

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

@pixi/filter-* パッケージは v7 専用です。v8 では、コミュニティフィルターのパッケージ構成が pixi-filters/{name} に変更されています。

[HIGH] コンテナー化せずにフィルターを使いすぎる

フィルターを適用するたびに、フレームバッファーの切り替え、境界の測定、テクスチャへのレンダリングパスが必要になります。親コンテナーにフィルターを1つ適用する方が、各子要素に同じフィルターを適用するよりもはるかに低コストです。

誤り:

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

正しい例:

container.filters = [new BlurFilter({ strength: 4 })];
[HIGH] WebGL で useBackBuffer を設定せずに blendRequired フィルターを使用する

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

コメント