渲染图层
🌐 Render Layers
PixiJS 层 API 提供了一种强大的方式来独立控制对象的 渲染顺序,而不依赖于场景图中的 逻辑父子关系。使用 RenderLayers,你可以将对象的变换方式(通过它们的逻辑父对象)与它们在屏幕上的视觉绘制方式分离开来。
🌐 The PixiJS Layer API provides a powerful way to control the rendering order of objects independently of their logical parent-child relationships in the scene graph. With RenderLayers, you can decouple how objects are transformed (via their logical parent) from how they are visually drawn on the screen.
使用 RenderLayers 可以确保这些元素在视觉上被优先显示,同时保持逻辑上的父子关系。示例包括:
🌐 Using RenderLayers ensures these elements are visually prioritized while maintaining logical parent-child relationships. Examples include:
- 带有生命条的角色:确保生命条始终显示在世界之上,即使角色移动到对象后面。
- 像得分计数器或通知这样的界面元素:无论游戏世界多么复杂,都要保持可见。
- 在教程中高亮元素:想象一个教程,你需要将大多数游戏元素向后推,同时高亮特定对象。RenderLayers 可以在视觉上将它们分开。被突出的对象可以放置在前景层中,以在推后层之上渲染。
本指南解释了关键概念,提供了实际示例,并强调了常见的陷阱,以帮助你有效地使用 Layer API。
🌐 This guide explains the key concepts, provides practical examples, and highlights common gotchas to help you use the Layer API effectively.
关键概念
🌐 Key Concepts
- 独立渲染顺序:
- RenderLayers 允许独立于逻辑层次结构控制绘制顺序,确保对象按所需顺序渲染。
- 逻辑育儿保持完整:
- 即使附加到 RenderLayers,对象也会从其逻辑父级保持变换(例如,位置、比例、旋转)。
- 显式对象管理:
- 对象从场景图或图层中移除后必须手动重新分配到图层,以确保对渲染进行精心控制。
- 动态排序:
- 在图层内,可以使用
zIndex和sortChildren动态重新排序对象,以实现对渲染顺序的精细控制。
- 在图层内,可以使用
基础 API 使用
🌐 Basic API Usage
首先让我们创建两个我们想要渲染的项目,红色人和蓝色人。
🌐 First lets create two items that we want to render, red guy and blue guy.
const redGuy = new PIXI.Sprite('red guy');
redGuy.tint = 0xff0000;
const blueGuy = new PIXI.Sprite('blue guy');
blueGuy.tint = 0x0000ff;
stage.addChild(redGuy, blueGuy);
现在我们知道红色的人会先被渲染,然后是蓝色的人。在这个简单的例子中,你可以通过仅排序红色和蓝色人物的 zIndex 来帮助重新排序。
🌐 Now we know that red guy will be rendered first, then blue guy. Now in this simple example you could get away with just sorting the zIndex of the red guy and blue guy to help reorder.
但这是一个关于渲染层的指南,所以让我们创建其中一个。
🌐 But this is a guide about render layers, so lets create one of those.
使用 renderLayer.attach 将对象分配到一个图层。这会覆盖其逻辑父对象定义的默认渲染顺序。
🌐 Use renderLayer.attach to assign an object to a layer. This overrides the object’s default render order defined by its logical parent.
// a layer..
const layer = new RenderLayer();
stage.addChild(layer);
layer.attach(redGuy);
所以现在我们的场景图顺序是:
🌐 So now our scene graph order is:
|- stage
|-- redGuy
|-- blueGuy
|-- layer
我们的渲染顺序是:
🌐 And our render order is:
|- stage
|-- blueGuy
|-- layer
|-- redGuy
这是因为该图层现在是舞台中的最后一个子项。由于红色角色附加在该图层上,它将在图层在场景图中的位置进行渲染。然而,它在场景层次结构中逻辑上仍然保持在同一个位置。
🌐 This happens because the layer is now the last child in the stage. Since the red guy is attached to the layer, it will be rendered at the layer's position in the scene graph. However, it still logically remains in the same place in the scene hierarchy.
3. 从图层中移除对象
🌐 3. Removing Objects from a Layer
现在让我们将红色的家伙从图层中移除。要阻止一个对象在图层中被渲染,使用 removeFromLayer。一旦从图层中移除,它仍然会在场景图中,并且会按照场景图的顺序渲染。
🌐 Now let's remove the red guy from the layer. To stop an object from being rendered in a layer, use removeFromLayer. Once removed from the layer, its still going to be in the scene graph, and will be rendered in its scene graph order.
layer.detach(redGuy); // Stop rendering the rect via the layer
将对象从其逻辑父对象(removeChild)中移除会自动将其从图层中移除。
🌐 Removing an object from its logical parent (removeChild) automatically removes it from the layer.
stage.removeChild(redGuy); // if the red guy was removed from the stage, it will also be removed from the layer
但是,如果你从舞台上移除红色人,然后将其添加回舞台,它将不会再次添加到图层中。
🌐 However, if you remove the red guy from the stage and then add it back to the stage, it will not be added to the layer again.
// add red guy to his original position
stage.addChildAt(redGuy, 0);
你需要自己将其重新连接到层。
🌐 You will need to reattach it to the layer yourself.
layer.attach(redGuy); // re attach it to the layer again!
这可能看起来很麻烦,但实际上是件好事。这意味着你可以完全控制对象的渲染顺序,而且可以随时更改。它也意味着你不会不小心把对象添加到一个容器中,然后它自动重新附加到可能仍然存在或已经不存在的层上——这会非常令人困惑,并导致一些非常难以调试的错误!
🌐 This may seem like a pain, but it's actually a good thing. It means that you have full control over the render order of the object, and you can change it at any time. It also means you can't accidentally add an object to a container and have it automatically re-attach to a layer that may or may not still be around - it would be quite confusing and lead to some very hard to debug bugs!
5. 场景图中的图层位置
🌐 5. Layer Position in Scene Graph
图层在场景图中的位置决定了其相对于其他图层和对象的渲染优先级。
🌐 The layer’s position in the scene graph determines its render priority relative to other layers and objects.
// reparent the layer to render first in the stage
stage.addChildAt(layer, 0);
🌐 !alt text
完整示例
🌐 Complete Example
这是一个真实的例子,展示了如何使用 RenderLayers 将 ap 播放器 ui 设置在世界之巅。
🌐 Here’s a real-world example that shows how to use RenderLayers to set ap player ui on top of the world.
陷阱和注意事项
🌐 Gotchas and Things to Watch Out For
-
手动重新分配:
- 当一个对象被重新添加到逻辑父级时,它不会自动与其之前的图层重新关联。始终显式地将对象重新分配到图层。
-
嵌套子元素:
- 如果你移除一个父容器,它的所有子元素都会自动从层中移除。在处理复杂的层级结构时要小心。
-
图层内排序:
- 图层中的对象可以使用它们的
zIndex属性动态排序。这对于对渲染顺序进行精细控制非常有用。
rect.zIndex = 10; // Higher values render later
layer.sortableChildren = true; // Enable sorting
layer.sortRenderLayerChildren(); // Apply the sorting - 图层中的对象可以使用它们的
-
图层重叠:
- 如果多个图层重叠,它们在场景图中的顺序决定渲染优先级。确保图层逻辑与你期望的视觉输出一致。
最佳实践
🌐 Best Practices
- 战略性分组:尽量减少层数以优化性能。
- 用于视觉清晰:为需要明确控制渲染顺序的对象保留图层。
- 测试动态更改:验证在你的特定场景设置中,向图层添加、移除或重新分配对象的行为是否符合预期。
通过理解和有效利用 RenderLayers,你可以精确控制场景的视觉渲染,同时保持干净、合乎逻辑的层次结构。
🌐 By understanding and leveraging RenderLayers effectively, you can achieve precise control over your scene's visual presentation while maintaining a clean and logical hierarchy.