Maison > interface Web > js tutoriel > le corps du texte

Maximiser les performances : une plongée approfondie dans l'optimisation PixiJS

WBOY
Libérer: 2024-09-04 18:33:00
original
456 Les gens l'ont consulté

Faites passer vos applications PixiJS au niveau supérieur grâce à des stratégies et techniques avancées

Avant-propos

Cet article passe en revue les différentes manières d'optimiser au mieux le rendu de plusieurs éléments dans pixiJS en termes de CPU/mémoire. Par exemple, en considérant la différence entre restituer chaque image sans aucune mise en cache (ce qui fonctionne bien en termes d'utilisation du processeur) ou mettre en cache un graphique rendu en mémoire. Cela augmentera l'utilisation de la mémoire proportionnellement au nombre de graphiques dans la scène.

Il existe un certain nombre de stratégies pour gérer de telles optimisations. Il convient de noter en particulier la conception orientée données, qui présente un ensemble d'approches radicalement différentes de la méthode de programmation orientée objet plus traditionnellement courante.

D'autres moyens majeurs incluent : l'élimination et l'utilisation de formats beaucoup plus structurés - NativeArrays en C# et TypedArrays en TypeScript, par exemple. Ceux-ci permettront une gestion bien plus importante des tampons mémoire, ce qui peut limiter les échecs de cache, mais qui nécessite également une expérience significative en ingénierie et/ou personnalisation.

Dans cet article, je me concentrerai sur une méthode de travail d'optimisation pour un environnement WebGL avec PixiJS : l'approche orientée objet, incluant les meilleures pratiques. Cela vous fournira un moyen bien organisé pour augmenter la vitesse et l'efficacité de vos applications PixiJS.

Dans mon prochain article, je parlerai d'une autre approche d'optimisation forte : l'approche Entité-Composant-Système. L'approche ECS est étonnamment orientée données et offre un nouveau regard lorsqu'il s'agit d'optimiser PixiJS dans des environnements hautes performances. Continuez sur Medium pour cet article où, en profondeur, j'entre dans le vif du sujet de l'approche ECS.

N'oubliez jamais qu'il y a toujours quelque chose à faire de mieux pour tenter d'optimiser et d'améliorer encore les performances de votre application Pixi. Par meilleur, cela ne signifie pas le plus optimisé ou le plus rapide. La meilleure solution est une question de compromis entre le temps que vous investissez dans une optimisation et le retour sur investissement pour vous assurer que vous pouvez respecter les délais du projet, mais avec suffisamment d'optimisation pour, espérons-le, satisfaire tous les utilisateurs potentiels sans sur-étendre vos ressources. 🎜>

Approche orientée objet

Dans cette section, je vais vous guider à travers les meilleures façons d'optimiser les applications PixiJS.

Cette section est basée sur des conseils officiels, ça vaut le coup de vérifier !

Le reste de notre discussion portera sur les graphiques Pixi, les sprites, les maillages et quand utiliser un conteneur de particules au lieu du conteneur Pixi par défaut. Ce chapitre devrait vous donner une vision claire de la façon dont tout peut être utilisé de manière optimale dans un contexte orienté objet afin que vos projets PixiJS soient fonctionnels et rendus avec la plus grande efficacité.

Comprendre le fonctionnement interne de Pixi Graphics

Afin d'utiliser efficacement les graphiques Pixi, nous devons comprendre comment ils fonctionnent en interne. Commençons donc par montrer un exemple très basique de création d'un objet graphique dans Pixi :


const graphics = new PIXI.Graphics();
graphics.beginFill(0xff0000);
graphics.drawRect(0, 0, 200, 100);
graphics.endFill();
Copier après la connexion
Ce qui est important dans cette mise en œuvre simple, cependant, c'est ce qui se passe « sous le capot ». En créant ce type de graphique, Pixi crée quelque chose appelé un objet GraphicsGeometry. Cet objet prend la forme et la taille en fonction des dimensions et des propriétés que vous spécifiez pour la forme que vous dessinez. L'objet Geometry final est ensuite stocké dans une GeometryList au sein de l'objet Graphics.

