Performances — MRTK2

Prise en main

Le moyen le plus simple de rationaliser les performances consiste à utiliser la fréquence d’images ou le nombre de fois que votre application peut restituer une image par seconde. Il est important d’atteindre la fréquence d’images cible, comme indiqué par la plateforme ciblée (c’est-à-dire Windows Mixed Reality, Oculus, etc.). Par exemple, sur HoloLens, la fréquence d’images cible est de 60 FPS. Les applications à faible fréquence d’images peuvent entraîner des expériences utilisateur détériorées, telles que la stabilisation des hologrammes, le suivi mondial, le suivi des mains, etc. Pour aider les développeurs à suivre et à atteindre une fréquence d’images de qualité, Mixed Reality Toolkit fournit une variété d’outils et de scripts.

Profileur visuel

Pour suivre en continu les performances tout au long de la durée de développement, il est vivement recommandé de toujours afficher un visuel à fréquence d’images lors de l’exécution & du débogage d’une application. Mixed Reality Toolkit fournit l’outil de diagnostic Visual Profiler qui fournit des informations en temps réel sur l’utilisation actuelle du FPS et de la mémoire dans la vue application. Le profileur visuel peut être configuré via les paramètres système de diagnostic sous l’inspecteur de profils MRTK.

En outre, il est particulièrement important d’utiliser Visual Profiler pour suivre la fréquence d’images lors de l’exécution sur l’appareil plutôt que dans un éditeur Unity ou un émulateur. Les résultats de performances les plus précis sont décrits lors de l’exécution sur l’appareil avec des builds de configuration Release.

Notes

Si vous générez pour Windows Mixed Reality, déployez avec des builds de configuration MASTER.

Visual Profiler Interface

Fenêtre d’optimisation

La fenêtre d’optimisation MRTK offre des informations et des outils d’automatisation pour aider les développeurs de réalité mixte à configurer leur environnement pour obtenir les résultats les plus performants et identifier les goulots d’étranglement potentiels dans leur scène & ressources. Certaines configurations clés dans Unity peuvent aider à fournir des résultats beaucoup plus optimisés pour les projets de réalité mixte.

En règle générale, ces paramètres impliquent des configurations de rendu idéales pour la réalité mixte. Les applications de réalité mixte sont uniques par rapport au développement graphique 3D traditionnel dans la mesure où il y a deux écrans (c.-à-d. deux yeux) à restituer pour l’ensemble de la scène.

Les paramètres recommandés référencés ci-dessous peuvent être configurés automatiquement dans un projet Unity en tirant parti de la fenêtre d’optimisation MRTK.

Paramètres de fenêtre d’optimisation MRTK

Unity Profiler

Unity Profiler est un outil utile pour examiner les détails des performances de l’application au niveau image par image.

Temps passé sur le processeur

Exemple de graphique unity Profiler

Pour maintenir des fréquences d’images confortables (généralement 60 images par seconde), les applications doivent atteindre un temps d’exécution maximal de 16,6 millisecondes de temps processeur. Pour aider à identifier le coût de la fonctionnalité MRTK, Microsoft Mixed Reality Toolkit contient des marqueurs pour les chemins de code de boucle interne (par image). Ces marqueurs utilisent le format suivant pour vous aider à comprendre les fonctionnalités spécifiques utilisées :

[MRTK] className.methodName

Notes

Il peut y avoir des données supplémentaires après le nom de la méthode. Cela permet d’identifier les fonctionnalités potentiellement coûteuses exécutées de manière conditionnelle qui peuvent être évitées par de petites modifications du code de l’application.

Exemple de hiérarchie unity Profiler

Dans cet exemple, la hiérarchie a été développée pour montrer que la méthode UpdateHandData de la classe WindowsMixedRealityArticulatedHand consomme 0,44 ms de temps processeur pendant l’analyse. Ces données peuvent être utilisées pour aider à déterminer si un problème de performances est lié au code d’application ou à un autre endroit du système.

