Présentation
En règle générale, lorsque vous jouez à des jeux 2D ou effectuez le rendu de canevas HTML5, vous devez effectuer des optimisations pour utiliser plusieurs calques pour créer une scène composite. Dans le rendu de bas niveau, tel qu'OpenGL ou WebGL, le rendu est effectué en nettoyant et en peignant la scène image par image. Une fois le rendu implémenté, le jeu doit être optimisé pour réduire la quantité de rendu, et le coût varie en fonction de la situation. Le canevas étant un élément DOM, il vous permet de superposer plusieurs canevas comme méthode d'optimisation.
Abréviations couramment utilisées
Cet article explorera la justification de la superposition des toiles. Comprenez les paramètres DOM pour implémenter des canevas en couches. L'optimisation à l'aide de la superposition nécessite diverses pratiques. Cet article explorera également certains concepts et techniques de stratégie d'optimisation qui étendent l'approche en couches.
Vous pouvez télécharger le code source des exemples utilisés dans cet article.
Choisissez une stratégie d'optimisation
Choisir la meilleure stratégie d'optimisation peut être difficile. Lorsque vous choisissez une scène en couches, vous devez tenir compte de la manière dont la scène est composée. Le rendu d'objets fixes sur de grands écrans nécessite souvent la réutilisation de plusieurs composants, et ceux-ci constituent d'excellents candidats à l'étude. Les effets tels que la parallaxe ou les entités animées nécessitent souvent de grandes quantités d'espace d'écran variable. C'est une bonne idée d'être conscient de ces situations lorsque vous explorez votre stratégie d'optimisation optimale. Bien que l'optimisation des couches de canevas nécessite plusieurs techniques différentes, lorsqu'elles sont appliquées correctement, ces techniques entraînent souvent des améliorations significatives des performances.
Définir le calque
Lors de l'utilisation de l'approche en couches, la première étape consiste à configurer le canevas sur le DOM. Généralement, cela est aussi simple que de définir l'élément de canevas et de le placer dans le DOM, mais le calque de canevas peut nécessiter un style supplémentaire. Il existe deux conditions pour réussir à implémenter la superposition de canevas lors de l'utilisation de CSS :
Chaque élément du canevas doit coexister à la même position dans la fenêtre.
Chaque toile doit être visible sous une autre toile.
La figure 1 montre le concept général de superposition derrière les paramètres de calque.
Figure 1. Exemple de calque
Les étapes pour configurer un calque sont les suivantes :
Définir la pile de chevauchement de toile
La création d'une pile de superposition en CSS peut nécessiter une petite quantité de style. Il existe de nombreuses façons de se chevaucher en utilisant HTML et CSS. Les exemples de cet article utilisent une balise
Réalisez la deuxième exigence de style de la technique de calque en utilisant une visibilité qui se chevauche. L'exemple utilise cette option pour définir la couleur d'arrière-plan de l'élément DOM, comme indiqué dans le listing 2.
Listing 2. Règles de feuille de style pour définir un arrière-plan transparent
Code XML/HTML
Stylisez la toile pour qu'elle ait un fond transparent, ce qui répond à la deuxième exigence d'avoir une toile superposée visible. Maintenant que vous avez structuré votre balisage et vos styles pour répondre à vos besoins en matière de superposition, vous pouvez configurer une scène en couches.
Considérations relatives à la superposition
Lorsque vous choisissez une stratégie d'optimisation, vous devez être conscient de tous les compromis liés à l'utilisation de cette stratégie. La superposition de scènes de canevas HTML5 est une stratégie d'exécution axée sur la mémoire utilisée pour obtenir des avantages en termes de vitesse d'exécution. Vous pouvez ajouter plus de poids au navigateur de la page pour obtenir une fréquence d'images plus rapide. De manière générale, le canevas est considéré comme un plan graphique sur le navigateur, qui inclut une API graphique.
En testant dans Google Chrome 19 et en enregistrant l'utilisation de la mémoire des onglets du navigateur, vous pouvez voir des tendances claires en matière d'utilisation de la mémoire. Ce test utilise un
Dans le Gestionnaire des tâches de Google Chrome, vous pouvez voir la quantité de mémoire (également appelée RAM) utilisée par une page. Chrome fournit également de la mémoire GPU, ou la mémoire utilisée par le GPU. Il s'agit d'informations courantes telles que la géométrie, les textures ou toute forme de données mises en cache dont l'ordinateur pourrait avoir besoin pour afficher les données de votre canevas à l'écran. Plus la mémoire est faible, moins l’ordinateur aura de poids. Bien qu'il n'existe pas encore de chiffres précis sur lesquels se baser, vous devez toujours tester cela pour vous assurer que votre programme ne repousse pas ses limites et n'utilise pas trop de mémoire. Si trop de mémoire est utilisée, le navigateur ou la page plantera en raison d'un manque de ressources mémoire. Le traitement GPU est une activité de programmation ambitieuse qui dépasse le cadre de cet article. Vous pouvez commencer par apprendre OpenGL ou consulter la documentation de Chrome (voir Ressources).
Tableau 1. Surcharge de mémoire de la couche de toile
Dans le tableau 1, à mesure que davantage d'éléments de canevas HTML5 sont introduits et utilisés sur la page, plus de mémoire est utilisée. La mémoire générale a également une corrélation linéaire, mais avec chaque couche supplémentaire, la croissance de la mémoire sera considérablement réduite. Bien que ce test ne détaille pas l'impact de ces couches sur les performances, il montre que le canevas peut avoir un impact important sur la mémoire GPU. N'oubliez jamais d'effectuer des tests de résistance sur votre plate-forme cible pour vous assurer que les limitations de la plate-forme ne rendent pas votre application incapable de fonctionner.
Lorsque vous choisissez de modifier le cycle de rendu de canevas unique d'une solution en couches, tenez compte des gains de performances en termes de surcharge de mémoire. Malgré le coût mémoire, cette technique fait son travail en réduisant le nombre de pixels modifiés sur chaque image.
La section suivante explique comment utiliser les calques pour organiser une scène.
Superposition de scènes : jeux
Dans cette section, nous examinerons une solution multicouche en refactorisant une implémentation sur une seule toile d'un effet de parallaxe sur un jeu de style coureur de plate-forme à défilement. La figure 2 montre la composition de la vue du jeu, qui comprend les nuages, les collines, le sol, l'arrière-plan et certaines entités interactives.
Figure 2. Vue du jeu synthétique
Dans le jeu, les nuages, les collines, le sol et l'arrière-plan se déplacent tous à des vitesses différentes. Essentiellement, les éléments situés plus en arrière-plan se déplacent plus lentement que les éléments situés devant, créant ainsi un effet de parallaxe. Pour rendre les choses plus compliquées, l'arrière-plan se déplace suffisamment lentement pour qu'il ne soit restitué que toutes les demi-secondes.
En général, une bonne solution serait d'effacer toutes les images et de restituer le rendu de l'écran puisque l'arrière-plan est une image et change constamment. Dans ce cas, puisque l'arrière-plan ne change que deux fois par seconde, vous n'avez pas besoin de restituer chaque image.
Actuellement, vous avez défini votre espace de travail, vous pouvez donc décider quelles parties de votre scène doivent être sur le même calque. Une fois les calques organisés, nous explorerons diverses stratégies de rendu pour la superposition. Tout d’abord, vous devez réfléchir à la manière d’implémenter cette solution à l’aide d’un seul canevas, comme le montre le listing 3.
Listing 3. Pseudocode pour une boucle de rendu sur un seul canevas
Comme le code du listing 3, cette solution aurait une fonction de rendu qui est appelée à chaque appel de boucle de jeu ou à chaque intervalle de mise à jour. Dans ce cas, le rendu est séparé des appels de boucle principale et des appels de mise à jour qui mettent à jour la position de chaque élément.
Suite à la solution "clear to render", render appelle le contexte clear et en garde la trace en appelant les entités à l'écran les fonctions de rendu respectives de l'écran. Le listing 3 suit un chemin programmatique pour placer des éléments sur le canevas. Bien que cette solution soit efficace pour le rendu des entités à l'écran, elle ne décrit pas toutes les méthodes de rendu utilisées et ne prend en charge aucune forme d'optimisation du rendu.
Afin de mieux spécifier la méthode de rendu des entités, deux types d'objets entité doivent être utilisés. Le listing 4 montre les deux entités que vous utiliserez et affinerez.
Listing 4. Pseudocode de l'entité rendu
L'objet du listing 4 stocke les variables d'instance pour l'image de l'entité, x, y, largeur et hauteur. Ces objets suivent la syntaxe JavaScript, mais par souci de concision, seul le pseudocode incomplet des objets cibles est fourni. Actuellement, les algorithmes de rendu sont très gourmands en rendu leurs images sur le canevas, sans égard aux autres exigences de la boucle de jeu.
Pour améliorer les performances, il est important de noter que l'appel de rendu panoramique génère une image plus grande que l'image souhaitée. Cet article ignore cette optimisation spécifique. Cependant, si l'espace utilisé est plus petit que celui fourni par votre image, assurez-vous de ne restituer que les correctifs nécessaires.
Déterminer la superposition
Maintenant que vous savez comment implémenter cet exemple en utilisant un seul canevas, voyons s'il existe des moyens d'affiner ce type de scène et d'accélérer la boucle de rendu. Pour utiliser des techniques de superposition, vous devez identifier les éléments de canevas HTML5 requis pour la superposition en recherchant le chevauchement du rendu des entités.
Redessiner la zone
Pour déterminer s'il y a un chevauchement, considérez une zone invisible appelée zone de redessinage. La zone de redessinage est la zone où le canevas doit être effacé lors du dessin de l'image de l'entité. Les régions de redessinage sont importantes pour l'analyse du rendu car elles vous permettent de trouver des techniques d'optimisation pour perfectionner votre scène rendue, comme le montre la figure 3.
Figure 3. Vue synthétique du jeu et zone de redessinage
Pour visualiser l'effet de la figure 3, chaque entité de la scène a une superposition représentant la zone de redessinage, qui s'étend sur la largeur de la fenêtre et la hauteur de l'image de l'entité. Les scènes peuvent être divisées en trois groupes : arrière-plan, premier plan et interactions. Les zones repeintes de la scène ont une superposition colorée pour différencier les différentes zones :
Pour tous les chevauchements, à l'exception des balles et des obstacles, la zone de redessinage s'étend sur la largeur de la fenêtre. Les images de ces entités remplissent presque tout l’écran. En raison de leurs exigences de traduction, ils restitueront toute la largeur de la fenêtre, comme le montre la figure 4. Les balles et les obstacles sont censés passer par cette fenêtre et peuvent avoir leurs propres zones définies par les positions des entités. Vous pouvez facilement voir les calques individuels si vous supprimez l'image rendue dans la scène, ne laissant que la zone redessinée.
Figure 4. Redessiner la zone
La couche initiale est évidente car on peut remarquer les différentes zones qui se chevauchent. Étant donné que les zones de balle et d'obstacles couvrent la colline et le sol, ces entités peuvent être regroupées en une seule couche, appelée couche d'interaction. Selon l'ordre de rendu des entités du jeu, la couche d'interaction est la couche supérieure.
Une autre façon de trouver des couches supplémentaires consiste à collecter toutes les zones sans chevauchement. Les zones rouges, vertes et bleues qui occupent la fenêtre ne se chevauchent pas et forment le deuxième calque, le premier plan. Les zones du nuage et les entités interactives ne se chevauchent pas, mais comme la balle a le potentiel de sauter vers la zone rouge, vous devriez envisager de faire de cette entité un calque distinct.
Pour la zone noire, on peut facilement en déduire que les entités d'arrière-plan constitueront le calque final. Toute zone qui remplit la totalité de la fenêtre (telle qu'une entité d'arrière-plan) doit être considérée comme remplissant cette zone dans la totalité du calque, bien que cela ne s'applique pas à cette scène. Après avoir défini nos trois calques, nous pouvons commencer à attribuer ce calque au canevas, comme le montre la figure 5.
Figure 5. Vue du jeu en couches
Maintenant que vous avez défini des calques pour chaque entité groupée, vous pouvez commencer à optimiser le nettoyage du canevas. Le but de cette optimisation est de gagner du temps de traitement, ce qui peut être obtenu en réduisant le nombre d'appareils à l'écran rendus à chaque étape. Il est important de noter que les images peuvent être mieux optimisées en utilisant différentes stratégies. La section suivante explore les méthodes d'optimisation pour diverses entités ou couches.
Optimisation du rendu
L'optimisation des entités est au cœur de la stratégie en couches. La superposition d'entités permet d'adopter des stratégies de rendu. En règle générale, les techniques d'optimisation tentent d'éliminer les frais généraux. Comme mentionné dans le tableau 1, vous avez augmenté la surcharge de mémoire en raison de l'introduction de couches. Les techniques d'optimisation discutées ici réduiront la quantité de travail que le processeur doit effectuer pour accélérer le jeu. Notre objectif est de trouver un moyen de réduire la quantité d'espace nécessaire au rendu et de supprimer autant d'appels de rendu et de nettoyage que possible à chaque étape.
Effacer une seule entité
La première optimisation vise à libérer de l'espace, en accélérant le traitement en effaçant uniquement le sous-ensemble de l'écran qui constitue l'entité. Réduisez d’abord la quantité de zone de redessinage qui chevauche les pixels transparents autour de chaque entité de la zone. L'utilisation de cette technique inclut des entités relativement petites qui remplissent une petite zone de la fenêtre.
La première cible est constituée des entités balle et obstacle. La technique de compensation d'une seule entité consiste à effacer la position où l'entité a été rendue dans l'image précédente avant de restituer l'entité à sa nouvelle position. Nous allons introduire une étape de nettoyage dans le rendu de chaque entité et stocker le cadre de délimitation de l'image de l'entité. L'ajout de cette étape modifie l'objet entité pour inclure l'étape de nettoyage, comme indiqué dans le listing 5.
Listing 5. Entités contenant une compensation de boîte unique
Vous pouvez implémenter cette solution de rendu en créant une méthode clear pour chaque entité appelée avant l'étape de mise à jour (mais cet article n'utilisera pas la méthode clear). Vous pouvez également introduire cette stratégie de compensation dans PanningEntity pour ajouter une compensation sur les entités au sol et dans le cloud, comme indiqué dans le listing 6.
Listing 6. PanningEntity avec suppression d'une seule boîte
Code XML/HTML
Étant donné que PanningEntity s'étend sur toute la fenêtre d'affichage, vous pouvez utiliser la largeur du canevas comme taille du rectangle de dégagement. Si vous utilisez cette stratégie de compensation, vous recevrez des zones redessinées qui ont été définies pour les nuages, les collines et les entités au sol.
Pour optimiser davantage les entités cloud, les nuages peuvent être séparés en entités distinctes avec leurs propres zones de redessinage. Cela réduira considérablement la quantité d’espace d’écran à libérer dans la zone de redessinage du cloud. La figure 7 montre la nouvelle zone de redessinage.
Figure 7. Nuage avec zones de redessinage séparées
Une stratégie de compensation d'une seule entité produit une solution qui résout la plupart des problèmes sur un jeu de canevas en couches comme celui-ci, mais elle peut toujours être optimisée. Pour trouver les cas extrêmes de cette stratégie de rendu, nous supposons que la balle entrera en collision avec le triangle. Si deux entités entrent en collision, il est possible que les zones redessinées de l'entité se chevauchent et créent un artefact de rendu indésirable. Une autre optimisation du nettoyage, plus adaptée aux entités susceptibles d'entrer en collision, qui bénéficiera également au layering.
Rectangle sale clair
En l'absence d'une stratégie de nettoyage unique, la stratégie de nettoyage des rectangles sales peut être une alternative puissante. Vous pouvez utiliser cette stratégie de nettoyage avec de grandes entités dont les zones ont été repeintes, telles que des systèmes de particules denses ou des jeux spatiaux avec des astéroïdes.
Conceptuellement, l'algorithme collecte la zone de redessinage de toutes les entités gérées par l'algorithme et efface toute la zone en un seul appel clair. Pour une optimisation supplémentaire, cette stratégie de nettoyage supprime également les appels de nettoyage en double effectués par chaque entité indépendante, comme indiqué dans le listing 7.
Liste 7.DirtyRectManager
将脏矩形算法集成到渲染循环,这要求在进行渲染调用之前调用清单 7中的管理器。将实体添加到管理器,使管理器可以在清除时计算清除矩形的维度。虽然管理器如图 8所示。
图 8.交互层的重绘区域
图 8显示了由针对在交互层的实体的算法计算出的重绘区域。因为游戏在这一层上包含交互,所以脏矩形策略足以解决交互和重叠的重绘区域问题。
作为清除的重写
对于在恒定重绘区域中动画的完全不透明实体,可以使用重写作为一项优化技术。将不透明的位图渲染为一个区域(默认的合成操作),这会将像素放在该区域这个优化消除了渲染调用之前所需的清除调用,因为渲染会覆盖原来的区域。
通过在之前的渲染的上方重新渲染图像,重写可以加快地面实体。也可以通过相同的方式加快最大的层,比如背景。
您已经有效地为层和它们所包含的实体找到优化策略。
结束语
对画布进行分层是一个可以应用于所有交互式实时场景的优化策略.优化,您需要通过分析场景的重绘区域来考虑场景如何重叠这些区域。一些场景是具有重叠的重绘区域的集合,可以定义层,因此它们是渲染分层画布的良好候选。如果您需要粒子系统或大量物理对象碰撞在一起,对画布进行分层可能是一个很好的优化选择。