Notez que chaque fois que vous dessinez quelque chose à l'aide de PIXI.Graphics, GeometryList est mis à jour. Parfois, vous souhaitez simplement effacer cette liste, tout en gardant votre objet Graphics en vie. C'est là que la méthode .clear() entre en jeu. Connaître le fonctionnement de ce processus vous aidera grandement lors de l'utilisation de Pixi, car cela affecte directement la façon dont Pixi gérera et restituera les graphiques dans votre application.

Techniques d'optimisation pour Pixi Graphics

Explorons les stratégies d'optimisation à travers un cas d'utilisation de création de 100 objets graphiques dans PixiJS.


function createGraphics(x, y) {
    const graphic = new PIXI.Graphics();
    graphic.beginFill(0xDE3249);
    graphic.drawCircle(x, y, 10);
    graphic.endFill();
    return graphic;
}

for (let i = 0; i < 100; i++) {
    const x = Math.random() * app.screen.width;
    const y = Math.random() * app.screen.height;
    const graphics = createGraphics(x, y);
    app.stage.addChild(graphic);
}
Copier après la connexion
Dans ce scénario, si les 100 objets graphiques partagent la même largeur et hauteur, nous pouvons optimiser en réutilisant la géométrie.

Maximising Performance: A Deep Dive into PixiJS Optimization

Passer GraphicsGeometry comme référence

Créez une géométrie unique pour un cercle et réutilisez-la :


// Create a single geometry for a circle
const circleGeometry = new PIXI.Graphics();
circleGeometry.beginFill(0xDE3249);
circleGeometry.drawCircle(0, 0, 10); // Draw a circle at the origin
circleGeometry.endFill();
// Function to create a graphic using the circle geometry
function createCircle(x, y) {
    const circle = new PIXI.Graphics(circleGeometry.geometry);
    circle.x = x;
    circle.y = y;
    return circle;
}
// Create 100 circles using the same geometry
for (let i = 0; i < 100; i++) {
    const x = Math.random() * app.screen.width;
    const y = Math.random() * app.screen.height;
    const circle = createCircle(x, y);
    app.stage.addChild(circle);
}
Copier après la connexion
Cette méthode réduit considérablement l'utilisation de la mémoire en référençant la même géométrie au lieu de la dupliquer pour chaque objet.

Maximising Performance: A Deep Dive into PixiJS Optimization

Draw All in One Graphics Object

For static graphics or complex structures, drawing all elements in a single Graphics object is another optimization technique:

const graphics = new PIXI.Graphics();
// Draw 100 circles using the same PIXI.Graphics instance
for (let i = 0; i < 100; i++) {
    const x = Math.random() * app.screen.width;
    const y = Math.random() * app.screen.height;
    graphics.beginFill(0xDE3249);
    graphics.drawCircle(x, y, 10);
    graphics.endFill();
}
// Add the graphics to the stage
app.stage.addChild(graphics);
Copier après la connexion

In this approach, instead of creating new Graphics objects, we add new geometries to the GeometryList of a single Graphics instance. This method is particularly efficient for more complex graphic structures.

Maximising Performance: A Deep Dive into PixiJS Optimization


Leveraging the Power of CacheAsBitmap in PixiJS

One of the most powerful features within PixiJS is CacheAsBitmap. Essentially, it lets the engine treat graphics like sprites. This can bring performance up substantially in certain cases.

  • Only use CacheAsBitmap if the object is not updated too often.

  • Big batch of Graphics can be cached as bitmap in container. Instead having 100 Graphics re-rendered, pixi will take a snapshot and pre-render it as a bitmap.

  • Always consider the memory usage, cached bitmaps are using a lot of memory.

When to Use CacheAsBitmap

One should use cacheAsBitmap judiciously. It will be most effective when applied to objects that need to update seldom. For instance, if one happens to have thousands of volume of Graphics that are static or have only a rare change, caching them as a bitmap radically reduces rendering overhead.

Instead of re-rendering 100 individual Graphics, PixiJS can take a 'snapshot' of these and render them as single bitmap. This is how you can implement:

const graphicsContainer = new PIXI.Container();
// Add your graphics to the container
// ...
// Cache the entire container as a bitmap
graphicsContainer.cacheAsBitmap = true;
Copier après la connexion

Memory Usage Consideration

