Comment Zugalu Entertainment a réduit l'utilisation de RAM de 20 Go à 500 Mo pour Prospérer: Le poids de la couronne

Cette page a été traduite automatiquement pour faciliter votre expérience. Nous ne pouvons pas garantir l'exactitude ou la fiabilité du contenu traduit. Si vous avez des doutes quant à la qualité de cette traduction, reportez-vous à la version anglaise de la page web.
Prospérer: Le poids de la couronne est un constructeur de ville médiéval avec des éléments de stratégie en temps réel. Le jeu, où le destin du royaume dépend de chaque décision qu'un joueur prend, a à la fois une fonctionnalité solo et multijoueur coopératif. Les joueurs peuvent stratégiquement étendre leur territoire et leur royaume, puis construire sur une grande carte.
Alors que l'équipe commençait à développer le titre, elle a rencontré des obstacles pour améliorer les performances. Après des tests approfondis, ils ont appris où se trouvaient les goulets d'étranglement et ce qu'ils devaient faire – construire un système de cuisson d'animation et un système de végétation personnalisé. Voici comment ils ont amélioré l'animation des personnages dans le jeu.
LE DÉFI:
Surmonter les goulets d'étranglement de performance liés à l'animation des personnages
PLATEFORME:
PC
EMPLACEMENT:
Alberta, Canada
PERSONNEL DU PROJET:
16
Prospérer: Le poids de la couronne: Une étude de cas Unity
Comment un studio optimise-t-il les performances tout en animant des centaines de personnages?
Alors que le jeu prenait forme, il était clair pour l'équipe de Zugalu Entertainment que la performance allait être leur plus grand défi. Ils visaient une exigence système assez basse – une carte graphique NVIDIA GeForce GTX 750 Ti pour le GPU et un processeur quad-core, qui est une puce avec quatre unités indépendantes appelées cœurs qui lisent et exécutent les instructions du CPU.
« Chaque fois que vous voulez cibler un système, le taux de rafraîchissement préférable est de 60 fps. Il y avait des parties de notre système que nous ne pouvions vraiment pas changer et qui prenaient une énorme part de la performance, donc nous devions trouver des gains de n'importe où que nous pouvions, » dit Jackie Li, artiste conceptuel principal et artiste technique chez Zugalu Entertainment.
Alors qu'ils cherchaient des domaines pour améliorer la performance, ils ont décidé que la vaste quantité d'animations de personnages devait être corrigée car elles utilisaient une grande quantité de RAM et provoquaient de nombreux plantages de systèmes de joueurs.

Les résultats
- Réduit l'utilisation de la RAM de 20 Go à 500 Mo
- Animé des milliers de personnages à l'écran en même temps
- Réduit le nombre d'appels de dessin de personnages de 1 000 à 20 appels de dessin instanciés
- Amélioré la performance d'environ 3,5 millisecondes sur la carte graphique GTX 750 Ti à 0,35 millisecondes sur la carte graphique 2080 Ti
Migration de la cuisson de vertex à la cuisson de bone
Pour optimiser le processus d'animation des personnages, l'équipe a construit un système de cuisson d'animation. Ils avaient besoin d'avoir des centaines de personnages animés à l'écran en même temps et ont d'abord examiné des solutions d'actifs d'animation de vertex. C'était un énorme problème pour leur utilisation de VRAM et de RAM. Ils n'ont pas pu trouver d'autre solution, alors ils ont décidé de construire la leur.
Pour le système d'animation, l'équipe a commencé à utiliser la cuisson de vertex, qui consiste à prendre toutes les images clés de leur animation et à cuire ces données par vertex. « Une texture contiendrait une animation, mais la taille de la texture pour cette animation est assez grande. Le coût mémoire est un facteur du nombre de vertices multiplié par le nombre d'images cuites. Donc, 5000 vertices multipliés par 100 images donnerait une texture de 6 Mo au format RGB float 32 bits, » dit Li. « Quand vous avez besoin de nombreuses animations différentes multipliées par un grand nombre de personnages divers, le coût mémoire commence à devenir extrême.
Ils devaient le réduire considérablement, mais tout en maintenant la capacité d'utiliser le GPU pour accélérer les animations. Ils ont décidé de migrer vers la cuisson des os, ce qui offrait un moyen simple d'utiliser moins de données puisque le moteur de rendu de maillage de Unity utilise des os pour transformer le sommet.

