mcpField
P
pixijs-scene-core-concepts

pixijs-scene-core-concepts

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

关于 pixijs-scene-core-concepts

pixijs-scene-core-concepts 为 PixiJS v8 开发者梳理场景图的共同概念,并指向各对象的深入资料。它说明容器与叶节点的区别,以及变换、渲染顺序、剔除和遮罩等机制。

主要功能

  1. 01场景图与节点角色
  2. 02变换与坐标空间
  3. 03渲染顺序与图层
  4. 04渲染组与剔除
  5. 05遮罩、可见性与销毁

适用场景

  1. 01规划显示对象的层级结构
  2. 02选择分组、渲染层或渲染组
  3. 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.md
container-hierarchy.md
layers.md
masking.md
render-groups.md
scene-management.md
transforms.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 为根节点的显示对象树。每个节点都有一个父节点、一个相对于父节点的变换(位置、缩放、旋转、轴心、倾斜),以及可选的视觉状态(alpha、色调、混合模式、可见性)。每一帧,渲染器都会遍历这棵树,将变换和视觉状态逐级合成到世界空间,剔除屏幕外的内容,并发出绘制调用。场景图既是布局模型,也是渲染顺序:靠前的同级节点会绘制在靠后的同级节点后面。

在 v8 中,每个显示对象都是 Container 的子类。早期版本中的 DisplayObject 已被移除。

Container 与叶节点(重要)

树中的节点分为两种:

  • 容器: 可包含子节点的节点。对于任何用于分组、定位或变换其他节点的节点,都应使用 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 合成 localTransform(一个 Matrix)。渲染器会将父节点的局部变换相乘,生成 worldTransform(如果变换链中有渲染组,还会生成 groupTransform),将局部坐标映射到场景根节点空间。使用 toGlobal(point) 和 toLocal(point, from?) 在不同空间之间转换,并使用 getGlobalPosition() 获取此对象的世界位置。Matrix 的完整介绍见 pixijs-math;变换设置器以及 toLocal/toGlobal 见 pixijs-scene-container。

渲染顺序与显式 z 顺序

子节点按数组顺序渲染:索引为 0 的最先绘制,索引最大的最后绘制。要在单个容器中显式设置 z 顺序,请设置 sortableChildren = true,并为子节点赋予 zIndex 值。要让渲染顺序脱离逻辑层级(例如,角色的父节点属于游戏世界,但角色实际绘制在 UI 层),请使用 RenderLayer。包括何时优先选择可排序子节点而非 RenderLayer 在内的详细内容,见 references/scene-management.md。

渲染组

将容器标记为 isRenderGroup: true(或调用 container.enableRenderGroup()),即可让 PixiJS 在 GPU 上将其变换作为单个矩阵应用,而不是每帧都在 CPU 上重新计算其所有后代的世界变换。大型且稳定的子树(例如游戏世界、UI 层或视差条带)适合使用渲染组。详细内容见 references/scene-management.md。

剔除

cullable = true + cullArea: Rectangle 会告知 CullerPlugin(或任何剔除流程)跳过渲染可见区域之外的对象。对于子对象始终位于屏幕上的子树,cullableChildren = false 会停止递归剔除。剔除属于性能相关主题;pixijs-performance 和 references/scene-management.md 介绍了其中的权衡。

遮罩

将 container.mask 设置为另一个显示对象,即可裁剪其渲染内容。PixiJS 会自动选择遮罩类型:Graphics 或 Container 遮罩使用模板缓冲区,Sprite 遮罩使用 Alpha 滤镜,数字则会选择 ColorMask。references/masking.md 涵盖了全部四种遮罩类型(AlphaMask、StencilMask、ScissorMask、ColorMask)。

可见性、透明度、色调和混合模式

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 适用于大量且开销低的文本,HTMLText 适用于富 HTML/CSS 布局,分割变体适用于逐字符动画。pixijs-scene-text
Graphics矢量绘图:形状、线条、路径、填充和描边。由 GraphicsContext 提供支持。pixijs-scene-graphics
Mesh / MeshSimple / MeshPlane / MeshRope / PerspectiveMesh使用着色器或纹理创建自定义几何体。使用 MeshRope 创建沿路径延伸的纹理带,使用 PerspectiveMesh 实现 2D 透视效果。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 个字段(变换、显示、层级、排序、布局、效果、回调),包括默认值、类型,以及何时适合逐行赋值。所有叶子技能共用的参考资料。
  • references/container-hierarchy.md:添加/移除/交换子级、保留变换的重新挂接、标签导航、销毁子树。
  • references/transforms.md:位置、缩放、旋转、枢轴、原点、倾斜、toGlobal/toLocal、三个矩阵(局部/组/世界)、边界。
  • references/masking.md:AlphaMask、StencilMask、ScissorMask、ColorMask、反向遮罩、开销比较。
  • references/layers.md:RenderLayer、挂接/解除挂接、排序图层、图层与逻辑父级的拆分。
  • references/render-groups.md:isRenderGroup、GPU 级变换、适用场景、渲染组与 cacheAsTexture 的比较。
  • references/scene-management.md:综合概览;渲染组、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;
}

DisplayObject 已在 v8 中移除。现在所有显示对象(包括 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] 设置 sortableChildren,却未设置 zIndex

错误:

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 扩展程序可让你实时检查和操控正在运行的场景图。调试任何较复杂的布局或渲染顺序问题时,都应安装此扩展程序。

API 参考

评论

支持 Markdown