However, it's important to be mindful of memory usage. Cached bitmaps can consume a significant amount of memory. Therefore, while cacheAsBitmap can drastically reduce the rendering load, it trades off by using more memory. This trade-off should be carefully considered based on the specific needs and constraints of your application.

In summary, cacheAsBitmap is an effective tool for optimizing performance in PixiJS, particularly for static or seldom-updated graphics. It simplifies rendering by treating complex graphics as single bitmaps, but it's essential to balance this with the memory footprint implications.

Why Sprites Are Often More Efficient than Graphics in PixiJS

When it comes to memory efficiency in PixiJS, sprites generally have the upper hand over graphics. This is particularly evident when dealing with multiple objects that share the same shape or texture. Let's revisit the example of creating 100 circle graphics, but this time using sprites.

Creating Sprites from a Single Texture

First, we create a texture from the geometry of a single circle graphic:

const circleGraphic = new PIXI.Graphics();
circleGraphic.beginFill(0xDE3249);
circleGraphic.drawCircle(0, 0, 10);
circleGraphic.endFill();
// Generate a texture from the graphic
const circleTexture = app.renderer.generateTexture(circleGraphic);
Next, we use this texture to create sprites:
// Function to create a sprite using the circle texture
function createCircleSprite(x, y) {
    const sprite = new PIXI.Sprite(circleTexture);
    sprite.x = x;
    sprite.y = y;
    return sprite;
}

// Create and add 100 circle sprites to the stage
for (let i = 0; i < 100; i++) {
    const x = Math.random() * app.screen.width;
    const y = Math.random() * app.screen.height;
    const circleSprite = createCircleSprite(x, y);
    app.stage.addChild(circleSprite);
}
Copier après la connexion

In this approach, instead of re-rendering graphics and managing a growing geometry list for each object, we create one texture and reuse it across multiple sprites. This significantly reduces the rendering load and memory usage.

Limitations and Creative Solutions

One limitation of this method is that you're constrained by the textures you've created. However, this is where creativity becomes key. You can generate various shaped textures using PIXI.Graphics and apply them to Sprites. An especially efficient approach is to create a baseTexture, like a 1x1 pixel bitmap, and reuse it for all rectangular sprites. By resizing the sprite to different dimensions, you can leverage the same baseTexture across multiple sprites without redundancy.
For instance:

// This creates a 16x16 white texture
const baseTexture = PIXI.Texture.WHITE;

// Use this baseTexture for all rectangular shapes
const sprite= new PIXI.Sprite(baseTexture);
sprite.tint = 0xDE3249; // Set the sprite color
sprite.position.set(x, y);
sprite.width = width;
sprite.height = height;

Copier après la connexion

Maximising Performance: A Deep Dive into PixiJS Optimization

With this method, .tint() allows you to color the sprite without triggering a full re-render, as the tint is applied as an additional shader effect directly on the GPU.

Using 100k Sprites in Particle Container

To illustrate the power of this technique, imagine running 100,000 individual sprites with random tints, each transforming on every frame, all while maintaining a smooth 60 FPS.

Maximising Performance: A Deep Dive into PixiJS Optimization

Maximising Performance: A Deep Dive into PixiJS Optimization

For further reading on optimizing PixiJS, I highly recommend an insightful article by one of the original creators of PixiJS, which delves deeply into the renderTexture technique. 

You can find it here

Wow ! Si vous êtes arrivé jusqu'ici, je tiens à vous remercier sincèrement d'être resté à mes côtés tout au long de cette plongée profonde dans l'optimisation PixiJS. J'espère que vous avez trouvé les idées et les techniques partagées ici utiles pour vos projets. Restez à l'écoute pour mon prochain article, dans lequel j'explorerai l'approche Entity-Component-System (ECS) et la puissance de NativeArrays de manière encore plus détaillée. Ces méthodes propulseront vos applications PixiJS vers de nouveaux sommets en termes de performances et d'efficacité. Merci d'avoir lu et à la prochaine !

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

source:dev.to
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal
À propos de nous Clause de non-responsabilité Sitemap
Site Web PHP chinois:Formation PHP en ligne sur le bien-être public,Aidez les apprenants PHP à grandir rapidement!