pixijs-scene-core-concepts について
pixijs-scene-core-conceptsは、PixiJS v8開発者向けにシーングラフの基本モデルを説明し、各概念の詳細資料を案内するスキルです。コンテナーとリーフの役割、変換、描画順、カリング、マスキングを扱います。
主な機能
- 01シーングラフとノードの役割
- 02変換と座標空間
- 03描画順とレイヤー
- 04レンダーグループとカリング
- 05マスキング、可視性、破棄
活用シーン
- 01表示オブジェクトの階層設計
- 02コンテナー、レンダーレイヤー、レンダーグループの選択
- 03画面外カリングとマスクの設定
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ pixijs/ pixijs-skills --skill pixijs-scene-core-conceptsインストール後、Claude Code で/pixijs-scene-core-conceptsを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/constructor-options.mdcontainer-hierarchy.mdlayers.mdmasking.mdrender-groups.mdscene-management.mdtransforms.md詳細
このスキルは、すべての pixijs-scene-* リーフスキルが参照する共通のメンタルモデルです。PixiJS v8 のシーングラフとは何か、Container とリーフの違い、各概念の説明箇所を解説します。個々の API を詳しく掘り下げるのではなく、要素の概要を示し、詳細を説明するスキルやリファレンスファイルを案内します。
クイックスタート
const world = new Container({ isRenderGroup: true });
app.stage.addChild(world);
const hero = new Container({ label: "hero" });
hero.addChild(new Sprite(bodyTexture));
hero.addChild(new Sprite(faceTexture));
world.addChild(hero);
const mask = new Graphics().rect(0, 0, 800, 600).fill(0xffffff);
world.mask = mask;
world.addChild(mask);
hero.position.set(world.width / 2, world.height / 2);
関連スキル: pixijs-scene-container(Container API の詳細)、リーフスキル(pixijs-scene-sprite、pixijs-scene-graphics、pixijs-scene-text、pixijs-scene-mesh、pixijs-scene-particle-container、pixijs-scene-dom-container、pixijs-scene-gif)、pixijs-events(ヒットテストではシーングラフをたどります)、pixijs-performance(キャッシュ、カリング、レンダーグループ)、pixijs-math(Matrix、toGlobal/toLocal の詳細)。
コアコンセプト
シーングラフとは
PixiJS のシーングラフは、app.stage をルートとするディスプレイオブジェクトのツリーです。各ノードには親、親に対する位置・スケール・回転・ピボット・スキューからなるトランスフォーム、そして任意のビジュアル状態(アルファ、色調、blendMode、表示状態)があります。各フレームでレンダラーはツリーをたどり、トランスフォームとビジュアル状態をワールド座標に合成し、画面外の要素をカリングして、描画呼び出しを発行します。シーングラフはレイアウトモデルであると同時に描画順序でもあり、先にある兄弟要素が後にある兄弟要素の背後に描画されます。
v8 のすべてのディスプレイオブジェクトは Container のサブクラスです。以前のバージョンにあった DisplayObject は削除されました。
Container とリーフの違い(重要)
ツリー内の役割は 2 種類あります。
- コンテナー: 子要素を保持するノードです。他のノードをグループ化、配置、またはトランスフォームするノードには、
Container(またはRenderLayer)を使用します。 - リーフ: 描画を行い、子要素を持たないノードです。リーフには、
Sprite、Graphics、Text、Mesh、ParticleContainerのParticle、DOMContainer、またはGifSpriteを使用します。
PixiJS v8 では、リーフに子要素を持たせてはいけません。Sprite/Graphics/Text/Mesh に子要素を追加すると非推奨警告がログに出力され、今後はエラーになる予定です。ルールは次のとおりです。子要素が必要なノードには Container を使い、リーフのシーンオブジェクトの中に子要素をネストしないでください。 リーフを他のリーフとグループ化する必要がある場合は、それらを Container で包んでください。
この違いが、pixijs-scene-* スキルがこのように分かれている理由です。pixijs-scene-container ではグループ化ノードを扱い、各リーフのスキルではそれぞれの描画動作に焦点を当てています。
トランスフォームと座標空間
各コンテナーは、position、scale、rotation、pivot、skew から Matrix の localTransform を合成します。レンダラーは親のローカルトランスフォームを掛け合わせ、ローカル座標の点をシーンルートの座標空間に変換する worldTransform(レンダーグループが階層内にある場合は groupTransform も)を生成します。座標空間を変換するには toGlobal(point) と toLocal(point, from?) を、オブジェクトのワールド座標での位置を取得するには getGlobalPosition() を使用します。Matrix の詳細は pixijs-math、トランスフォームのセッターと toLocal/toGlobal は pixijs-scene-container を参照してください。
描画順序と明示的な z オーダー
子要素は配列の順序で描画されます。インデックス 0 が最初、最後のインデックスが最後に描画されます。1 つのコンテナー内で明示的な z オーダーを設定するには、sortableChildren = true にし、子要素に zIndex の値を割り当てます。論理階層と描画順序を切り離す場合(例:キャラクターの親はゲームワールドだが、UI レイヤーに描画する場合)は、RenderLayer を使用します。ソート可能な子要素と RenderLayer のどちらを選ぶべきかなど、詳しくは references/scene-management.md を参照してください。
レンダーグループ
コンテナーに isRenderGroup: true を設定する(または container.enableRenderGroup() を呼び出す)と、PixiJS は各フレームに CPU 上で子孫すべてのワールドトランスフォームを再計算する代わりに、そのコンテナーのトランスフォームを単一の行列として GPU 上で適用します。ワールド、UI レイヤー、視差ストリップなど、大きく安定したサブツリーにレンダーグループを使用してください。詳しくは references/scene-management.md を参照してください。
カリング
cullable = true と cullArea: Rectangle を設定すると、CullerPlugin(または任意のカリングパス)は、可視領域の外にあるオブジェクトのレンダリングをスキップします。cullableChildren = false を設定すると、子要素が常に画面内にあるサブツリーの再帰的なカリングを停止します。カリングはパフォーマンスに関するトピックです。トレードオフについては、pixijs-performance と references/scene-management.md を参照してください。
マスキング
container.mask に別の表示オブジェクトを設定すると、そのオブジェクトのレンダリングをクリップできます。PixiJS はマスクの種類を自動的に選択します。Graphics または Container のマスクはステンシルバッファーを使用し、Sprite のマスクはアルファフィルターを使用します。また、数値を指定すると ColorMask が選択されます。4 種類すべてのマスク(AlphaMask、StencilMask、ScissorMask、ColorMask)については、references/masking.md で説明しています。
可視性、アルファ、不透明度、ブレンドモード
visible = false はレンダリングと変換の更新をスキップします。renderable = false はレンダリングをスキップしますが、変換の更新は続行します(ヒットテストや境界のクエリを最新の状態に保つ必要がある場合に使用します)。alpha と tint はサブツリー全体に適用されます。blendMode は、このコンテナーの描画命令を描画先にすでに存在する内容とどのように合成するかを制御します。ブレンドモードの一覧は pixijs-blend-modes を、ノードごとの状態については pixijs-scene-container を参照してください。
破棄の動作
container.destroy() は単一のノードのリンクを解除します。container.destroy({ children: true }) はサブツリー全体を再帰的に破棄します。ブランチを削除する場合は、必ずこちらを使用してください。さらに、texture: true と textureSource: true を指定すると、リーフが所有する GPU リソースも解放されます。cacheAsTexture が有効な場合は、破棄する前に無効にしてください。シグネチャ全体については pixijs-scene-container に記載されています。
ライフサイクルイベント
コンテナーは階層や可視性の変更に応じてイベントを発行します。親では childAdded / childRemoved、子では added / removed が発行され、コンテナー自体では visibleChanged と destroyed が発行されます。リアクティブな UI の更新やリソース管理の設定に役立ちます。詳細は references/container-hierarchy.md を参照してください。
リーフの比較:各スキルがどのオブジェクトを扱うか
| リーフ | 主な用途 | スキル |
|---|---|---|
Sprite | テクスチャを位置に描画します(サイズ変更可能な UI パネル用の NineSliceSprite や、背景を繰り返す TilingSprite などのバリアントがあります)。 | pixijs-scene-sprite |
Text / BitmapText / HTMLText / SplitText / SplitBitmapText | テキストを描画します。汎用用途の Canvas ベースの Text、大量のテキストを低コストで描画する BitmapText、リッチな HTML/CSS レイアウト用の HTMLText、文字単位のアニメーション用の分割バリアントがあります。 | pixijs-scene-text |
Graphics | ベクター描画:図形、線、パス、塗りつぶし、ストローク。GraphicsContext を基盤とします。 | pixijs-scene-graphics |
Mesh / MeshSimple / MeshPlane / MeshRope / PerspectiveMesh | シェーダーまたはテクスチャを使ったカスタムジオメトリです。テクスチャ付きでパスに沿うリボンには MeshRope、2D のパースペクティブには PerspectiveMesh を使用します。 | pixijs-scene-mesh |
ParticleContainer + Particle | 制限されたトランスフォームセットを持つ軽量なスプライトを数千個使用し、高スループットのパーティクルエフェクトを実現します。 | pixijs-scene-particle-container |
DOMContainer | シーングラフ内の位置に HTML 要素を描画します(入力欄、iframe、アクセシビリティオーバーレイなどに便利です)。 | pixijs-scene-dom-container |
GifSprite | ディスプレイオブジェクトとしてアニメーション GIF を再生します。pixi.js/gif が必要です。 | pixijs-scene-gif |
Container 自体は pixijs-scene-container で扱います。各リーフがその内部に配置されるノードです。
どれを使うか(簡単な判断基準)
- 「いくつかのディスプレイオブジェクトをグループ化して変形したい」→
Container。pixijs-scene-containerを参照してください。 - 「テクスチャを描画したい」→
Sprite。pixijs-scene-spriteを参照してください。 - 「ベクター図形やパスを描画したい」→
Graphics。pixijs-scene-graphicsを参照してください。 - 「テキストを描画したい」→
Text/BitmapText/HTMLText。pixijs-scene-textを参照してください。 - 「低コストのスプライトを数千個使いたい」→
ParticleContainer。pixijs-scene-particle-containerを参照してください。 - 「カスタムジオメトリのメッシュ、または変形したスプライトを使いたい」→
Meshまたはそのバリアント。pixijs-scene-meshを参照してください。 - 「サブツリーをクリップしたい」→
.maskを設定します。references/masking.mdを参照してください。 - 「描画順序を切り離したい」→
RenderLayer。references/scene-management.mdを参照してください。 - 「大きく安定したサブツリーに GPU レベルのトランスフォームを適用したい」→
isRenderGroup: true。references/scene-management.mdを参照してください。 - 「画面外の描画をスキップしたい」→
cullable = true+CullerPlugin。pixijs-performanceを参照してください。
参考資料
- references/constructor-options.md:すべての
Container派生ノードが継承する約30個のフィールド(変換、表示、階層、並べ替え、レイアウト、エフェクト、コールバック)について、デフォルト値、型、1行ずつ代入するのが適切な場面を説明します。すべてのリーフスキルに共通するリファレンスです。 - references/container-hierarchy.md:子の追加/削除/入れ替え、変換を保持した再親設定、ラベルによるナビゲーション、サブツリーの破棄。
- references/transforms.md:位置、スケール、回転、ピボット、原点、スキュー、toGlobal/toLocal、3つの行列(ローカル/グループ/ワールド)、境界。
- references/masking.md:AlphaMask、StencilMask、ScissorMask、ColorMask、逆マスキング、コスト比較。
- references/layers.md:
RenderLayer、アタッチ/デタッチ、ソート済みレイヤー、レイヤーと論理上の親の分離。 - references/render-groups.md:
isRenderGroup、GPU レベルの変換、使用する場面、render-groups とcacheAsTextureの比較。 - references/scene-management.md:統合的な概要。render groups、
RenderLayer、カリング、zIndex によるソート、boundsArea。
よくある間違い
[CRITICAL] リーフ表示オブジェクトに子を追加する
誤り:
const sprite = new Sprite(texture);
sprite.addChild(new Graphics().rect(0, 0, 10, 10).fill(0xff0000));
正しい例:
const group = new Container();
group.addChild(new Sprite(texture));
group.addChild(new Graphics().rect(0, 0, 10, 10).fill(0xff0000));
v8 のリーフ(Sprite、Graphics、Text、Mesh、ParticleContainer、DOMContainer、GifSprite)は技術的には Container を継承していますが、子を持たせるべきではありません。リーフに子を追加すると、描画動作が未定義になります。グループ化が必要な場合は、リーフを Container でラップしてください。
[CRITICAL] DisplayObject を参照する
誤り:
import { DisplayObject } from "pixi.js"; // no such export in v8
function moveNode(node: DisplayObject) {
node.x += 1;
}
正しい例:
import { Container } from "pixi.js";
function moveNode(node: Container) {
node.x += 1;
}
v8 では DisplayObject は削除されました。Sprite、Graphics、Text、Mesh を含め、すべての表示オブジェクトが Container のサブクラスになりました。基底型には Container を使用してください。
[HIGH] 大規模な静的サブツリーで isRenderGroup を設定し忘れる
誤り:
const world = new Container();
for (let i = 0; i < 5000; i++) {
world.addChild(new Sprite(texture));
}
app.stage.addChild(world);
正しい例:
const world = new Container({ isRenderGroup: true });
for (let i = 0; i < 5000; i++) {
world.addChild(new Sprite(texture));
}
app.stage.addChild(world);
isRenderGroup: true がない場合、レンダラーは毎フレーム、各子の変換を親に対して再合成します。サブツリーをレンダーグループとして指定すると、子に変更があるまで変換と描画状態がキャッシュされます。これは、大規模またはほとんど静的なツリーでは不可欠です。
[HIGH] child.x をワールド座標として扱う
誤り:
const enemy = new Container();
enemy.x = 500;
world.addChild(enemy);
world.x = 200;
console.log(enemy.x); // 500 (local), not 700 (world)
正しい例:
const worldPos = enemy.toGlobal({ x: 0, y: 0 });
console.log(worldPos.x); // 700
Container.x/y/scale/rotation は親に対するローカル値です。ワールド座標を計算するには toGlobal(point) を、ワールド空間におけるコンテナの原点を取得するには getGlobalPosition() を使用してください。ワールド変換は単純な x/y の組として公開されていません。
[MEDIUM] zIndex を設定せずに sortableChildren を使う
誤り:
const layer = new Container();
layer.sortableChildren = true;
layer.addChild(bg); // no zIndex
layer.addChild(mid); // no zIndex
layer.addChild(fg); // no zIndex
// order is unchanged — all zIndex default to 0
正しい例:
const layer = new Container();
layer.sortableChildren = true;
bg.zIndex = 0;
mid.zIndex = 10;
fg.zIndex = 20;
layer.addChild(bg, mid, fg);
sortableChildren は描画前に子を zIndex で並べ替えますが、子に異なる zIndex 値が設定されている場合にのみ効果があります。親のフラグだけを設定しても、目に見える変化はありません。
ツール
PixiJS Devtools Chrome extension を使うと、実行中のシーングラフをリアルタイムで調査・操作できます。複雑なレイアウトや描画順のデバッグを行う場合は、インストールしてください。