Il est fortement recommandé aux développeurs d’instrumenter le code d’application de la même manière. Les principaux domaines d’intérêt pour l’instrumentation du code d’application se trouvent dans les gestionnaires d’événements, car ces méthodes sont facturées à la boucle de mise à jour MRTK à mesure que les événements sont déclenchés. Les temps d’images élevés dans la boucle de mise à jour MRTK peuvent indiquer un code coûteux dans les méthodes de gestionnaire d’événements.

rendu Single-Pass instance

La configuration de rendu par défaut pour XR dans Unity est multi-passe. Ce paramètre indique à Unity d’exécuter l’intégralité du pipeline de rendu deux fois, une fois pour chaque œil. Cela peut être optimisé en sélectionnant Rendu instancené à passe unique à la place. Cette configuration tire parti des tableaux cibles de rendu pour pouvoir effectuer un appel de dessin unique qui s’exécute dans la cible de rendu appropriée pour chaque œil. En outre, ce mode permet d’effectuer tout le rendu en une seule exécution du pipeline de rendu. Ainsi, la sélection du rendu à instance unique comme chemin de rendu pour une application de réalité mixte peut gagner beaucoup de temps sur le processeur & GPU et constitue la configuration de rendu recommandée.

Toutefois, pour émettre un seul appel de dessin pour chaque maillage de chaque œil, l’instanciation GPU doit être prise en charge par tous les nuanceurs. L’instanciation permet au GPU de dessiner des appels sur les deux yeux. Les nuanceurs intégrés Unity ainsi que le nuanceur MRTK Standard par défaut contiennent les instructions d’instanciation nécessaires dans le code du nuanceur. Si vous écrivez des nuanceurs personnalisés pour Unity, ces nuanceurs doivent peut-être être mis à jour pour prendre en charge le rendu avec instance à passe unique.

Exemple de code pour le nuanceur personnalisé

struct appdata
{
    float4 vertex : POSITION;
    float2 uv : TEXCOORD0;

    UNITY_VERTEX_INPUT_INSTANCE_ID //Insert
};

struct v2f
{
    float2 uv : TEXCOORD0;
    float4 vertex : SV_POSITION;

    UNITY_VERTEX_OUTPUT_STEREO //Insert
};

v2f vert (appdata v)
{
    v2f o;

    UNITY_SETUP_INSTANCE_ID(v); //Insert
    UNITY_INITIALIZE_OUTPUT(v2f, o); //Insert
    UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); //Insert

    o.vertex = UnityObjectToClipPos(v.vertex);

    o.uv = v.uv;

    return o;
}

Paramètres de qualité

Unity fournit des présélections pour contrôler la qualité du rendu pour chaque point de terminaison de plateforme. Ces présélections contrôlent les fonctionnalités graphiques qui peuvent être activées, telles que les ombres, l’anticrénelage, l’éclairage global, etc. Il est recommandé de réduire ces paramètres et d’optimiser le nombre de calculs effectués pendant le rendu.

Étape 1 : Mettre à jour des projets Unity de réalité mixte pour utiliser le paramètre de niveau de qualité faible
Modifier>Paramètres du projet, puis sélectionnez la catégorie >Qualité Sélectionner une qualité faible pour la plateforme UWP

Étape 2 : Pour chaque fichier de scène Unity, désactivez l’illumination globale en temps réel
Fenêtre>Rendu>Paramètres >d’éclairageDécochez l’option Illumination globale en temps réel

Partage de mémoire tampon de profondeur (HoloLens)

Si vous développez pour la plateforme Windows Mixed Reality et en particulier HoloLens, l’activation du partage de mémoire tampon de profondeur sous paramètres XR peut faciliter la stabilisation de l’hologramme. Toutefois, le traitement de la mémoire tampon de profondeur peut entraîner un coût de performances, en particulier si vous utilisez le format de profondeur 24 bits. Par conséquent, il est vivement recommandé de configurer la mémoire tampon de profondeur avec une précision de 16 bits.

