From cf8f5884bb92927f3849ef9f69333023d54c4f0c Mon Sep 17 00:00:00 2001 From: Mat Groves Date: Tue, 21 Jan 2025 15:22:56 +0000 Subject: [PATCH 1/4] add a render layer guide --- docs/guides/advanced/render-groups.md | 45 ------ docs/guides/advanced/render-layers.mdx | 195 +++++++++++++++++++++++++ 2 files changed, 195 insertions(+), 45 deletions(-) delete mode 100644 docs/guides/advanced/render-groups.md create mode 100644 docs/guides/advanced/render-layers.mdx diff --git a/docs/guides/advanced/render-groups.md b/docs/guides/advanced/render-groups.md deleted file mode 100644 index 9b0b96080..000000000 --- a/docs/guides/advanced/render-groups.md +++ /dev/null @@ -1,45 +0,0 @@ -# Render Groups - -## Understanding RenderGroups in PixiJS - -As you delve deeper into PixiJS, especially with version 8, you'll encounter a powerful feature known as RenderGroups. Think of RenderGroups as specialized containers within your scene graph that act like mini scene graphs themselves. Here's what you need to know to effectively use Render Groups in your projects: - -### What Are Render Groups? - -Render Groups are essentially containers that PixiJS treats as self-contained scene graphs. When you assign parts of your scene to a Render Group, you're telling PixiJS to manage these objects together as a unit. This management includes monitoring for changes and preparing a set of render instructions specifically for the group. This is a powerful tool for optimizing your rendering process. - -### Why Use Render Groups? - -The main advantage of using Render Groups lies in their optimization capabilities. They allow for certain calculations, like transformations (position, scale, rotation), tint, and alpha adjustments, to be offloaded to the GPU. This means that operations like moving or adjusting the Render Group can be done with minimal CPU impact, making your application more performance-efficient. - -In practice, you're utilizing Render Groups even without explicit awareness. The root element you pass to the render function in PixiJS is automatically converted into a RenderGroup as this is where its render instructions will be stored. Though you also have the option to explicitly create additional RenderGroups as needed to further optimize your project. - -This feature is particularly beneficial for: - -- **Static Content:** For content that doesn't change often, a Render Group can significantly reduce the computational load on the CPU. In this case static refers to the scene graph structure, not that actual values of the PixiJS elements inside it (eg position, scale of things). -- **Distinct Scene Parts:** You can separate your scene into logical parts, such as the game world and the HUD (Heads-Up Display). Each part can be optimized individually, leading to overall better performance. - -### Examples - -```ts -const myGameWorld = new Container({ - isRenderGroup:true -}) - -const myHud = new Container({ - isRenderGroup:true -}) - -scene.addChild(myGameWorld, myHud) - -renderer.render(scene) // this action will actually convert the scene to a render group under the hood -``` - -Check out the [container example](../../examples/basic/container). - -### Best Practices - -- **Don't Overuse:** While Render Groups are powerful, using too many can actually degrade performance. The goal is to find a balance that optimizes rendering without overwhelming the system with too many separate groups. Make sure to profile when using them. The majority of the time you won't need to use them at all! -- **Strategic Grouping:** Consider what parts of your scene change together and which parts remain static. Grouping dynamic elements separately from static elements can lead to performance gains. - -By understanding and utilizing Render Groups, you can take full advantage of PixiJS's rendering capabilities, making your applications smoother and more efficient. This feature represents a powerful tool in the optimization toolkit offered by PixiJS, enabling developers to create rich, interactive scenes that run smoothly across different devices. diff --git a/docs/guides/advanced/render-layers.mdx b/docs/guides/advanced/render-layers.mdx new file mode 100644 index 000000000..ddfa07324 --- /dev/null +++ b/docs/guides/advanced/render-layers.mdx @@ -0,0 +1,195 @@ +import { EmbeddedEditor } from "@site/src/components/Editor/EmbeddedEditor"; +import ThreePixiIndexFile from '!!raw-loader!../../examples/ordering/render-layer.js'; + +# Render Layers + +## PixiJS Layer API Guide + +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. + +Using RenderLayers ensures these elements are visually prioritized while maintaining logical parent-child relationships. Examples include: + +- A character with a health bar: Ensure the health bar always appears on top of the world, even if the character moves behind an object. + +- UI elements like score counters or notifications: Keep them visible regardless of the game world’s complexity. + +- Highlighting Elements in Tutorials: Imagine a tutorial where you need to push back most game elements while highlighting a specific object. RenderLayers can split these visually. The highlighted object can be placed in a foreground layer to be rendered above a push back layer. + +This guide explains the key concepts, provides practical examples, and highlights common gotchas to help you use the Layer API effectively. + +!--- inset char with clouds ---! + +--- + +### **Key Concepts** + + +1. **Independent Rendering Order**: + + - RenderLayers allow control of the draw order independently of the logical hierarchy, ensuring objects are rendered in the desired order. + +2. **Logical Parenting Stays Intact**: + + - Objects maintain transformations (e.g., position, scale, rotation) from their logical parent, even when attached to RenderLayers. + +3. **Explicit Object Management**: + + - Objects must be manually reassigned to a layer after being removed from the scene graph or layer, ensuring deliberate control over rendering. + +4. **Dynamic Sorting**: + + - Within layers, objects can be dynamically reordered using layerZIndex and sortChildren for fine-grained control of rendering order. + + + +--- + +### **Basic API Usage** + +First lets create two items that we want to render, red guy and blue guy. + +```typescript +const redGuy = new PIXI.Sprite('red guy'); +redGuy.tint = 0xff0000; + +const blueGuy = new PIXI.Sprite('blue guy'); +blueGuy.tint = 0x0000ff; + +stage.addChild(redGuy, blueGuy); +``` + +![alt text](image-1.png) + +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. + +Use `renderLayer.attach` to assign an object to a layer. This overrides the object’s default render order defined by its logical parent. + + +```typescript +// a layer.. +const layer = new RenderLayer(); +stage.addChild(layer); +layer.attach(redGuy); +``` +![alt text](image-2.png) + +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. Removing Objects from a Layer** + +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. + +```typescript + +layer.detach(redGuy); // Stop rendering the rect via the layer + +``` + +![alt text](image-1.png) + + +Removing an object from its logical parent (`removeChild`) automatically removes it from the layer. + + + +```typescript + +stage.removeChild(redGuy); // if the red guy was removed from the stage, it will also be removed from the layer + +``` +![alt text](image-3.png) + + +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. + +```typescript +// add red guy to his original position +stage.addChildAt(redGuy, 0); + +``` +![alt text](image-1.png) + +You will need to reattach it to the layer yourself. + +```typescript + +layer.attach(redGuy); // re attach it to the layer again! + +``` +![alt text](image-2.png) + +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. Layer Position in Scene Graph** + +The layer’s position in the scene graph determines its render priority relative to other layers and objects. + +```typescript + +// reparent the layer to render first in the stage +stage.addChildAt(layer, 0); + +``` +![alt text](image-1.png) +--- + +### **Complete Example** + +Here’s a real-world example that shows how to use RenderLayers to set ap player ui on top of the world. + +![will insert playground here](image-4.png) + + +
+ +--- + +### **Gotchas and Things to Watch Out For** + +1. **Manual Reassignment**: + - When an object is re-added to a logical parent, it does not automatically reassociate with its previous layer. Always reassign the object to the layer explicitly. + +2. **Nested Children**: + - If you remove a parent container, all its children are automatically removed from layers. Be cautious with complex hierarchies. + +3. **Sorting Within Layers**: + - Objects in a layer can be sorted dynamically using their `layerZIndex` property. This is useful for fine-grained control of render order. + + ```javascript + rect.layerZIndex = 10; // Higher values render later + layer.sortChildren(); // Apply the sorting + ``` + +4. **Layer Overlap**: + - If multiple layers overlap, their order in the scene graph determines the render priority. Ensure the layering logic aligns with your desired visual output. + +--- + +### **Best Practices** + +1. **Group Strategically**: Minimize the number of layers to optimize performance. +2. **Use for Visual Clarity**: Reserve layers for objects that need explicit control over render order. +3. **Test Dynamic Changes**: Verify that adding, removing, or reassigning objects to layers behaves as expected in your specific scene setup. + +By understanding and leveraging RenderLayers effectively, you can achieve precise control over your scene's visual presentation while maintaining a clean and logical hierarchy. + From e6045411862e6130294d63fef7fabb376fdf3757 Mon Sep 17 00:00:00 2001 From: Mat Groves Date: Tue, 21 Jan 2025 15:23:26 +0000 Subject: [PATCH 2/4] render layer --- docs/examples/ordering/render-layer.mdx | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 docs/examples/ordering/render-layer.mdx diff --git a/docs/examples/ordering/render-layer.mdx b/docs/examples/ordering/render-layer.mdx new file mode 100644 index 000000000..175e2e278 --- /dev/null +++ b/docs/examples/ordering/render-layer.mdx @@ -0,0 +1,11 @@ +--- +hide_table_of_contents: true +hide_edit_this_page: true +sidebar_position: 1 +custom_edit_url: null +title: Render Layer +--- +import { ExampleEditor } from "@site/src/components/Editor/ExampleEditor"; +import IndexFile from '!!raw-loader!./render-layer'; + + From c6ee884e3ba0cc6f67470a5a6af4f0ef4283c895 Mon Sep 17 00:00:00 2001 From: Mat Groves Date: Tue, 21 Jan 2025 15:28:10 +0000 Subject: [PATCH 3/4] side bars --- sidebars.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sidebars.js b/sidebars.js index 45996ae9b..98cb6d0ed 100644 --- a/sidebars.js +++ b/sidebars.js @@ -33,7 +33,7 @@ const sidebars = { type: 'category', label: 'Advanced', collapsed: true, - items: ['guides/advanced/render-groups', 'guides/advanced/cache-as-texture'], + items: ['guides/advanced/render-groups', 'guides/advanced/cache-as-texture', 'guides/advanced/render-layers'], }, { type: 'category', From 495a8008b687cb95da62dbc96f3961f0f50defb1 Mon Sep 17 00:00:00 2001 From: Mat Groves Date: Tue, 21 Jan 2025 15:32:03 +0000 Subject: [PATCH 4/4] add back render groups --- docs/guides/advanced/render-groups.md | 45 +++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 docs/guides/advanced/render-groups.md diff --git a/docs/guides/advanced/render-groups.md b/docs/guides/advanced/render-groups.md new file mode 100644 index 000000000..6a1670dce --- /dev/null +++ b/docs/guides/advanced/render-groups.md @@ -0,0 +1,45 @@ +# Render Groups + +## Understanding RenderGroups in PixiJS + +As you delve deeper into PixiJS, especially with version 8, you'll encounter a powerful feature known as RenderGroups. Think of RenderGroups as specialized containers within your scene graph that act like mini scene graphs themselves. Here's what you need to know to effectively use Render Groups in your projects: + +### What Are Render Groups? + +Render Groups are essentially containers that PixiJS treats as self-contained scene graphs. When you assign parts of your scene to a Render Group, you're telling PixiJS to manage these objects together as a unit. This management includes monitoring for changes and preparing a set of render instructions specifically for the group. This is a powerful tool for optimizing your rendering process. + +### Why Use Render Groups? + +The main advantage of using Render Groups lies in their optimization capabilities. They allow for certain calculations, like transformations (position, scale, rotation), tint, and alpha adjustments, to be offloaded to the GPU. This means that operations like moving or adjusting the Render Group can be done with minimal CPU impact, making your application more performance-efficient. + +In practice, you're utilizing Render Groups even without explicit awareness. The root element you pass to the render function in PixiJS is automatically converted into a RenderGroup as this is where its render instructions will be stored. Though you also have the option to explicitly create additional RenderGroups as needed to further optimize your project. + +This feature is particularly beneficial for: + +- **Static Content:** For content that doesn't change often, a Render Group can significantly reduce the computational load on the CPU. In this case static refers to the scene graph structure, not that actual values of the PixiJS elements inside it (eg position, scale of things). +- **Distinct Scene Parts:** You can separate your scene into logical parts, such as the game world and the HUD (Heads-Up Display). Each part can be optimized individually, leading to overall better performance. + +### Examples + +```ts +const myGameWorld = new Container({ + isRenderGroup:true +}) + +const myHud = new Container({ + isRenderGroup:true +}) + +scene.addChild(myGameWorld, myHud) + +renderer.render(scene) // this action will actually convert the scene to a render group under the hood +``` + +Check out the [container example](../../examples/basic/container). + +### Best Practices + +- **Don't Overuse:** While Render Groups are powerful, using too many can actually degrade performance. The goal is to find a balance that optimizes rendering without overwhelming the system with too many separate groups. Make sure to profile when using them. The majority of the time you won't need to use them at all! +- **Strategic Grouping:** Consider what parts of your scene change together and which parts remain static. Grouping dynamic elements separately from static elements can lead to performance gains. + +By understanding and utilizing Render Groups, you can take full advantage of PixiJS's rendering capabilities, making your applications smoother and more efficient. This feature represents a powerful tool in the optimization toolkit offered by PixiJS, enabling developers to create rich, interactive scenes that run smoothly across different devices. \ No newline at end of file