PixiJSとは何か?WebGLベースの高速2D描画エンジンの概要と活用メリットについて徹底解説

目次

PixiJSとは何か?WebGLベースの高速2D描画エンジンの概要と活用メリットについて徹底解説

PixiJSはWebGL(またはWebGPU)を土台にしたオープンソースの2Dレンダリングエンジンです。Webブラウザ上で高速かつ高品質な2Dグラフィックス描画を可能にし、ゲームやインタラクティブ広告、教育コンテンツ、データ可視化など幅広い用途で利用されています。商用利用も含めMITライセンスで無償利用でき、多くの企業のキャンペーンサイトやスマホゲームのブラウザ版、デジタルサイネージなどプロの現場でも採用されている実績があります。
PixiJSの最大の特徴は、「WebGLのパワーを手軽に使える」点にあります。通常、ブラウザでリッチなアニメーションや多数のオブジェクトを描画しようとすると、<canvas>要素やSVGを直接JavaScriptで操作しなければなりません。しかしそれらを高度に活用するコードは複雑になりがちで、オブジェクト数が増えると性能面の限界もあります。PixiJSは低レベルなWebGL APIを抽象化し、シンプルなAPIで操作できるようにすることで、こうした煩雑さを解消しつつGPUによる高速描画を実現しています。例えばスプライト(画像オブジェクト)やテキスト、シェイプ描画、フィルター効果、マスク処理など、リッチな表現に必要な機能がひと通り揃っており、開発者はそれらを組み合わせるだけで高度な2D表現が可能です。
またPixiJSは純粋な2D専用エンジンであり3D表現は扱いませんが、その分軽量かつ高速で、2Dに特化した最適化が図られています。Flash全盛期には困難だったマルチプラットフォーム(PC・スマホ問わず)でのスムーズなアニメーション描画を、PixiJSはブラウザ上で実現します。特に以下の点でエンジニアにとって扱いやすいよう設計されています:

オブジェクトの管理がしやすい

シーンを階層構造(シーングラフ)で表現でき、親子関係による直感的なオブジェクト配置・管理が可能。

クリック/タッチなどインタラクション対応が簡単

オブジェクトごとにイベントリスナーを設定するだけで、ユーザーの入力操作を検知できる。
以上のように、PixiJSは「WebGLの高性能を背景に持ちながら、シンプルなJavaScript APIでリッチな2D表現を実装できる」点が大きな魅力です。次章では、そんなPixiJSの最新版であるv8系の新機能について詳しく見ていきましょう。

PixiJS v8の新機能紹介:WebGPU対応や描画性能向上など、最新版の注目ポイントを徹底解説!

2024年3月にリリースされたPixiJS v8では、大規模なアップデートが行われました。その中でも特に注目すべきポイントが次世代WebAPIである「WebGPU」への対応と描画パフォーマンスの大幅向上です。加えて、開発者に嬉しいAPI改善や内部構造の刷新も含まれています。主な新機能・変更点をまとめると以下の通りです。

WebGPUレンダラーの統合

従来のWebGLに加えて、新たにWebGPUに対応しました。WebGPUは将来的にWebGLの後継となりうる最新のグラフィックスAPIであり、ブラウザ上でより高効率なGPU活用を可能にします。PixiJS v8ではこのWebGPUを既存のWebGLレンダラーへの単なる追加ではなくエンジンのコアに統合しており、WebGLが将来的にフェーズアウトしても最先端の技術に追随できる設計になっています。環境に応じて自動的にWebGL/WebGPUを選択し、ユーザ側のコード変更なしに次世代技術の恩恵を受けられる点は大きな強みです。

全般的なパフォーマンス向上

PixiJSは元々高速な描画エンジンとして知られていましたが、v8ではさらに描画処理の効率化が図られ、WebGL利用時でもv7より高速になっています。レンダリングループが最適化され、毎フレームで「必要な更新だけを行う」リアクティブな仕組みに改良されたためです。その結果、例えば100,000個のスプライトを一斉に動かすベンチマークでは、v7ではCPU処理に約50msかかっていたところがv8では15ms程度と約3倍高速化し、GPU処理時間も9msから2msへと約3.5倍も短縮されています。静止オブジェクトではさらに顕著で、100k個のスプライトが画面上にあるだけの場合、CPU時間は21msからわずか0.12msへと激減しています。このようにv8は大量オブジェクト描画のボトルネックを徹底的に削減しており、大規模な描画でもより高いフレームレートを期待できます。

パッケージ構成の変更(単一パッケージ化)

v7までは@pixi/spriteや@pixi/graphics等に分割されていたPixiJSの各機能ですが、v8では一つのパッケージに再統合されました。例えば従来はSpriteクラスを使うのに別パッケージを個別にimportしていましたが、v8ではimport { Sprite, Graphics } from ‘pixi.js’;のようにpixi.jsモジュールから一括で必要なクラスを取り出せるようになっています。これによりビルド時のツリーシェイキング性能も向上し、使っていない部分を自動的に除外してバンドルサイズを削減しやすくなりました。

初期化手順の変更(非同期化)