Si z-fighting se produit en raison du format de bits inférieur, vérifiez que le plan de découpage lointain de toutes les caméras est défini sur la valeur la plus faible possible pour l’application. Unity définit par défaut un plan de découpage lointain de 1 000 m. Sur HoloLens, un plan de découpage lointain de 50 m est généralement plus que suffisant pour la plupart des scénarios d’application.

Notes

Si vous utilisez le format de profondeur 16 bits, les effets requis de la mémoire tampon de gabarit ne fonctionnent pas, car Unity ne crée pas de mémoire tampon de gabarit dans ce paramètre. La sélection du format de profondeur 24 bits à l’inverse crée généralement une mémoire tampon de gabarit 8 bits, le cas échéant sur la plateforme graphique du point de terminaison.

Si vous utilisez un composant Mask qui nécessite la mémoire tampon de gabarit, envisagez d’utiliser RectMask2D à la place, ce qui ne nécessite pas la mémoire tampon de gabarit et peut donc être utilisé conjointement avec un format de profondeur de 16 bits.

Notes

Pour déterminer rapidement quels objets d’une scène n’écrivent pas visuellement dans la mémoire tampon de profondeur, vous pouvez utiliser l’utilitaire Render Depth Buffer sous les Paramètres de l’éditeur dans le profil de configuration MRTK.

Optimiser les données de maillage

Les paramètres Optimiser les données de maillage tentent de supprimer les attributs de vertex inutilisés au sein de votre application. Le paramètre effectue cette opération en exécutant chaque passe de nuanceur dans chaque matériau qui se trouve sur chaque maillage de la build. Cela est bon pour la taille des données de jeu et les performances d’exécution, mais peut considérablement entraver les temps de génération.

Il est recommandé de désactiver ce paramètre pendant le développement et de réactiver lors de la création de la build « Master ». Vous trouverez le paramètre sous Modifier>les paramètres> duprojet Lecteur>Autres paramètres>Optimiser les données de maillage.

Recommandations générales

Les performances peuvent être un défi ambigu et en constante évolution pour les développeurs de réalité mixte, et le spectre des connaissances permettant de rationaliser les performances est vaste. Il existe toutefois des recommandations générales pour comprendre comment aborder les performances d’une application.

Il est utile de simplifier l’exécution d’une application dans les éléments qui s’exécutent sur le processeur ou le GPU et d’identifier ainsi si une application est limitée par l’un ou l’autre des composants. Il peut y avoir des goulots d’étranglement qui couvrent à la fois les unités de traitement et certains scénarios uniques qui doivent être examinés avec soin. Toutefois, pour commencer, il est judicieux de comprendre où une application s’exécute le plus longtemps.

GPU limité

Étant donné que la plupart des plateformes pour les applications de réalité mixte utilisent le rendu stéréoscopique, il est très courant d’être limité par GPU en raison de la nature du rendu d’un écran « double large ». De plus, les plateformes de réalité mixte mobiles telles que HoloLens ou Oculus Quest seront limitées par la puissance de traitement processeur & GPU de classe mobile.

Lorsque vous vous concentrez sur le GPU, il existe généralement deux étapes importantes qu’une application doit effectuer chaque image.

  1. Exécuter le nuanceur de vertex
  2. Exécuter le nuanceur de pixels (également appelé nuanceur de fragments)

Sans une plongée approfondie dans le domaine complexe de l’infographie & pipelines de rendu, chaque étape du nuanceur est un programme qui s’exécute sur le GPU pour produire les éléments suivants.

  1. Les nuanceurs de vertex transforment les sommets de maillage en coordonnées dans l’espace d’écran (c’est-à-dire le code exécuté par sommet)
  2. Les nuanceurs de pixels calculent la couleur à dessiner pour un fragment de pixel et de maillage donné (c’est-à-dire l’exécution de code par pixel)