Prospérer: Le poids de la couronne | Zugalu Entertainment | PlaySide Studios
« Tout ce que nous devions faire était de prendre le processus de peau de maillage, liant un maillage 3D à un squelette ou un rig, permettant au maillage de se déformer et de bouger de manière réaliste lorsque le squelette était animé, et de le transférer au GPU, » dit Garrett Hau, CTO de Zugalu Entertainment.
Ils ont ensuite pris les transformations des os par image et les ont cuites en tant que textures. Cuire ce genre d'informations a permis d'économiser beaucoup de mémoire. « Avec la cuisson des os, différents personnages ayant la même structure osseuse peuvent partager les données d'animation cuites. Nous avions des personnages comme un fermier et un ouvrier, dont les structures osseuses étaient les mêmes. Nous avons réutilisé les mêmes données cuites à travers plusieurs personnages pour obtenir encore plus d'économies, » explique Li.
Au final, même si le jeu a une tonne de personnages et d'animations, ils ont réduit leur utilisation de RAM de 20 Go à 500 Mo.

Aperçu dans l'éditeur des animations cuites
Bénéficiant de l'instanciation GPU
En ce qui concerne l'animation, l'équipe s'est concentrée sur le rendu de la peau, appliquant des matériaux, des shaders et des textures au maillage pour simuler la couleur de la peau, l'ombrage et les textures. Li explique que, « un avantage du rendu de peau basé sur le calcul GPU est que nous avions accès à l'instanciation GPU. Au lieu de rendre chaque personnage un par un, chacun étant un seul appel de dessin, nous avons rendu plusieurs personnages avec différentes animations en utilisant un seul appel de dessin. »
C'était possible puisqu'ils ont pris les données d'animation, les textures, et les ont regroupées dans un seul tableau de textures. Cela ressemble à une seule texture pour le GPU. « Il est possible de rendre chaque personnage en utilisant un seul appel de dessin, mais pour être plus flexible, nous n'avions que quatre personnages qui partageaient des os. »

Capturer un appel de dessin instancié
Lors du passage de la cuisson des sommets à la cuisson des os, l'équipe a réduit le nombre d'appels de dessin de personnages de 1 000 à 20 appels de dessin instanciés. « Le baking de vertex était difficile car chaque sous-maille individuelle était considérée comme différente. » Un personnage pouvait avoir plusieurs parties et chacune aurait un appel de dessin, dit Hau.
Avec le baking d'os, cela varie en fonction du nombre de types différents de personnages qu'un jeu a à la place. Chaque personnage serait au maximum un appel de dessin car il combine toutes les sous-maille en une seule maille. « Par exemple, » explique Hau, « même s'il y a 10 types différents de personnages à l'écran et que chacun a plusieurs sous-maille, il n'y aura que 10 appels de dessin. »

Prospérer: Le poids de la couronne | Zugalu Entertainment | PlaySide Studios
“« Unity a de nombreuses API qui font exactement ce que vous voulez. Cela inclut la récupération d'informations spécifiques d'un FBX importé, le basculement facile des mots-clés de shader et la création d'outils d'éditeur personnalisés avec des API d'inspecteur faciles à utiliser. »”
Jackie Li - Zugalu Entertainment
Lead Concept Artist and Technical ArtistConstruction d'une transformation de matrice
Apprendre le skinning de maillage a aidé l'équipe à surmonter ses grands obstacles d'animation. Ils ont utilisé les API Unity pour les aider en cours de route.
Pour récupérer les transformations d'os, ils ont accédé à la propriété publique de SkinnedMeshRenderer.bones. Cette API renvoie un tableau de transformations qui contient des informations comme toute autre transformation de GameObject. Pour la mesure de performance, ils ont utilisé la détection automatique des builds de développement de Unity Profiler fonctionnant sur d'autres ordinateurs sur le réseau local. Cela leur a permis de profiler le jeu sur leur système de minimum requis tout en travaillant depuis leurs ordinateurs principaux.
L'équipe de test de performance a également appliqué ProfilerMarker.Begin() et ProfilerMarker.End() APIs pour échantillonner la performance par image. Ceci peut être utilisé en créant un ProfileMarket.struct, puis en insérant les deux appels de méthode précédents à l'endroit où ils voulaient tester le timing du CPU. Ce résultat est ensuite apparu dans le Unity Profiler.