WebGPU対応に伴い、レンダラーの初期化処理が非同期になりました。Applicationを生成した後、即座に利用する前にawait app.init()で初期化完了を待つ必要があります(詳細は後述)。これにより、ユーザー環境に応じた最適なバックエンド(WebGL/WebGPU)のモジュールを動的にロードする仕組みになっています。適切な初期化手順を踏まないと描画が行われないため、この変更はv7から移行する際のハマりポイントの一つです。

描画機能の強化

表現力の面でもさまざまな改良が加わりました。例えば新たに「レンダーグループ」機能が追加され、特定のContainerをGPU側で処理することで2Dカメラのような挙動(大きなワールドのパンやズームを高速に実現)を可能にしています。またブレンドモードやティント(色調)の継承がサポートされ、親コンテナに対して一括で乗算ブレンディングや色調変更を指定すると子オブジェクトにも自動適用されるようになりました。このほかPhotoshopライクな多数のブレンドモードが標準で追加されたり、Graphics描画APIの使い勝手向上(Canvasの2Dコンテキストに近いメソッド追加やSVGパス対応、グラデーション塗りつぶし対応など)、テキスト機能の強化(HTML形式テキストの統合やBitmapFontのオンザフライ生成など)といった改善も盛り込まれています。
以上がPixiJS v8の主な新機能・改善点です。最新バージョンでは将来を見据えた技術対応と既存機能のブラッシュアップが図られ、より高速かつ開発者フレンドリーなエンジンへ進化しています。それでは次に、そのPixiJS v8を実際にプロジェクトに導入する方法を解説していきます。

PixiJS v8の導入方法:CDNスクリプト利用・Node.js環境でのインストールと初期化手順を解説

PixiJS v8を使い始めるには、大きく分けて2通りの導入方法があります。ひとつはCDN経由でブラウザに直接読み込む方法、もうひとつはnpmパッケージをプロジェクトに追加してビルド環境で利用する方法です。それぞれ順を追って説明します。

1. CDNからスクリプトを読み込む方法

最も手軽にPixiJSを試すには、公式が提供しているCDN(Content Delivery Network)上のライブラリを利用する方法があります。PixiJS公式サイトやcdnjsなどでホストされているスクリプトファイルを直接HTMLに読み込むことで、即座にPIXIグローバルオブジェクトを使えるようになります。
例: HTML内でPixiJS v8を読み込む基本的な記述(UMDビルドを利用):

<script src="https://cdnjs.cloudflare.com/ajax/libs/pixi.js/8.5.0/pixi.min.js"></script>
この記述をページに追加すると、JavaScriptからPIXI.Application等のクラスにアクセスできるようになります。公式サイトのExamplesや他のチュートリアルコードを動かしたい場合は、この方法が手軽です。なお、CDN経由の場合はインターネット接続が必要になる点に注意してください。
ESモジュール版として、次のようにtype=”module”でESM版を読み込むことも可能です:
<script type="module">
import * as PIXI from "https://cdn.jsdelivr.net/npm/pixi.js@8/dist/browser/pixi.min.mjs";
// ここでPIXI.Applicationを利用したコードを書く…
</script>
ESM版を使うとツリーシェイキングが働きますが、ブラウザ環境によってはモジュール対応が必要です。簡便さでは前者のUMD版読み込みが勝るでしょう。

2. Node.js+ビルド環境でインストールする方法

