"Si un ouvrier veut bien faire son travail, il doit d'abord affûter ses outils." - Confucius, "Les Entretiens de Confucius. Lu Linggong"
Page de garde > La programmation > Maximiser les performances : une plongée approfondie dans l'optimisation PixiJS

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

Publié le 2024-11-08
Parcourir:301

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 poussée 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é d'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 graphiques = new PIXI.Graphics(); graphiques.beginFill(0xff0000); graphiques.drawRect(0, 0, 200, 100); graphiques.endFill();
const graphics = new PIXI.Graphics();
graphics.beginFill(0xff0000);
graphics.drawRect(0, 0, 200, 100);
graphics.endFill();
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.


fonction createGraphics(x, y) { const graphique = new PIXI.Graphics(); graphique.beginFill(0xDE3249); graphique.drawCircle(x, y, 10); graphique.endFill(); retourner le graphique ; } pour (soit i = 0; i const graphics = new PIXI.Graphics(); graphics.beginFill(0xff0000); graphics.drawRect(0, 0, 200, 100); graphics.endFill(); Dans ce scénario, si les 100 objets graphiques partagent la même largeur et la même 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 :


// Créer une géométrie unique pour un cercle const circleGeometry = new PIXI.Graphics(); circleGeometry.beginFill(0xDE3249); circleGeometry.drawCircle(0, 0, 10); // Dessine un cercle à l'origine circleGeometry.endFill(); // Fonction pour créer un graphique en utilisant la géométrie du cercle fonction createCircle(x, y) { const circle = new PIXI.Graphics(circleGeometry.geometry); cercle.x = x; cercle.y = y; cercle de retour ; } // Crée 100 cercles en utilisant la même géométrie pour (soit i = 0; i const graphics = new PIXI.Graphics(); graphics.beginFill(0xff0000); graphics.drawRect(0, 0, 200, 100); graphics.endFill(); 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

Dessinez un objet graphique tout-en-un

Pour les graphiques statiques ou les structures complexes, dessiner tous les éléments dans un seul objet graphique est une autre technique d'optimisation :


const graphiques = new PIXI.Graphics(); // Dessinez 100 cercles en utilisant la même instance PIXI.Graphics pour (soit i = 0; i const graphics = new PIXI.Graphics(); graphics.beginFill(0xff0000); graphics.drawRect(0, 0, 200, 100); graphics.endFill(); Dans cette approche, au lieu de créer de nouveaux objets Graphics, nous ajoutons de nouvelles géométries à la GeometryList d'une seule instance Graphics. Cette méthode est particulièrement efficace pour les structures graphiques plus complexes.

Maximising Performance: A Deep Dive into PixiJS Optimization


Tirer parti de la puissance de CacheAsBitmap dans PixiJS

L'une des fonctionnalités les plus puissantes de PixiJS est CacheAsBitmap. Essentiellement, cela permet au moteur de traiter les graphiques comme des sprites. Cela peut améliorer considérablement les performances dans certains cas.

  • Utilisez CacheAsBitmap uniquement si l'objet n'est pas mis à jour trop souvent.

  • Un gros lot de graphiques peut être mis en cache sous forme de bitmap dans un conteneur. Au lieu de restituer 100 graphiques, pixi prendra un instantané et le pré-rendra sous forme de bitmap.

  • Toujours tenir compte de l'utilisation de la mémoire, les bitmaps mis en cache utilisent beaucoup de mémoire.

Quand utiliser CacheAsBitmap

Il faut utiliser cacheAsBitmap judicieusement. Il sera plus efficace lorsqu’il sera appliqué à des objets qui doivent rarement être mis à jour. Par exemple, si l'on dispose de milliers de volumes de graphiques statiques ou ne présentant que de rares modifications, leur mise en cache sous forme de bitmap réduit radicalement la surcharge de rendu.

Au lieu de restituer 100 graphiques individuels, PixiJS peut en prendre un « instantané » et les restituer sous forme de bitmap unique. Voici comment vous pouvez mettre en œuvre :


const graphiquesContainer = new PIXI.Container(); // Ajoutez vos graphiques au conteneur //... // Cache l'intégralité du conteneur sous forme de bitmap graphiquesContainer.cacheAsBitmap = true;
const graphics = new PIXI.Graphics();
graphics.beginFill(0xff0000);
graphics.drawRect(0, 0, 200, 100);
graphics.endFill();
Considération sur l'utilisation de la mémoire

Cependant, il est important de faire attention à l'utilisation de la mémoire. Les bitmaps mis en cache peuvent consommer une quantité importante de mémoire. Par conséquent, même si cacheAsBitmap peut réduire considérablement la charge de rendu, il utilise davantage de mémoire. Ce compromis doit être soigneusement étudié en fonction des besoins et des contraintes spécifiques de votre application.

En résumé, cacheAsBitmap est un outil efficace pour optimiser les performances dans PixiJS, notamment pour les graphiques statiques ou rarement mis à jour. Il simplifie le rendu en traitant les graphiques complexes comme des bitmaps uniques, mais il est essentiel d'équilibrer cela avec les implications en matière d'empreinte mémoire.

Pourquoi les sprites sont souvent plus efficaces que les graphiques dans PixiJS

En ce qui concerne l'efficacité de la mémoire dans PixiJS, les sprites ont généralement le dessus sur les graphiques. Cela est particulièrement évident lorsqu’il s’agit de plusieurs objets partageant la même forme ou la même texture. Reprenons l'exemple de la création de graphiques à 100 cercles, mais cette fois en utilisant des sprites.

Créer des sprites à partir d'une seule texture

Tout d'abord, nous créons une texture à partir de la géométrie d'un graphique à cercle unique :


const circleGraphic = new PIXI.Graphics(); circleGraphic.beginFill(0xDE3249); circleGraphic.drawCircle(0, 0, 10); circleGraphic.endFill(); // Génère une texture à partir du graphique const circleTexture = app.renderer.generateTexture(circleGraphic); Ensuite, nous utilisons cette texture pour créer des sprites : // Fonction pour créer un sprite en utilisant la texture cercle fonction createCircleSprite(x, y) { const sprite = new PIXI.Sprite(circleTexture); sprite.x = x; sprite.y = y; retourner le sprite ; } // Créez et ajoutez 100 sprites circulaires à la scène pour (soit i = 0; i const graphics = new PIXI.Graphics(); graphics.beginFill(0xff0000); graphics.drawRect(0, 0, 200, 100); graphics.endFill(); Dans cette approche, au lieu de restituer les graphiques et de gérer une liste de géométries croissante pour chaque objet, nous créons une texture et la réutilisons sur plusieurs sprites. Cela réduit considérablement la charge de rendu et l'utilisation de la mémoire.

Limites et solutions créatives

Une limitation de cette méthode est que vous êtes limité par les textures que vous avez créées. Cependant, c’est là que la créativité devient essentielle. Vous pouvez générer différentes textures de forme à l'aide de PIXI.Graphics et les appliquer aux Sprites. Une approche particulièrement efficace consiste à créer une baseTexture, comme un bitmap de 1x1 pixel, et à la réutiliser pour tous les sprites rectangulaires. En redimensionnant le sprite à différentes dimensions, vous pouvez exploiter la même baseTexture sur plusieurs sprites sans redondance.

Par exemple:

// Cela crée une texture blanche 16x16 const baseTexture = PIXI.Texture.WHITE; // Utilisez cette baseTexture pour toutes les formes rectangulaires const sprite= new PIXI.Sprite(baseTexture); sprite.tint = 0xDE3249; // Définir la couleur du sprite sprite.position.set(x, y); sprite.width = largeur; sprite.hauteur = hauteur;
const graphics = new PIXI.Graphics();
graphics.beginFill(0xff0000);
graphics.drawRect(0, 0, 200, 100);
graphics.endFill();

Maximising Performance: A Deep Dive into PixiJS Optimization

Avec cette méthode, .tint() vous permet de colorer le sprite sans déclencher un nouveau rendu complet, car la teinte est appliquée comme un effet de shader supplémentaire directement sur le GPU.

Utiliser 100 000 sprites dans un conteneur de particules

Pour illustrer la puissance de cette technique, imaginez exécuter 100 000 sprites individuels avec des teintes aléatoires, chacun se transformant à chaque image, tout en conservant une fluidité de 60 FPS.

Maximising Performance: A Deep Dive into PixiJS Optimization

Maximising Performance: A Deep Dive into PixiJS Optimization

Pour en savoir plus sur l'optimisation de PixiJS, je recommande fortement un article perspicace de l'un des créateurs originaux de PixiJS, qui approfondit la technique de renduTexture. 

Vous pouvez le trouver ici

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 approfondie 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 !

Déclaration de sortie Cet article est reproduit sur : https://dev.to/recursivevoid/maximising-performance-a-deep-dive-into-pixijs-optimization-4i0g?1 En cas de violation, veuillez contacter [email protected] pour supprimer il
Dernier tutoriel Plus>

Clause de non-responsabilité: Toutes les ressources fournies proviennent en partie d'Internet. En cas de violation de vos droits d'auteur ou d'autres droits et intérêts, veuillez expliquer les raisons détaillées et fournir une preuve du droit d'auteur ou des droits et intérêts, puis l'envoyer à l'adresse e-mail : [email protected]. Nous nous en occuperons pour vous dans les plus brefs délais.

Copyright© 2022 湘ICP备2022001581号-3