Prospérer: Le poids de la couronne | Zugalu Entertainment | PlaySide Studios
Li dit, « Les API de Unity ont été formidables. Elles ont aidé à rendre certaines parties du développement sans couture. » Le seul bug que l'équipe a rencontré était avec l'espace de coordonnées dans le GPU. « Nous obtenions l'espace mondial, mais nous avions besoin de l'espace des os. »
Lors de l'échantillonnage d'une image de la transformation de l'os pendant la cuisson, ils avaient besoin d'une transformation par rapport à la position initiale de l'os, connue sous le nom de bindpose. Pour y parvenir, ils ont construit une transformation matricielle. Tout d'abord, ils ont récupéré la matrice de bindpose de SkinnedMeshRenderer.sharedMesh.bindposes. Ils ont ensuite multiplié la matrice de transformation mondiale de l'os avec la matrice de transformation de bindpose (par exemple, boneTransform.localToWorldMatrix * bindpose).

Prise de vue dans l'éditeur d'un shader de personnage dans Shader Graph
“« Shader Graph est la réponse de Unity pour créer des shaders sans avoir une compréhension approfondie du code des shaders lui-même. C'était vraiment pratique puisque nous n'avions pas besoin de réécrire tout le shader nous-mêmes. »”
Garrett Hau - Zugalu Entertainment
CTOCréer des shaders facilement
Lorsqu'il s'agissait de produire des shaders pour l'animation, l'équipe a choisi Shader Graph. « C'est la réponse de Unity pour créer des shaders sans avoir une compréhension approfondie du code des shaders lui-même. C'était vraiment pratique puisque nous n'avions pas besoin de réécrire tout le shader nous-mêmes, » dit Hau.
Pour le skinning de maillage, ils ont dû faire beaucoup de mathématiques de shader, et les nœuds que Shader Graph fournit leur ont permis de le compléter. Li explique que, « c'est l'échantillonnage de texture et les mathématiques matricielles. Si vous le souhaitiez, vous pourriez également utiliser le nœud de fonction personnalisé de Unity pour écrire le code vous-même. »
Pour les outils de l'éditeur, le directeur d'animation avait des exigences spécifiques pour cuire les animations puisqu'il les a toutes créées lui-même. « Avec C# et les API de Unity, il était assez facile d'activer et de désactiver l'interpolation pour les shaders. Ils nous ont également aidés à changer le nombre d'os à cuire et le nombre d'images à cuire, » dit Li. « Les API Inspector conviviales ont permis d'ajouter facilement ces fonctionnalités d'éditeur à l'outil de cuisson. »

Échantillonnage de textures de matrice dans Shader Graph
Rester optimiste et conscient
À la fin de la journée, bien que le développement du jeu ait été rempli de hauts et de bas, l'équipe a amélioré les performances du GPU d'environ 3,5 millisecondes sur la carte graphique GTX 750 Ti à 0,3 millisecondes sur la carte graphique 2080 Ti.
Comme le dit Li, « Nous sommes ravis des économies de performances et de la façon dont le jeu s'est révélé. »

Prospérer: Le poids de la couronne | Zugalu Entertainment | PlaySide Studios
Téléchargez Unity Pro dès aujourd'hui
Commencez à créer des jeux qui rivalisent avec, et surpassent la qualité et le succès des sorties de grands studios avec l'aide d'outils puissants, de soutien, de partenaires vérifiés et d'une communauté dynamique.