Ce que vous obtiendrez de cette page : Deuxième partie de notre collection de conseils utilespour optimiser vos ressources artistiques pour votre jeu mobile. La première partie estici.
Vous pouvez trouver de nombreux autres conseils d'optimisation mobile danscet e-book completet dans ce cours Unity Learn surl'optimisation de l'art 3D pour les applications mobiles.
Le même éclairage et les mêmes matériaux physiques provenant des consoles et des PC peuvent également être adaptés à votre téléphone ou tablette grâce au Universal Render Pipeline (URP).
Regroupez vos appels de tirage
Avec chaque image, Unity détermine les objets qui doivent être rendus, puis crée des appels de dessin. Un appel draw est un appel à l'API graphique pour dessiner des objets (par exemple un triangle), tandis qu'un lot est un groupe d'appels draw à exécuter ensemble. Le regroupement d'objets à dessiner ensemble minimise les changements d'état nécessaires pour dessiner chaque objet dans un lot. Cela conduit à des performances améliorées en réduisant le coût du processeur pour le rendu des objets.
- Traitement par lots dynamique : Pour les petits maillages, Unity peut regrouper et transformer les sommets sur le CPU, puis les dessiner tous en une seule fois. remarque Utilisez-le uniquement si vous disposez de suffisamment de maillages low-poly (moins de 900 attributs de sommet et pas plus de 300 sommets). Le Dynamic Batcher ne regroupera pas les maillages plus grands que cela, donc son activation fera perdre du temps au processeur à rechercher de petits maillages à regrouper dans chaque image.
- Traitement par lots statique : Pour une géométrie immobile, Unity peut réduire les appels de dessin pour les maillages partageant le même matériau. Bien qu’il soit plus efficace que le traitement par lots dynamique, il utilise plus de mémoire.
- Instanciation GPU : Si vous disposez d'un grand nombre d'objets identiques, cette technique les regroupe plus efficacement grâce à l'utilisation de matériel graphique.
Lotage SRP : Activez le SRP Batcher dans votre actif URP sous Avancé. Cela peut accélérer considérablement les temps de rendu de votre processeur, en fonction de la scène.
Il est crucial d'éviter d'ajouter trop de lumières dynamiques à votre application mobile. Envisagez des alternatives telles que des effets de shader personnalisés et des sondes de lumière pour les maillages dynamiques, ainsi qu'un éclairage ancré pour les maillages statiques.
Consultez ce tableau de comparaison des fonctionnalités pour connaître les limites spécifiques des lumières en temps réel URP et Built-In Render Pipeline.
La projection d'ombre peut être désactivée par MeshRenderer et la lumière. Désactivez les ombres autant que possible pour réduire les appels de tirage.
Vous pouvez également créer de fausses ombres en utilisant une texture floue appliquée à un simple maillage ou quad sous vos personnages. Sinon, vous pouvez créer des ombres blob avec des shaders personnalisés.
Ajoutez un éclairage spectaculaire à votre géométrie statique à l'aide de Global Illumination (GI). Marquez les objets avec Contribute GI afin de pouvoir stocker un éclairage de haute qualité sous forme de lightmaps.
Les ombres et l'éclairage ancrés peuvent ensuite être rendus sans affecter les performances au moment de l'exécution. Le Lightmapper progressif du CPU et du GPU peut accélérer la cuisson de l’éclairage global.
Suivez le manuel et cet article sur l'optimisation de la lumière pour démarrer avec le lightmapping dans Unity.
Pour les scènes complexes avec plusieurs lumières, séparez vos objets à l'aide de calques, puis limitez l'influence de chaque lumière à un masque de sélection spécifique.
Les sondes lumineuses stockent des informations d'éclairage cuites sur l'espace vide de votre scène, tout en fournissant un éclairage de haute qualité (à la fois direct et indirect). Ils utilisent des harmoniques sphériques, qui calculent rapidement par rapport aux lumières dynamiques.
Une sonde à réflexion peut créer des réflexions réalistes, mais peut être très coûteuse en termes de lots. Utilisez des cubemaps basse résolution, des masques de sélection et une compression de texture pour améliorer les performances d'exécution.
Le rendu d'un objet avec transparence utilise toujours plus de ressources GPU que le rendu d'un objet opaque, en particulier lorsque les objets transparents sont rendus les uns sur les autres plusieurs fois, un processus appelé overdraw. C'est une bonne pratique d'utiliser un matériau opaque autant que possible, en particulier pour les plateformes mobiles. Vous pouvez vérifier le surdessin à l'aide du débogueur graphique RenderDoc .
Utilisez le shader le plus simple possible (comme un shader éteint) et évitez d'utiliser des fonctionnalités inutiles. Utilisez les shaders prédéfinis de Unity, spécialement conçus pour les systèmes tels que les particules. URP comprend plusieurs shaders légers Lit et Unlit déjà optimisés pour les plates-formes mobiles. Pour minimiser l'overdraw, réduisez le nombre et/ou la taille des particules dans votre jeu.
Pour atteindre les objectifs de performances, envisagez d'utiliser des matériaux opaques non éclairés avec une demi-précision, lorsque cela est possible, et soyez attentif aux opérations complexes dans les nœuds. Retrouvez plus de conseils dans cette session sur Shader Graph.
Lors de la création d'un shader, vous pouvez décider de la manière dont le matériau réagira à la lumière. La plupart des shaders sont classés comme allumés ou éteints. Un shader non éclairé est le modèle d'ombrage le plus rapide et le moins coûteux en termes de calcul. Utilisez-le si vous ciblez un appareil bas de gamme.
Les points clés à considérer comprennent :
- L'éclairage n'affecte pas un modèle d'ombrage non éclairé. Cela signifie que de nombreux calculs, tels que les calculs de spécularité, ne sont pas nécessaires. Le résultat est soit un rendu moins cher, soit un rendu plus rapide.
- L’utilisation d’une direction artistique stylisée qui ressemble à un dessin animé fonctionne bien avec un ombrage non éclairé. Ce style mérite d’être pris en compte lorsque vous développez des jeux pour plateformes mobiles.
Les vertex shaders fonctionnent sur chaque sommet tandis que les pixel shaders (ou fragments) s'exécutent sur chaque pixel. Habituellement, il y a plus de pixels rendus que de sommets à l’écran. Cela signifie que le pixel shader s'exécute plus souvent que le vertex shader. Pour cette raison, nous vous recommandons de déplacer le calcul du pixel shader vers le vertex shader chaque fois que cela est possible. Comme d'habitude, après avoir travaillé sur les optimisations, vous devez effectuer un profilage plus approfondi pour déterminer la meilleure solution pour votre situation particulière.
Les opérations de base, telles que l’addition et la multiplication, sont plus rapides à traiter. Il est préférable de limiter autant que possible le nombre d’opérations mathématiques plus lentes. La quantité de mathématiques complexes utilisées doit être réduite sur les appareils plus anciens, tels que ceux utilisant GLES 2.0.
Lorsque vous activez le SRP Batcher , observez la fenêtre Statistiques et le graphique des sommets de la section de rendu dans la vue Profiler. Mis à part une augmentation des FPS, le nombre de triangles et de sommets traités diminue considérablement. Étant donné que nos objets utilisent un shader compatible avec URP, le pipeline de rendu regroupe automatiquement toutes les données géométriques pertinentes pour réduire la quantité de données traitées.
Par défaut, Unity importe des modèles animés avec le Generic Rig, bien que les développeurs passent souvent au Humanoid Rig lors de l'animation d'un personnage. Une plate-forme humanoïde consomme 30 à 50 % de temps CPU en plus que la plate-forme générique équivalente, car elle calcule la cinématique inverse et recible l'animation de chaque image.
Le rendu des maillages avec peau coûte cher. Assurez-vous que chaque objet utilisant un SkinnedMeshRenderer l'exige. Si un GameObject n'a besoin que d'une animation de temps en temps, utilisez la fonction BakeMesh pour figer le maillage skinné dans une pose statique, puis passez à un MeshRenderer plus simple au moment de l'exécution.
Principalement destiné aux personnages humanoïdes, le système Mecanim de Unity est assez sophistiqué mais est souvent utilisé pour animer des valeurs uniques (par exemple, le canal alpha d'un élément d'interface utilisateur). Évitez d’abuser des animateurs. En particulier en conjonction avec des éléments de l'interface utilisateur, envisagez de créer des fonctions d'interpolation ou d'utiliser une bibliothèque tierce pour des animations simples (par exemple, DOTween ou LeanTween).
Travailler sur un budget de temps spécifique par image
Chaque image aura un budget de temps basé sur vos images cibles par seconde (fps). Idéalement, une application exécutée à 30 ips permettra environ 33,33 ms par image (1 000 ms / 30 ips). De même, un objectif de 60 ips laisse 16,66 ms par image.
Les appareils peuvent dépasser ce budget pendant de courtes périodes (par exemple, pour des cinématiques ou des séquences de chargement), mais pas pour une durée prolongée.
Préréglages
Ne vous fiez pas aux paramètres par défaut. Utilisez l'onglet de remplacement spécifique à la plate-forme pour optimiser les ressources telles que les textures et la géométrie du maillage. Des paramètres incorrects peuvent entraîner des tailles de build plus grandes, des temps de build plus longs et une mauvaise utilisation de la mémoire. Pensez à utiliser la fonctionnalité Préréglages pour vous aider à personnaliser les paramètres de base qui amélioreront un projet spécifique.
Limiter l’utilisation des caméras
Chaque caméra entraîne une certaine surcharge, qu'elle effectue un travail significatif ou non. Utilisez uniquement les composants de caméra requis pour le rendu. Sur les plates-formes mobiles bas de gamme, chaque caméra peut utiliser jusqu'à 1 ms de temps CPU.
Évitez les effets plein écran
Les effets de post-traitement plein écran, comme les lueurs, peuvent ralentir considérablement les performances. Utilisez-les avec prudence dans la direction artistique de votre titre.
Soyez prudent avec Renderer.material
L'accès à Renderer.material dans les scripts duplique le matériau et renvoie une référence à la nouvelle copie. Cela rompt tout lot existant qui inclut déjà le matériau. Si vous souhaitez accéder au matériel de l'objet par lots, utilisez plutôt Renderer.sharedMaterial .