プロジェクトでしっかりPixiJSを組み込む場合は、npmパッケージとしてPixiJSを追加する方法が一般的です。Node.jsの環境が整っていれば、以下のコマンドでパッケージをインストールできます。
npm install pixi.js
インストール後、モジュールバンドラを利用しているプロジェクトでは、JavaScript/TypeScriptコード中でPixiJSをインポートして使用します。PixiJS v8では前述の通り単一パッケージになったため、次のように記述します。
import { Application, Graphics, Sprite, Assets } from ‘pixi.js’;
この一行で必要なクラスをすべて取り込めます。旧バージョンから移行する際には、@pixi/*名前空間のインポート文をこの形に書き換える必要がある点に注意してください。

3. Pixiアプリケーションの初期化

PixiJSを読み込みインポートできたら、次は実際にPixiアプリケーション(描画領域)を初期化します。v8ではPIXI.Applicationクラスの使用方法が一部変更されています。基本的な流れは以下の通りです。

1. Applicationインスタンスの生成

描画領域とレンダラーを管理するApplicationオブジェクトを作成します。サイズ指定や背景色などのオプションはv8ではコンストラクタではなく後述のinitメソッドで渡す仕様に変わりました。まずはオプション無しで生成します。
const app = new PIXI.Application();

2. 非同期の初期化処理

続いて非同期メソッドであるapp.init(options)を呼び出し、レンダラー等の初期化完了を待ちます。initにはオプションとして、背景色やサイズ、アンチエイリアス設定などを渡せます。例えばウィンドウ全体を描画領域にし、背景色を白にする場合:
await app.init({
resizeTo: window,
backgroundColor: 0xffffff,
antialias: true
});
initの完了をawaitしないとレンダリングが開始されないため注意してください(async functionの中で呼ぶか、Promiseチェーンを利用します)。

3. canvas要素のDOM配置

Applicationが管理するHTMLCanvasElement(app.viewまたはapp.canvasプロパティ)を実際のページDOMに追加します。例えば:
document.body.appendChild(app.view);
これでブラウザ上にPixiJSの描画用<canvas>が配置されます。ここまでで初期化は完了です。
以上が基本的な導入と初期化手順です。特にv8ではawait app.init()が必要になった点を押さえておきましょう。これは前述したWebGPU対応による変更で、適切に初期化することで環境に応じた最適なレンダラー(WebGL/WebGPU)が選択・ロードされます。初期化周りでエラーが出る場合は、init()の呼び出し忘れや記述ミスがないか確認してみてください。

PixiJS v8の基本的な使い方とサンプルコード:表示オブジェクトの描画と簡単なアニメーションの入門解説

PixiJSを導入できたら、実際に表示オブジェクト(DisplayObject)を描画してみましょう。基本的な使い方の流れは次のとおりです。

1. 表示するオブジェクトを作成

スプライト画像や図形、テキストなどを生成します。例えば画像を表示する場合はPIXI.Spriteを、簡単な図形ならPIXI.Graphicsを使用します。

2. ステージに配置(addChild)

作成したオブジェクトをapp.stageに追加します。stageは表示オブジェクトツリーのルート(親)です。

3. 必要に応じてアニメーション処理

動きを付けたい場合は毎フレーム更新処理を登録します。PixiJSではapp.tickerに関数を登録することで、FPSに合わせて繰り返し実行できます。

4. レンダリング

Applicationはデフォルトで自動的にループ描画します。特に何もする必要はありませんが、手動で制御する場合はapp.ticker.stop()やapp.render()も可能です。
では具体例として、赤い円を画面上に描画し左右に動かす簡単なコードを見てみます。
// 1. Graphicsオブジェクトで赤い円を生成
const circle = new PIXI.Graphics();
circle.beginFill(0xff0000);
circle.drawCircle(0, 0, 50); // 半径50の円
circle.endFill();
circle.x = 50; // 初期位置
circle.y = 100;

// 2. ステージに追加して表示
app.stage.addChild(circle);

// 3. アニメーションさせる: 毎フレーム円を移動
let speed = 3;
app.ticker.add(() => {
circle.x += speed;
// 端まで来たら反転
if (circle.x + 50 >= app.screen.width || circle.x - 50 <= 0) { speed *= -1; } });

上記コードでは、まずGraphicsで塗りつぶし円を描画し、stageに追加しています。続いてapp.ticker.addで毎フレームごとに円のx座標を更新し、画面端に達したら移動方向を反転させています。実行すると赤い円が左右にバウンドするアニメーションが確認できるはずです。
※PixiJS v8ではTickerによる自動更新がデフォルトで有効になっています。Application作成時にoptions.autoStartをfalseにしない限り、app.tickerは自動で動き出し、ticker.addした関数が毎フレーム実行されます。
画像スプライトの表示も見てみましょう。画像を表示する場合はSpriteクラスを使います。PixiJSには簡単な画像読み込み機能があり、例えば以下のように記述可能です。
const texture = await PIXI.Assets.load("https://pixijs.com/assets/bunny.png");
const bunny = new PIXI.Sprite(texture);
bunny.anchor.set(0.5); // アンカー(基準点)を中央に
bunny.x = app.screen.width / 2; // 画面中央に配置
bunny.y = app.screen.height / 2;
app.stage.addChild(bunny);

まずAssets.loadで画像URLからテクスチャを読み込み(v7までのPIXI.Loaderに相当)、Spriteに渡しています。アンカーを中央にセットしてステージの中心に配置すると、有名なバニーちゃん画像がCanvas中央に描画されます。もちろん自前の画像パスを指定すれば任意の画像スプライトを表示できます。
静的な表示だけでなく、先ほどのようにticker.addで位置を更新すれば画像を動かすこともできますし、回転させる場合はbunny.rotationプロパティを変化させるだけです。PixiJSでは座標系や回転角、スケーリングなど基本的な変形プロパティを直接操作するだけで、エンジンが自動的に画面に反映してくれます。さらに高度なアニメーションが必要であれば、GSAPなど他のアニメーションライブラリと組み合わせることも可能です。
このように、PixiJSの基本は「オブジェクトを作ってステージに追加し、必要なら毎フレーム更新する」ことに尽きます。シンプルなパターンで動くため、初心者でも理解しやすいでしょう。次章では、PixiJSの核となるGPU描画の仕組みについて、2D表現との関係を解説します。

PixiJSにおける2D表現とWebGLとは:GPUを活用した描画の仕組みと知っておきたい基礎知識を解説

PixiJSの高性能の秘密は、その描画処理の大部分をGPUに担わせている点にあります。Webブラウザ上でGPUを活用するための標準APIがWebGLであり、PixiJSはこのWebGLのラッパーとして機能します。ではWebGLとは何か、なぜGPUを使うと速いのか、2D描画とどう関係するのかを見ていきましょう。

WebGLは3D専用ではない?2D描画への応用

「WebGLって3Dグラフィックスのためのものでは?」という疑問を持つ方も多いでしょう。確かにWebGL(およびその元になったOpenGL)は主に3D描画を高速に行うためのAPIです。しかし2Dグラフィックスに使えないわけではありません。WebGLはポリゴン(主に三角形)の描画やテクスチャマッピング、シェーダーによるピクセル処理などを得意としますが、これは2D表現にも応用可能です。例えば「画像を表示する」は四角形にテクスチャを貼る処理ですし、「図形を塗りつぶす」も細かい三角形の集合で近似できます。要は2Dも最終的にはピクセル描画であり、その計算処理をGPUに任せられるなら大きな高速化が期待できるわけです。
実際、PixiJSではスプライト一つひとつがWebGL上のテクスチャ付き四辺形として描画されます。JavaScriptからはSpriteオブジェクトを操作するだけですが、内部では頂点バッファやシェーダーが効率良く管理され、多数のスプライトもまとめて一度に描画(バッチ描画)されます。これによりCPUが個々のオブジェクトを逐次描画する場合に比べて桁違いに高速になります。特に複雑なパーティクル演出やフィルタ効果など重い描画処理もGPUなら高速で、CPU処理のボトルネックを回避できます。逆に言えば、Canvas2Dで十分な軽い描画であっても、将来的に表現を強化する可能性があるなら初めからWebGLベースのPixiJSを使っておくメリットがあります(PixiJS自体のロードが約350KB程度と軽量なのでオーバーヘッドも小さいです)。

GPUによる並列処理の威力

GPU(Graphics Processing Unit)は並列処理に優れたプロセッサです。一度に数百~数千の演算ユニットでピクセル描画や頂点変換を行えるため、多数のオブジェクトを同時に処理する場合に極めて高い性能を発揮します。ブラウザでの通常の描画(Canvas2DやDOM操作)はCPUが一つ一つの要素を順番に処理しますが、GPUを使えば画面全体を一気に描画できます。WebGLはこのGPU機能を利用するためのAPIであり、シェーダーと呼ばれるプログラムを書いて柔軟な描画効果も得られます。
もっとも、直接WebGLを扱うのは高い専門知識を要しハードルが高いのも事実です。そこで登場するのがPixiJSのようなエンジンです。PixiJSは高度なWebGL知識がなくても直感的なコードで2D描画ができるよう設計されています。例えば「スプライトをステージにaddする」だけで、裏では適切なバッファ設定やテクスチャ転送が行われ描画されます。開発者は2Dに特化したシンプルなAPIに集中でき、その裏でGPUパワーが最大限活用されるのです。
まとめると、PixiJSにおける2D表現とWebGLは切っても切れない関係です。WebGL(そして将来のWebGPU)の性能を背景に、PixiJSはリッチな2Dグラフィックスを滑らかに描画する基盤を提供しています。エンジニアはPixiJSを使うことで、難解なWebGLコードを書くことなくGPUの恩恵を享受できるというわけです。
では次に、そのPixiJSの強みであった「インタラクション対応」について詳しく見ていきましょう。クリックやタッチイベントをどのように扱えるのかを解説します。

PixiJSのイベント処理(クリックやタッチ対応):インタラクティブな入力操作の実装方法を詳しく解説

PixiJSはブラウザのマウス・タッチイベントを統合的に扱える独自のイベントシステムを備えています。これは従来のInteractionManagerを刷新したもので、DOMのイベントモデルに近い使い勝手でありながら高パフォーマンスに動作するのが特徴です。ここではクリックやタッチ操作を扱う方法を中心に、イベント処理の基本を解説します。

基本のイベント設定手順

1. イベント対象オブジェクトをインタラクティブに設定

PixiJSでは表示オブジェクトごとに「イベントを受け取るか」を設定できます。v7まではobject.interactive = true;で指定していましたが、v8ではeventModeプロパティで設定する方式に変わりました。例えばボタンにしたいスプライトの場合:
const button = new PIXI.Sprite(texture);
button.eventMode = 'static'; // このオブジェクト自身でイベントを受け取る
eventMode = 'static'は「自分自身がヒットテスト対象となり、イベントを発火する」モードです(対して'none'は非インタラクティブ、'passive'は自分は無視して子要素のみなど複数モードがあります)。動かないボタンなど大半のケースでは'static'で良いでしょう。

2. イベントリスナーの登録

対象オブジェクトに対して、扱いたいイベント種類のリスナー関数を登録します。PixiJSではDOMと同様にonメソッド(もしくはaddEventListenerメソッドの alias)でイベントハンドラを設定できます。例えばクリック(タップ)に反応させたい場合:
button.on('pointerdown', () => {
console.log('ボタンがクリックされました');
});
ここではpointerdownイベントを使っていますが、PixiJSはマウス・タッチ・ペン入力を統一した「ポインタイベント」をサポートしています。pointerdownはマウスのmousedownやタッチ開始に相当し、対応するpointerupやクリックを抽象化したpointertapなども用意されています。基本的にはpointer系イベントを使うのが推奨で、これ一つでPCとモバイル両方の入力に対応可能です。

3. 必要に応じて追加設定

ボタン演出としてマウスオーバー時にカーソルを指マークにしたい場合は、オブジェクトのbuttonModeプロパティをtrueにするとCSSカーソルが自動で変更されます。またドラッグ操作を実装する場合はpointerdownでドラッグ開始フラグを立て、pointermoveで位置更新、pointerupでドラッグ終了処理をする、といったように複数イベントを組み合わせます。PixiJSはドラッグ専用のイベントはありませんが、これら低レベルイベントを組み合わせることで自由に実装できます。

イベント処理の仕組みと注意点

PixiJSのイベントシステムはシーングラフ上での伝播もサポートしています。親コンテナがeventMode='auto'もしくは'static'なら、その子もヒットテスト対象になります(逆に'none'だと子も含め全て無視)。また、あるオブジェクトがクリックされた際に、その親やさらに上位の祖先コンテナにもイベントがバブルアップする(伝播する)仕組みがあります。これにより、例えば背景コンテナで全体のクリックを捕捉するといった実装も可能です。
v8での変更点として、前述のようにinteractiveプロパティ設定がeventModeに置き換わった点が挙げられます。旧来のコードではsprite.interactive = true;としていた箇所は、v8ではsprite.eventMode = 'static';にする必要があります。またイベントオブジェクトの型なども改善されており、DOMのEventに近いプロパティ(例えばevent.globalX/Yで画面座標取得など)が使えます。移行時には古い書き方との違いに注意してください。
パフォーマンス上の注意としては、非常に多数のオブジェクトにイベントを付けるとヒットテストの負荷が上がります。使わない場合は親コンテナでeventMode = 'none'(または少なくともinteractiveChildren = false相当)にしておくとイベント探索をスキップでき負荷軽減になります。また、hitAreaを明示的に指定すると当たり判定計算が高速化される場合があります。通常は自動計算に任せて問題ありませんが、巨大な透明部分を持つスプライトなどでは検討しても良いでしょう。
まとめると、PixiJSのイベント処理は「対象をインタラクティブ化し、pointer系イベントをonで登録する」だけで直感的に扱えます。クリックやタッチへの反応はもちろん、ドラッグやホバー演出も自由に実装可能です。次章では、こうしたイベント対象を含むオブジェクト類をどのように管理・配置するか(シーンの階層構造)について解説します。
PixiJSのオブジェクト管理と階層構造:DisplayObjectによるシーンツリーの構築と管理方法
PixiJSでは、画面に表示される全ての要素(スプライト、テキスト、グラフィックスなど)はDisplayObjectと呼ばれるクラスを継承しています。そしてDisplayObject同士を親子関係で構成したシーングラフ(オブジェクトツリー)によって管理されます。この章ではPixiJSにおけるオブジェクト管理の仕組みを理解しましょう。

シーングラフとステージ

PixiJSアプリケーションを初期化すると、自動的にルートコンテナとしてapp.stageが生成されます。stageは表示オブジェクトツリーの根本(root)であり、全ての表示物は最終的にこのstageの子孫として追加しなければ画面に表示されません。新たなスプライトやグラフィックを表示する際には、基本的に以下のようにstage.addChild(オブジェクト)とします。
const sprite = PIXI.Sprite.from('image.png');
app.stage.addChild(sprite);
このaddChildを呼ぶことで、spriteはステージの子(直接の子供)となり、以後PixiJSの毎フレームの更新・描画対象に組み込まれます。PixiJSは毎フレーム、このシーングラフをルート(stage)から順に走査し、各オブジェクトを描画していきます。従って、ツリー上に存在しないオブジェクト(addChildされていない)は描画もイベント処理もされない点に注意しましょう。

コンテナと親子関係

PixiJSにはContainerクラスがあり、これはDisplayObjectを継承しつつ子を持てる特殊なオブジェクトです。stageもContainerの一種で、他にも自分自身は何も描画しないが子オブジェクトをグルーピングできる入れ物として利用します。コンテナを使うことでシーンに階層構造をもたせ、論理的にオブジェクトをグループ化できます。
親子関係の効果として重要なのは、「親の変形・状態が子に継承される」ことです。親を移動すれば子もまとめて移動し、親を回転すれば子も相対的な位置関係を保ったまま一緒に回転します。表示/非表示(visibleプロパティ)や透明度(alphaプロパティ)も親の値が乗算的に影響します。例えば親コンテナのalphaを0.5にし、子のalphaが1.0なら見た目は0.5の透明度になります。子のalphaを0.5にすると合計で0.25の透明度になる、という具合です。この継承のおかげで、複数のオブジェクトから成るキャラクターをコンテナでまとめておき、そのコンテナを動かすだけでキャラクター全体を移動・変形できるようになります。
オブジェクトを削除する際も親子関係を利用します。parent.removeChild(child)やcontainer.removeChild(sprite)で木構造から取り除けば、次フレームから描画されなくなります。ガベージコレクションの対象にもなるため、不要になった表示物はツリーから外すようにしましょう(テクスチャなど大きなリソースはdestroy()で明示的に破棄も可能です)。

表示順序の管理

シーングラフにおける描画順(奥行き関係)は、基本的にツリー内の挿入順序で決まります。PixiJSはステージから子を順番に描画し、同じ親を持つ子同士はaddChildされた順に描画されます。後に追加された子ほど手前に描画され、先に追加されたものは背面になります。例えば同じコンテナAの下に子BとCを追加した場合、コード上でA.addChild(B); A.addChild(C);とするとCがBの上(前面)に表示されます。これはちょうどHTMLの要素が後に書かれたほうが前面に積み重なるようなイメージです。
表示順を変えたいときは、PixiJSではいくつか方法があります。単純に後から追加し直すのが手軽ですが、コンテナのsetChildIndex(child, index)メソッドで任意のインデックス順に入れ替えることもできます。さらに、コンテナのsortableChildrenプロパティをtrueに設定し、各子にzIndex値を持たせることで、自動的にzIndexの数値順にソートして描画する仕組みも利用できます。この方法ならzIndex値を変更するだけで前後関係を制御できるため便利です。ただし子供の数が非常に多い場合に毎フレームソートが走ると負荷になるため、必要な場合に限定して使うのが良いでしょう。
以上、PixiJSのオブジェクト管理はシーンツリーで体系的に行われ、親子構造によりグループ操作や描画順管理が可能となっています。エンジニアはこの仕組みを理解することで、シンプルなUIから複雑なゲーム画面まで効率よく構築できるでしょう。次章では、このシーン内の描画順序をさらに細かく制御する方法と、パフォーマンスを最大化するテクニックについて掘り下げます。

PixiJSの描画順序制御(表示順)とパフォーマンス最適化:大量スプライトを高速処理するテクニックを徹底解説

前節で説明したように、PixiJSでは基本的に追加した順序(あるいはzIndex)でオブジェクトの前後関係を制御できます。しかし大規模なプロジェクトではより高度なレイヤー制御が必要になったり、同時にパフォーマンスにも気を配る必要が出てきます。この章では描画順序のテクニックと、大量オブジェクトを扱う際の最適化について詳しく解説します。

描画順序のテクニック

レイヤー用コンテナの活用

背景・中景・前景などレイヤーを分けたい場合、それぞれコンテナを用意してstageに追加し、各コンテナ間で順序を調整する方法があります。たとえばbgContainer(背景)とuiContainer(UI)を作り、stage.addChild(bgContainer, uiContainer)と順に追加すればUIコンテナの方が常に前面に表示されます。個々のオブジェクトの順序は各コンテナ内で管理しつつ、コンテナ自体の順序で大まかなレイヤーを実現できます。

手動での順序入れ替え

一時的に特定オブジェクトを最前面に出したい場合、parent.setChildIndex(obj, parent.children.length-1)で親コンテナ内の末尾に移動させる方法があります。また一度removeChildしてからaddChildし直すとその時点で末尾に追加されます。シンプルですが即座に順序変更したい場合に使えます。

自動ソートとzIndex

前述の通り、PixiJSはcontainer.sortableChildren = true設定でzIndexプロパティに基づく自動ソートを行います。例えばsprite.zIndex = 10;などと値を設定し、同一コンテナ内で値の小さい順に背面、大きいほど前面になります。これを利用すると、例えばゲーム内の高さ座標に応じてzIndexを動的に変えることで「奥行きによる前後関係」を表現する、といったことも可能です。ソートコストには注意しつつ、動的シーンでは重宝するテクニックです。

Pixi Layersプラグイン

PixiJSにはv7まで外部プラグインとしてpixi-layersが提供されており、複雑なレイヤー順を便利に管理できました。v8ではこの機能のコア統合がロードマップにありますが、2025年現在まだ完全統合されていないようです(記事執筆時点)。必要に応じてpixi-layersプラグインを使うか、上記コンテナ+zIndex組み合わせで対応すると良いでしょう。

パフォーマンス最適化テクニック

PixiJSはデフォルトでも十分高速ですが、大量のスプライトや重いエフェクトを扱う際には工夫が必要です。以下に代表的な最適化テクニックを挙げます。

スプライトシートの活用

複数の画像をまとめたスプライトシート(テクスチャアトラス)を使うことで、描画時のテクスチャ切り替え回数(ドローコール)を削減できます。WebGLでは異なるテクスチャ間の描画はバッチ分割を引き起こしパフォーマンス低下要因となります。PixiJSはハードウェアにもよりますが最大16種類のテクスチャを一度にバッチ描画でき、それを超えると別バッチになります。できるだけ多くのスプライトが同一テクスチャから描画されるよう、キャラクターやUIの画像はまとめて一枚のシートにしておくと良いでしょう。

ParticleContainerの利用

非常に多数(数万以上)のスプライトを扱う場合、PixiJS v8で刷新されたParticleContainerを使うことで圧倒的な速度向上が得られます。通常のContainerは柔軟ですがオーバーヘッドもあります。ParticleContainerは一部機能を制限した軽量な描画専用コンテナで、v8では各要素をSpriteではなく専用のParticleオブジェクトで管理する設計に変わりました。その結果、v7比で3倍以上高速になり、例えば100万個のパーティクルスプライトも60FPSで描画可能だったという報告もあります。大量の小オブジェクト(パーティクルや星空の星など)を描画する際は、多少の機能制限(個別の回転やアルファを頻繁に変えるのは苦手など)はありますがこのコンテナを検討すべきです。

オブジェクトのオフスクリーン判定(カリング)

画面外にあるオブジェクトは表示する必要がないため、描画処理から除外することで負荷を減らせます。PixiJS v8ではカリング(視界外判定)機能がコアに統合され、container.cullable = trueと設定すると指定領域外の子を自動でスキップできます。ただしカリング処理自体にもコストがあるため、ケースバイケースで有効化すると良いでしょう(一般にGPU負荷が高い状況では有効、CPU負荷が高い場合は逆効果とされています)。手動で各オブジェクトの可視/非可視を切り替える方法でも構いません。重要なのは「描画しなくて良いものは描画しない」という原則です。

キャッシュと再利用

動かない背景や複雑なベクター図形などは、一度テクスチャに描き起こしてSpriteとして扱うと再レンダリングを省けます(cacheAsBitmapの利用)。テクスチャやスプライト、グラフィックスも使い回せるものはプールして再利用することで、オブジェクト生成・GCコストを下げられます。またフィルター適用範囲をfilterAreaで限定したり、頻繁に変更しないGraphicsはそのままにしておく等、余計な計算を減らす工夫も有効です。

不要な処理のオフ

PixiJSは多機能ゆえにデフォルトでオンな機能もあります。例えばインタラクションを使わないシーンではapp.stage.eventMode = 'none'としてヒットテストを完全に無効化したり、特定のコンテナで子のイベント不要ならcontainer.eventMode = 'passive'(子は受けるが自分は受けない)にするなど設定できます。これらは地味ですが、積み重ねると負荷軽減に寄与します。
以上のようなテクニックを組み合わせることで、PixiJSは大量のスプライトを扱うゲームやインタラクティブ作品でも60FPSの滑らかな描画を維持できます。特にv8では基本性能が底上げされているため、従来諦めていた大規模処理も可能になっているでしょう。パフォーマンスチューニングの際は公式の「Performance Tips」ガイドも参考に、ボトルネックに応じた対策を講じてみてください。

PixiJSとLottieアニメーションの連携:After Effects制作アニメをPixiJSで表示する方法

近年Webでのアニメーション手法としてLottieが注目されています。LottieはAdobe After Effectsで制作したアニメーションをJSONファイルにエクスポートし、Web上で再生できる仕組みです。PixiJSと組み合わせれば、デザイナーが作成した洗練されたモーショングラフィックスを、PixiJSのシーンに組み込んで表示することが可能です。本節ではPixiJSでLottieアニメーションを表示する方法を解説します。

After EffectsのアニメをJSON化

Lottieでは、AEのアニメーションをプラグイン(BodymovinやLottieFilesプラグイン)でエクスポートし、図形や動きの情報をJSONフォーマットにします。このJSONと必要に応じ画像アセットを用いることで、コードで再現可能なアニメーションデータとなります。

Lottieライブラリ

エクスポートしたJSONを再生するために、公式のlottie-webライブラリがあります。これを使うとCanvasやSVG、<canvas>上にAE同等のアニメーションを再現できます。今回焦点のPixiJS連携では、このデータをPixiJS上で描画するアプローチを取ります。

PixiJSでLottieを表示する方法

PixiJS単体ではLottie JSONを解釈する機能はありませんが、便利なプラグインが有志によって提供されています。その一つが「pixi-lottie」というライブラリです。@qva/pixi-lottieというパッケージ名でnpm提供されており、これを使うとLottieのJSONデータをまるでPixiのSprite画像かのように扱うことができます。

pixi-lottieの特徴

- JSONデータと連携してPixiJS上にSpriteとして配置できる。 - 幅・高さのスケール調整や再生速度(speed)などをプロパティで指定可能。 - 再生制御も簡単で、play()やstop()メソッドでアニメーションの開始・停止、ループ設定などができる。
実際の使用方法は以下のようになります。
import { LottieSprite } from "@qva/pixi-lottie";
// Lottie用のSpriteを生成
const anim = new LottieSprite({
asset: "path/to/animation.json", // Lottie JSONファイルへのパス
autoplay: true, // 自動再生する
loop: true // ループ再生する
});
app.stage.addChild(anim);
anim.x = 400;
anim.y = 300;

たったこれだけで、指定したLottieアニメーションJSONが読み込まれ、PixiJSのステージ上に表示されます。LottieSpriteは内部でlottie-webを利用して描画用のテクスチャを生成していると考えられますが、開発者は意識する必要はありません。通常のスプライト同様にx,y座標やscale、rotationを操作できますし、他のPixiオブジェクトと一緒にコンテナに入れてアニメーションさせることも可能です。
上記コードではautoplay:trueとしているため、自動的に再生が開始しループします。必要に応じてanim.stop()やanim.play()で制御したり、anim.speed = 2.0で倍速再生するなどの調整もできます。まさにAfterEffects製アニメを一つのSpriteとして扱える感覚です。
※注意点:pixi-lottieプラグインを使用する際は、そのREADMEやドキュメントも参照してください。大きなJSONだと読み込み時間がかかったり、PixiJSのバージョン互換性などもあるかもしれません。またプラグイン導入が難しい場合、代替としてlottie-webでCanvasに描画し、そのCanvasをPixiのTextureとして取り込む方法も考えられます。しかし手軽さではpixi-lottieのような専用プラグインに軍配が上がります。
このようにPixiJSとLottieを連携させれば、解像度非依存のベクターアニメーションをゲームやサイト上で活用できます。デザインとコードを分離しつつ高度な演出を実現できるため、エンジニアにとっても強力な手段となるでしょう。

PixiJS v8でよくあるハマりポイントとトラブルシューティング:エラー対処法や開発中の落とし穴を解説

最後に、PixiJS v8を使う上で開発者が陥りがちなハマりどころや、困ったときの対処法についてまとめます。大型アップデートだけにv7以前との違いも多く、いくつか注意点があります。

よくあるハマりポイント

app.init()の呼び忘れ

v8で最も多い初歩的ミスがこれです。Applicationを生成しただけでは描画が開始されず、非同期初期化処理を待つ必要があります。await app.init()または.init().then(...)を実行せずにaddChildなどしても何も表示されません。「画面が真っ黒」「Pixiが動かない」と感じたら、まずinit()の呼び出しを確認してください。なお、Applicationのコンストラクタ引数にオプションを渡すコードを書いていた場合、それもv8では効果がなくinitに移行した点に注意です。

イベント周りの変更

既存ユーザにはイベントシステムの変更も混乱ポイントです。具体的にはinteractive = trueやbuttonModeといった旧プロパティがv8では非推奨となり、eventModeへと置き換えられました。またpointertapなど統一ポインタイベントが追加された反面、従来の右クリックイベントの扱い方が変わるなど微細な違いがあります。移行時は公式のEventsガイドを読み、使い方を合わせましょう。

クラスや機能の廃止

PixiJS v8では内部構造の整理のために一部クラスが廃止・統合されています。例えばBaseTextureクラスが削除され、代わりにTextureSourceという概念に一本化されました。通常のSprite利用程度では意識しなくてよい変更ですが、低レベルでテクスチャ管理していた場合はコード修正が必要です。またプラグインによってはv8未対応で動作しないものがあります。PixiJS公式のサブライブラリ(PixiJS SoundやFilters等)は統合・対応済みですが、React用ラッパーやSpine用ランタイムなどはv8版が出るまで待つ必要がありました(※執筆時点ではReact, Spineもv8対応済の模様)。エラーが出た場合、そのクラスやプラグインがv8対応しているかをまず確認してください。

パフォーマンス最適化に関する勘違い

「v8にすれば何も考えなくても速い」わけではありません。確かに基礎性能は上がっていますが、前章で触れたようなベストプラクティス(バッチ考慮、適切なコンテナ利用など)は依然重要です。逆に「これまでボトルネックだった部分がv8で解消されている」ケースもありえます。例えばParticleContainerの仕様変更で旧コードがそのままでは動かないが、書き換えれば飛躍的に性能が上がる、といったことがあります。移行時は古い最適化や回避策を一度見直し、不要になった処理はシンプルにすることもトラブル防止につながります。

ブラウザ環境による違い

WebGPU対応とはいえ、2025年現在まだすべてのユーザ環境でWebGPUが使えるわけではありません(Chrome/Edgeの一部とSafariプレビュー版程度)。PixiJSは対応環境では自動的にWebGPUを使いますが、ブラウザによっては警告や初期化に時間がかかる場合もあります。特にモバイルや旧端末では引き続きWebGLになるため、WebGPU前提のコードを書かないようにしましょう(例えばWebGPU専用のシェーダー機能等にはまだ手を出さないほうが無難です)。WebGPU未対応環境では内部的にWebGLにフォールバックします。もし「WebGPU」を明示的に使いたい/使いたくない場合は、app.init({ preferHybrid: false })等オプションで調整もできますが、通常はauto検出に任せて問題ありません。

トラブルシューティングのコツ

PixiJSでエラーや挙動不良に遭遇した際は、まずデベロッパーコンソールのログを確認しましょう。PixiJS本体やプラグインは比較的親切なエラーメッセージを出すことがあります。例えば「XXX is not a function」のようなエラーなら、廃止されたメソッドを呼んでいないか疑ってみます。また公式ドキュメントのMigration Guideにはv7からの変更点が網羅されているので、移行に詰まったら目を通すと解決策が書いてあることが多いです。
さらに、PixiJSはオープンソースかつコミュニティも活発なため、フォーラムやGitHub Issues、Discordで過去に同様の問題が報告・解決されていないか検索するのも有効です。英語になりますが「PixiJS v8 [キーワード] error」等で検索すると解決策が見つかる場合があります。特にv8リリース直後は多くのQAが飛び交ったので、有用な情報が蓄積されています。
最後に、公式Examplesやテンプレートプロジェクトで正常動作するか試すのも手です。PixiJS公式サイトには様々なサンプルコードがあり、自分の環境でそれらが動くか確認することで、問題がコードにあるのか環境にあるのか切り分けられます。公式のnpm create pixi.js@latestでプロジェクトを作成してみて正常に表示されれば、設定やコードの問題ということになります。

資料請求

RELATED POSTS 関連記事