Cherchez Unity

Une scène, 10 optimisations graphiques pour les développeurs de consoles

Last updated: January 2019

What you will get from this page: Console graphics optimization tips, courtesy of Unity’s Rob Thompson, a console graphics developer (who les a présentées au cours d'Unite), and our demo team. These optimizations were made to an especially difficult scene to ensure smooth 30fps performance.

Qualité AAA avec les pipelines de rendu Scriptable de Unity

The Book of the Dead (in this article we refer to it as BOTD) was produced by Unity's demo team. It’s a real-time rendered animated short, essentially created to test-drive and show off the capabilities of the new (and still experimental) Scriptable Render Pipelines (SRP). The SRPs allow you to code the core of your render loop in C#, thereby giving you much more flexibility for customizing how your scene is drawn to make it specific to your content.

console scriptable rendering pipeline

There are two SRPs available: the SRP haute-définition (HDRP) which offers all of the features that you'd expect from a modern, AAA quality, high fidelity renderer, while the SRP léger (LWRP) maintains responsive performance when scaling for mobile. BOTD uses the HDRP, and you can find advanced learning resources for the SRPs at the end of this article.

All of the assets and all of the script code for BOTD are disponibles in the Asset Store.

Une optimisation majeure pour atteindre 1080p à 30fps (ou mieux) sur les consoles

L'objectif de la démo était d'offrir une expérience interactive permettant aux utilisateurs de se promener à l'intérieur de cet environnement et de le découvrir d'une manière qui leur était familière du point de vue des jeux traditionnels AAA. Plus précisément, nous voulions montrer BOTD fonctionnant sur Xbox One et PS4. Nous avions des exigences de performance de 1080p à 30 images par seconde, ou mieux.

Comme il s'agit d'une démo, et non d'un jeu complet, les optimisations ont surtout porté sur le rendu.

En général, les performances de BOTD sont assez constantes car il n'y a pas de scènes où, par exemple, des milliers de particules prennent soudainement vie ou de nombreux personnages animés apparaissent.

Pour commencer, Rob et l'équipe de démo ont trouvé la vue qui fonctionnait le moins bien en ce qui concerne la charge du GPU, en voici une capture d'écran :

console scriptable rendering pipeline

Ce qui se passe dans la scène est à peu près constant ; ce qui varie, c'est ce qui est dans la vue de la caméra. S'ils pouvaient faire des économies sur cette scène, ils augmenteraient en fin de compte les performances pendant toute la durée de la démo.

La raison pour laquelle cette scène a mal fonctionné est qu'il s'agit d'une vue extérieure du niveau depuis le centre de la scène. La grande majorité des actifs de la scène sont dans le tronc de la caméra. Il en résulte un grand nombre de requêtes.

En bref, voici comment cette scène a été rendue :

  • Avec le HDRP
  • La plupart des textures créées par l'artiste sont des cartes entre 1K et 2K, avec un maximum à 4K.
  • Les fonctions Baked Occlusion et Baked GI sont utilisées pour l'éclairage indirect, et une source de lumière dynamique unique sert pour l'éclairage direct du soleil.
  • Il émet environ quelques milliers de requêtes à tout moment (requêtes et calculs d'envois de shaders).
  • Au début de l'optimisation, la vue était liée par GPU sur PS4 Pro à environ 45 millisecondes.
Ce que le GPU Frame a montré avant l'optimisation

Au début de l'optimisation, Rob et l'équipe ont analysé la trame GPU étape par étape, et ont vu les performances suivantes :

  • The Gbuffer was at 11ms (you can find a description of the Gbuffer layouts for HDRP in cet article by Unity lead graphics developer Sebastien Lagarde)
  • Les vecteurs de mouvement et l'occlusion ambiante de l'espace de l'écran ont été assez rapides, à respectivement 0,25 et 0,6 ms.
  • Les cartes d'ombres de la projection d'ombres directionnelles avec des lumières dynamiques sont arrivées à 13,9 ms, ce qui est énorme.
  • L'éclairage différé était à 4,9 ms.
  • La diffusion atmosphérique était à 6,6 ms.

Voici à quoi ressemblait leur cadre GPU, du début à la fin :

console GPU frame

Comme vous pouvez le voir, ils sont à 45 millisecondes et les deux lignes verticales orange indiquent où ils devaient être pour atteindre respectivement 30 et 60 images par seconde.

10 façons d'optimiser le rendu pour Book of the Dead

Contrôle du nombre de lots

La performance du CPU n'était pas un gros problème pour l'équipe parce que BOTD est une démo, pas un jeu, ce qui signifie l'absence de la complexité du code script qui va avec tous les systèmes qui sont nécessaires pour un jeu complet. Encore une fois, le souci principal était d'optimiser le travail de rendu.

However keeping the batch count low is still a valuable tip for any platform. The team did this by using Détermination des surfaces cachées, and, primarily, Instances GPU. Avoid using Dynamic batching on consoles unless you are sure it’s providing a performance win.

Dans ce cas, l'instanciation GPU était la méthode la plus utile. Sans elle, il y aurait eu 4500 lots pour cette scène. Elle a permis de réduire ce nombre à 1832.

Un autre point à retenir : le nombre d'actifs individuels utilisés pour créer cette scène est en fait très faible. En utilisant des ressources de bonne qualité et en les plaçant intelligemment, l'équipe a créé des scènes complexes qui n'ont pas l'air répétitives et a maintenu le nombre de lots à un faible niveau avec l'instanciation GPU.

Voici la scène sans instance.

console scriptable rendering pipeline

Et voici des exemples :

console scriptable rendering pipeline

Utiliser les multiples noyaux disponibles sur les consoles.

La Xbox One et la PS4 sont tous deux des périphériques multi-cœurs, et afin d'obtenir les meilleures performances CPU, nous devons essayer de garder ces cœurs occupés tout le temps.

If you follow Unity news, you’ll know that Unity is currently developing un système multithread hautes performances, that will make it possible for your game to fully utilise the multicore processors available today and in the future. (Very) briefly, this system comprises three sub-systems: the Système de composantes d'entité, the système de tâches C# and the Burst Compiler.

Le nouveau système multithreaded est encore en mode expérimental. Dans le système graphique de Unity, vous pouvez l'essayer via le mode Graphics Jobs (encore une fois, en mode expérimental). Vous trouverez les commandes des tâches graphiques sous Player Settings -> Other Settings.

console Graphics Jobs

Le mode Graphics Jobs vous permet d'optimiser les performances dans presque toutes les circonstances sur la console, à moins que vous ne n'ayez besoin d'appeler de nombreux lots. Il en existe deux types :

  • Legacy Jobs, disponible sur PS4 et DirectX 11 pour Xbox One
    • Permet de réduire la pression sur le thread principal en répartissant le travail sur d'autres noyaux. Sachez que dans de très grandes scènes il peut y avoir un goulot d'étranglement dans le « Render Thread ², un thread que Unity utilise pour parler à l'API graphique des détenteurs de plateforme.
  • Native Jobs, disponible sur PS4, et DirectX 12 pour Xbox One (à venir)
    • Répartit le plus de travail sur les cœurs disponibles et est la meilleure option pour les grandes scènes.
    • Devrait toujours être la meilleure option à partir de 2018.2 (dans les versions 2018.1 ou antérieures, il peut attribuer plus de tâches au thread principal, provoquant des régressions de performance).

Utiliser les outils d'analyse de la performance du porteur de la plateforme

Microsoft and Sony provide des outils essentiels for analyzing your project’s performance both on the CPU and on the GPU. These tools are available to you for free if you're working on console. Learn them early on and keep using them throughout your development cycle. Pix for Xbox One is Microsoft's offering and the Razor Suite is Sony's; as Rob says, they are your main tools in your arsenal when it comes to optimization on these platforms.

Profiler vos effets post-processus

Rob dit qu'il a profilé des jeux Unity sur PS4 lorsque jusqu'à ⅔ du framerate a été pris par le post-traitement, à l'insu des développeurs. Ceci est souvent causé par le téléchargement des ressources de post-traitement de l'Asset Store qui sont écrites principalement pour PC. Ces ressources semblent bien fonctionner sur la console, mais en fait les caractéristiques de performance sont vraiment mauvaises.

So, when en appliquant ces effets, profile how long they take on the GPU, and iterate until you find a happy balance between visual quality and performance. And then, leave them alone, because they comprise a static cost in every scene, meaning you know how much GPU bandwidth is left over to work with.

Évitez d'utiliser la tesselation (sauf pour une très bonne raison)

En général, il n'est pas conseillé d'utiliser la tesselation dans les graphismes des jeux de console. Dans la plupart des cas, il est préférable d'utiliser les ressources équivalentes créées par l'artiste que de les tesseller sur le GPU.

Mais dans le cas de BOTD, la tessellation était nécessaire pour rendre l'écorce des arbres.

console tesselation

Le déplacement tessellé leur a permis d'ajouter les évidements profonds et les détails complexes dans la géométrie qui s'auto-ombrageront correctement, d'une manière impossible avec la cartographie normale.

Comme les arbres sont des objets « héros » dans une grande partie de BOTD, cela était justifié. Ceci a été fait avec le même maillage que celui utilisé sur les arbres à LOD 0 et LOD 1. La différence entre les deux est simplement que le déplacement tessellé a été réduit de sorte qu'il n'est plus en vigueur au moment où ils ont atteint LOD 1.

Viser un taux d'occupation sain du front d'onde en tout temps sur le GPU.

OK, c'est un gros morceau, mais l'occupation du front d'onde vaut vraiment la peine d'être comprise.

Vous pouvez considérer un front d'onde comme un paquet de tâches GPU. Lorsque vous soumettez une requête au GPU, ou une répartition de shader de calcul, ce travail est alors divisé en plusieurs fronts d'onde et ces fronts d'onde sont répartis dans tous les SIMD à l'intérieur de toutes les unités de calcul qui sont disponibles sur le GPU.

console wave front occupancy

Chaque SIMD a un nombre maximum de fronts d'onde qui peuvent fonctionner à tout moment et donc, nous avons un nombre maximum total de fronts d'onde qui peuvent fonctionner en parallèle sur le GPU en tout point. Le nombre de fronts d'onde que nous utilisons est appelé occupation du front d'onde, et c'est une mesure très utile pour comprendre dans quelle mesure vous utilisez le potentiel de parallélisme du GPU de manière optimale.

Pix et Razor peuvent montrer l'occupation du front d'onde dans les moindres détails. Les graphiques ci-dessus proviennent de Pix for Xbox One. Sur la gauche, nous avons un exemple de bonne occupation du front d'onde. Le long du bas de la bande verte, on peut voir des fronts d'ondes de nuanceurs de vertex et, au-dessus, en bleu, des fronts d'ondes de nuanceurs de pixels.

Sur la droite cependant, on peut voir qu'il y a un problème de performance. Il y a beaucoup de travail de shader de vertex qui n'entraîne pas beaucoup d'activité du shader de pixel. C'est une sous-utilisation du potentiel du GPU. Ceci nous amène au prochain conseil d'optimisation.

Comment cela se fait-il ? Ce scénario est typique lorsque nous faisons un travail de shader de vertex qui n'aboutit pas à des pixels.

Utiliser Depth Prepass

D'autres analyses sur Pix et Razor ont montré que l'équipe recevait beaucoup d'overdraw pendant la passe Gbuffer. C'est particulièrement mauvais sur la console lorsque vous regardez des objets testés en alpha.

Sur la console, si vous émettez des instructions d'élimination des pixels ou si vous écrivez directement en profondeur dans votre shader de pixel, vous ne pouvez pas profiter d'un rejet précoce de la profondeur. Ces fronts d'onde de shader de peixel s'exécutent dans tous les cas.

La solution était d'ajouter un Depth Prepass. Cela implique de rendre la scène à l'avance en profondeur uniquement, en utilisant des shaders très légers, qui peuvent alors être la base d'un rejet de profondeur plus intelligent lorsque vos shaders Gbuffer plus lourds sont liés.

The HDRP now includes a Depth Prepass for all alpha tested objects, but you can also switch on a full Depth Prepass if you want. The settings for controlling HDRP, what render passes are used, and features enabled, are all made available via the .

Si vous effectuez une recherche dans un projet HDRP pour le pipeline de rendu HD, vous trouverez un grand nombre de cases à cocher qui contrôlent tout ce que fait le HDRP.

Pour BOTD, l'utilisation de Depth Prepass a été une grande victoire pour le GPU, mais n'oubliez pas qu'il y a une contrpartie à ajouter plus de lots pour à orienter vers le CPU.

Réduire la taille de vos cibles de rendu de mappage des ombres

Comme nous l'avons mentionné plus haut, les ombres portées de cette scène sont générées contre une seule ombre projetant une lumière directionnelle. Quatre divisions de la carte d'ombres ont été utilisées et au départ, elles étaient rendues sur une carte d'ombres 4K à une profondeur de 32 bits, car c'est la valeur par défaut pour les projets HDRP. Lors du rendu sur les cartes d'ombres, la résolution de la carte d'ombres est presque toujours le facteur limitant ; ceci a été confirmé par des analyses dans Pix et Razor.

Réduire la résolution de la carte des ombres était la solution évidente, même si cela pouvait avoir un impact sur la qualité.

The shadow map resolution was dropped to 3k, which provided a perfectly acceptable trade-off against performance. The demo team also added an option specifically to allow developers to render to 16-bit depth Shadow maps. If you want to give that a go for yourself le the project assets.

Enfin, en changeant la résolution de leur carte d'ombres, ils ont aussi dû modifier certains réglages de la lumière.

Reduce size of shadow

À ce stade, l'équipe avait fait ses révisions de cartes d'ombres et repositionné sa caméra de cartographie d'ombres pour essayer d'obtenir la meilleure utilisation possible de la nouvelle résolution réduite dont elle dispose maintenant. Qu'ont-ils fait ensuite ?

Appelez seulement la dernière carte d'ombres (la plus dézoomée) divisée une seule fois sur la charge de niveau

Comme la caméra de cartographie de l'ombre ne bouge pas beaucoup,cela pourrait suffire. La division la plus dézoomée est généralement utilisée pour rendre les ombres les plus éloignées de la caméra.

Ils n'ont pas constaté de baisse de qualité. L'optimisation s'est avérée très intelligente, car elle leur a permis d'économiser du temps d'images par seconde sur le GPU et de réduire le nombre de lots sur le CPU.

Après cette série d'optimisations, la phase de création de la carte d'ombres est passée de 13ms à un peu moins de 8ms, le passage de l'éclairage de 4,9ms à 4,4ms et celui de l'atmosphérique de 6,6ms à 4,2ms.

L'équipe en était là à la fin de l'optimisation du mappage des ombres. Il ont maintenant atteint les limites d'un fonctionnement à 30 images par seconde sur PS4 Pro.

console GPU frame

Utiliser Async Compute

Async Compute is a method available for minimizing periods of underutilization on the GPU with useful shader de calcul work. It’s currently only supported on PS4, but coming to DX12 for Xbox One very soon. It's accessible through Unity's Command Buffer interface. It's not just exclusively for the SRP but is primarily aimed at it. Code examples are available in the BOTD assets, or look at the HDR PSOS.

La phase de profondeur seule, qui est ce que vous faites avec le mappage des ombres, est traditionnellement un point où vous n'utilisez pas pleinement le potentiel du GPU. Async Compute vous permet de déplacer votre travail de shader de calcul pour l'exécuter en parallèle de votre file d'attente graphique, utilisant ainsi des ressources que la file d'attente graphique sous-utilise.

BOTD utilise Async Compute pour sa liste de lumière carrelée qui fait partie de l'éclairage différé, ce qui se fait principalement avec des shaders de calcul sur console en HDRP. Il l'utilise également pour ses calculs SSAO. Ces deux éléments se chevauchent avec le rendu de la carte d'ombres pour combler les lacunes dans l'utilisation du front d'onde.

For a run-through of some conceptual code where Async Compute is employed, tune into la session Unite de Rob at 35:30.

Plus de ressources

Dites-nous si vous avez aimé ce contenu !

Oui, continuez comme ça Ça pourrait être mieux
Compris

Ce site utilise des cookies dans le but de vous offrir la meilleure expérience possible. Consultez la page de politique des cookies pour en savoir plus.