En ce qui concerne le réglage des performances, il est généralement plus utile de se concentrer sur l’optimisation des opérations dans le nuanceur de pixels. Une application peut avoir seulement besoin de dessiner un cube qui ne sera que de 8 sommets. Toutefois, l’espace d’écran occupé par le cube est probablement de l’ordre de millions de pixels. Ainsi, la réduction du code du nuanceur de 10 opérations peut permettre d’économiser beaucoup plus de travail si elle est réduite sur le nuanceur de pixels que sur le nuanceur de vertex.

C’est l’une des principales raisons pour tirer parti du nuanceur MRTK Standard , car ce nuanceur exécute généralement beaucoup moins d’instructions par pixel & vertex que le nuanceur Standard Unity tout en obtenant des résultats esthétiques comparables.

Optimisations du processeur Optimisations GPU
Logique de simulation d’application Opérations de rendu
Simplifier la physique Réduire les calculs d’éclairage
Simplifier les animations Réduire le nombre de polygones & nombre d’objets dessinables
Gérer le garbage collection Réduire le nombre d’objets transparents
Références de cache Éviter les effets de post-traitement/plein écran

Dessiner l’instanciation d’appel

L’une des erreurs les plus courantes dans Unity qui réduit les performances est le clonage des matériaux au moment de l’exécution. Si les GameObjects partagent le même matériau et/ou sont le même maillage, ils peuvent être optimisés en appels à dessin unique via des techniques telles que le traitement par lots statique, le traitement par lots dynamique et l’instanciation GPU. Toutefois, si les propriétés du développeur modifient le matériel d’un renderer au moment de l’exécution , Unity crée une copie clone du matériel affecté.

Par exemple, s’il y a 100 cubes dans une scène, un développeur peut vouloir affecter une couleur unique à chacun au moment de l’exécution. L’accès de renderer.material.color en C# permet à Unity de créer un nouveau matériau en mémoire pour ce renderer/GameObject particulier. Chacun des 100 cubes aura son propre matériel et, par conséquent, ils ne peuvent pas être fusionnés en un seul appel de dessin, mais au lieu de cela, ils deviendront 100 demandes d’appel de dessin du processeur vers le GPU.

Pour surmonter cet obstacle tout en attribuant une couleur unique par cube, les développeurs doivent tirer parti de MaterialPropertyBlock.

private PropertyBlock m_PropertyBlock ;
private Renderer myRenderer;

private void Start()
{
     myRenderer = GetComponent<Renderer>();
     m_PropertyBlock = new MaterialPropertyBlock();
}

private void ChangeColor()
{
    // Creates a copy of the material once for this renderer
    myRenderer.material.color = Color.red;

    // vs.

    // Retains instancing capability for renderer
    m_PropertyBlock.SetColor("_Color", Color.red);
    myRenderer.SetPropertyBlock(m_PropertyBlock);
}

Outils de performances Unity

Unity fournit d’excellents outils de performances intégrés à l’éditeur.

Si vous estimez le compromis entre les performances approximatives entre un nuanceur et un autre, il est utile de compiler chaque nuanceur et d’afficher le nombre d’opérations par étape du nuanceur. Pour ce faire, sélectionnez une ressource de nuanceur et cliquez sur le bouton Compiler et afficher le code . Cette opération compile toutes les variantes du nuanceur et ouvre Visual Studio avec les résultats. Remarque : Les résultats statistiques produits peuvent varier en fonction des caractéristiques activées sur les matériaux utilisant le nuanceur donné. Unity compile uniquement les variantes de nuanceur utilisées directement dans le projet actuel.

Exemple de statistiques de nuanceur Unity Standard

Unity Standard Shader Statistics 1

Exemple de statistiques de nuanceur MRTK Standard

Statistiques du nuanceur standard MRTK 2

Voir aussi

Unity

Windows Mixed Reality

Oculus

Optimisation du maillage