Deferred+ : culling et rendu nouvelle génération pour Dawn Engine

Introduction

Afin de pouvoir répondre à des besoins grandissants de réalisme visuel et de vitesse d’exécution, nous avons testé un nouveau système de culling et de rendu en vue de son usage avec le Dawn Engine. Il s’agit de l’une des nombreuses recherches menées par notre équipe de R&D interne, LABS, pour l’univers de Deus Ex. Cependant, le système ne sera pas exploité par le prochain titre, Deus Ex: Mankind Divided. L’un des principaux objets de cette étude est le développement d’un système compatible avec la pipeline d’assets en place qui permettrait des itérations rapides durant la production du jeu. Notre système de culling allie la faible latence et l’overhead contenu d’une approche basée sur un tampon de profondeur hiérarchique [Hill et Collin 11] à la précision de pixel de requêtes d’occlusion matérielle par GPU conventionnelles. Il délimite de manière efficace des environnements complexes et hautement dynamiques tout en restant compatible avec des assets de mesh standard. Notre système de rendu repose sur une approche pratique du concept de texturage différé [Reed 14] et prend en charge des matières très diverses et complexes de façon efficace tout en recourant à des assets de texture conventionnels. Le culling et le système de rendu tirent parti de nouvelles capacités graphiques offertes par DirectX 12, notamment le rendu indirect amélioré et le nouveau modèle de liaison de ressource de shader.

Culling

Notre système de culling est en partie basé sur les concepts présentés par [Haar et Aaltonen 15], dans lesquels le tampon de profondeur de l’image précédente est utilisé pour acquérir une première visibilité, et les potentiels faux négatifs sont retestés avec le tampon de profondeur actualisé de l’image actuelle. Ainsi, on ne calcule pas la géométrie d’occlusion dédiée qui peut être difficile à générer dans les environnements naturels, par exemple. Cependant, au lieu d’adopter une approche basée sur un tampon de profondeur hiérarchique et de subdiviser des meshes en petites partitions, on applique un concept dans l’esprit de [Kubisch et Tavenrath 14], qui repose sur les capacités de test anticipé de profondeur-pochoir du matériel graphique grand public moderne. Pour cela, les volumes englobants des objets occlus sont rendus via le tampon de profondeur reprojeté de l’image précédente et le shader de pixel associé est forcé d’utiliser le test anticipé de profondeur-pochoir. De cette façon, seuls les fragments visibles marquent dans un tampon de GPU commun à un endroit, spécifique à chaque instance de mesh, que l’instance correspondante est visible. Un shader de calcul génère ensuite, à partir de l’information de visibilité acquise, les données utilisées pour le rendu indirect. Comme proposé par [Haar et Aaltonen 15], les objets occlus sont retestés avec le tampon de profondeur actualisé de l’image actuelle pour éviter de passer à côté de faux négatifs. La figure 1 récapitule les étapes et ressources requises.

 

Figure 1. Présentation du système de culling. Les flèches à gauche de chaque étape du culling représentent les données entrantes. Les flèches à droite, les données sortantes. Les couleurs sont celles des tampons de GPU correspondants.

 

Puisque les scènes, construites avec la pipeline d’assets actuelle du Dawn Engine, sont de toute façon constituées de blocs modulaires relativement petits, cette approche pourrait nous dispenser d’un système subdivisant les meshes en plus petites partitions. En remplaçant le culling basé sur un tampon de profondeur hiérarchique par l’approche de test anticipé de profondeur-pochoir, nous avons pu atteindre dans un environnement de jungle naturel sans partitions de mesh des taux de culling et temps d’affichage en moyenne 2,3 et 1,6 fois plus rapides respectivement.

Rendu

Dans les jeux modernes, il est important d’utiliser un système de rendu capable de gérer des matières de surface réalistes et une géométrie de mesh de plus en plus complexe. Les systèmes de rendu direct prennent en charge une grande variété de matières mais souffrent d’overdraw ou requièrent une passe préliminaire de profondeur qui peut être coûteuse dans le cas de meshes comportant un grand nombre de triangles, une tesselation matérielle par GPU, un test alpha ou un skinning avec shader de sommet. Les systèmes de rendu différé parviennent à s’exécuter de façon efficace sans passe préliminaire de profondeur mais ne prennent en charge qu’un nombre limité de matières et requièrent donc souvent un rendu direct supplémentaire pour varier davantage les matières. Notre approche pratique du texturage différé allie les avantages des deux systèmes de rendu en prenant en charge une grande variété de matières tout en n’effectuant qu’une passe de géométrie. Nous allons plus loin que le rendu différé traditionnel et dissocions totalement la géométrie d’un côté et la matière et l’éclairage de l’autre. Lors d’une première passe de géométrie, toutes les instances de meshes qui passent l’étape de culling du GPU sont rendues indirectement et leurs attributs de sommet sont écrits et compressés dans un ensemble de tampons de géométrie. Aucune opération spécifique à une matière ou récupération de texture n’est effectuée (sauf pour le test alpha et certains types de techniques de tessellation matérielle par GPU). Une passe plein écran transfère ensuite un ID de matière depuis les tampons de géométrie vers un tampon de profondeur 16 bits. Enfin, lors de la passe de shading pour chaque matière, est rendu un rectangle d’espace écran qui contient les limites de tous les meshes visibles. On donne à la profondeur des sommets du rectangle une valeur qui correspond à l’ID de matière actuellement traité et on effectue le test anticipé de profondeur-pochoir pour rejeter les pixels d’autres matières. Toutes les matières standard qui utilisent le même shader et la même disposition de liaison de ressource sont rendues dans une même passe via des textures indexées de façon dynamique. À ce stade, le rendu et l’éclairage spécifiques à la matière (par ex. tuilé [Billeter et autres 13] ou partitionné [Olsson et autres 12]) sont traités simultanément. La figure 2 récapitule le procédé de rendu.

 

Figure 2. Présentation du système de rendu.

 

Puisque, d’une manière générale, la bande passante de mémoire du matériel grand public est bien plus restreinte que la puissance de calcul, il est important de limiter autant que possible la taille des tampons de géométrie. Par conséquent, les attributs des sommets doivent être stockés dans un format compressé. Nous stockons les coordonnées des textures dans 2x 16 bits en ne conservant que leur partie fractionnelle après interpolation. Puisque les dérivés des coordonnées de la texture originale sont stockés à côté, aucune démarcation ne sera visible plus tard. En théorie, les dérivés peuvent être reconstruits dans la passe de shading en utilisant les coordonnées de la texture voisine mais, dans le cas d’arêtes de géométrie, les coordonnées de la texture voisine appropriée ne pouvant pas toujours être obtenues, des artefacts seront visibles. C’est particulièrement notable lors des mouvements de caméra avec un feuillage alpha-testé dense. Par conséquent, nous avons décidé de stocker les coordonnées des textures à côté de leurs dérivés. Pour cela, nous traitons les dérivés dans les sens X- et Y-, comme des vecteurs 2D. En dissociant la longueur du vecteur et son orientation, la longueur du vecteur peut être stockée en 2x 16 bits et l’orientation en 2x 8 bits, ce qui laisse assez de précision pour le filtrage de texture anisotrope. Nous avons tenté de stocker l’espace de tangente (tangente, bitangente, normale) en tant que quaternion en 32 bits, selon [Mc Auley 15], mais avons abandonné cette approche en raison d’un facettage visible sur les surfaces lisses brillantes. À la place, nous stockons l’espace de tangente en tant que représentation axe-angle, avec la normale stockée comme un axe en utilisant un encodage de vecteur normal d’octaèdre [Meyer et autres 10], et la tangente stockée comme un angle. De cette façon, nous pouvons stocker l’intégralité de l’espace de tangente en 32 bits et atteindre la même qualité qu’en stockant l’espace de tangente non compressé en 3x 30 bits. Il convient de noter que cette méthode requiert environ la moitié du nombre d’instructions pour encoder l’espace de tangente en 32 bits qu’en convertissant une matrice TBN en quaternion de façon mathématiquement stable et précise et en la stockant en 32 bits.

Avantages et inconvénients

Vous trouverez ci-dessous un récapitulatif des principaux avantages et inconvénients du système de culling et rendu présenté.

Culling

Avantages:

  • La précision de pixel est la même qu’avec les requêtes d’occlusion matérielle par GPU conventionnelles, mais sans problèmes de latence (popping).
  • Les objets d’occlusion hautement dynamiques, complexes et alpha-testés sont pris en charge sans besoin de créer et de rendre une géométrie d’occlusion dédiée.
  • Le culling est très efficace, même sans partition de mesh pour les scènes composites modulaires, et donc totalement compatible avec les pipelines d’assets standard.
  • Le système de culling est assorti d’un overhead basse performance.
  • Le nombre de draw calls est massivement réduit (gain de performance même avec des API graphiques à faible overhead comme DirectX 12 et Vulkan).

Inconvénients:

  • Les commandes draw ne sont plus dans un ordre déterministe (les surfaces quasi coplanaires peuvent causer du z-fighting et doivent être évitées).
  • Le tri de profondeur des draw calls n’est plus donné, ce qui provoque davantage d’overdraw (avec deferred+, moins problématique en raison de la passe de géométrie légère et de la grande efficacité du culling).

 

Rendu

Avantages:

  • Grâce à la passe de géométrie légère, la passe préliminaire de profondeur n’est plus requise.
  • L’utilisation du warp GPU pour l’application des matières et des lumières est considérablement meilleure qu’avec le shading direct partitionné [Olsson et autres 12], donc les petits triangles sont moins problématiques et la tessellation matérielle par GPU est nettement plus performante.
  • Le système de rendu unifié, contrairement au rendu différé, peut gérer une grande variété de matières efficacement.
  • La dissociation complète du traitement de la géométrie et du rendu des matières et de la lumière génère moins de permutations de shader et accélère l’itération durant la production du jeu.
  • En dissociant le traitement de la géométrie et le rendu de la matière, les échanges des ressources du GPU sont nettement réduits.
  • Contrairement à un système avec récupération d’attributs de sommet différée [Burns et Hunt 13], l’information de la géométrie n’est récupérée qu’une fois par image de façon cohérente et ménageant le cache.
  • Les données de texture compressées n’ont pas besoin d’être décompressées dans la mémoire du GPU comme avec le rendu différé, donc la bande passante de mémoire des textures est nettement moins sollicitée.
  • Les tampons de géométrie modifiée contiennent des informations utiles qui ne sont pas disponibles avec le rendu différé :
    • Dérivés de coordonnée de texture (corrige les problèmes de mip-mapping avec les autocollants différés)
    • Normales de sommet (améliore les techniques d’occlusion ambiante dans l’espace écran)
    • Tangentes de sommet (éclairage anisotrope)
  • Le système est indépendant des fonctionnalités graphiques spécifiques des fabricants et compatible avec toute la gamme de matériels graphiques acceptant DirectX 12 (quand la plage de textures indexées de façon dynamique prise en charge est trop faible, les applications peuvent se rabattre sur le rendu séparé de matières communes).

Inconvénients:

  • Les attributs de sommet sont beaucoup plus limités qu’avec les techniques de rendu traditionnelles.
  • Les objets transparents doivent être gérés séparément.
  • L’anticrénelage reste difficile à gérer.

Résultats

Pour illustrer les résultats, nous avons utilisé des scènes du jeu Deus Ex: Mankind Divided que nous avons converties dans un format que nous pouvions charger et rendre dans un cadre expérimental basé sur DirectX 12. Notre machine de test est dotée d’une carte graphique AMD Radeon R9 390 et la résolution de l’écran est de 1920×1080. Dans la vidéo ci-dessous, vous pourrez voir une scène rendue avec 1024 lumières de zone sphériques dynamiques recourant à l’éclairage partitionné. Afin de simuler les objets dynamiques pour le culling d’occlusion, la lumière de zone est rendue en tant que sphère émettrice. Pour pouvoir comparer notre système de rendu à un système de rendu direct partitionné tout en utilisant un culling par GPU, toutes les matières, excepté la matière de sphère émettrice, utilisent le même code de shading et sont rendues pour deferred+ dans des passes séparées à l’aide de la méthode de rejet profondeur-pochoir décrite. Nous avons également utilisé, pour toutes les textures de matière, un filtrage de texture anisotrope 8x afin de nous assurer que notre méthode de compression de dérivé de texture ne génère pas d’artefacts. Les temps d’affichage et de GPU affichés sur le côté gauche de l’écran sont mesurés en millisecondes et les compteurs de culling au centre de l’écran ne prennent en compte que les meshes ayant été tronqués sur CPU.

Au début de la vidéo, nous activons et désactivons le culling par GPU, ce qui démontre un gain de performance d’environ 1,44 ms et une efficacité de culling d’environ 80 %. Ensuite, nous affichons en rouge les arêtes de délimitation des objets ayant fait l’objet du culling. Enfin, nous comparons les temps de rendu de deferred+ à ceux du rendu direct partitionné et démontrons que deferred+ s’exécute environ 4,31 ms plus vite tout en produisant des résultats à la qualité pratiquement équivalente. En activant la tessellation matérielle par GPU adaptative et en utilisant un facteur de tessellation maximal de 5, deferred+ s’exécute même 24,98 ms plus vite. Dans des conditions de jeu réalistes, avec des matières et des éclairages plus complexes (différents types de lumières, mappage des ombres), le gain de performance de deferred+ devrait être encore plus évident.

Conclusion

Nous avons présenté un système de culling et de rendu de scènes complexes et hautement dynamiques qui tire parti des nouvelles capacités graphiques offertes par DirectX 12. Le système de culling démontre une grande efficacité, même pour les assets de mesh traditionnels non partitionnés, et ce avec un overhead faible. À qualité comparable, le système de rendu surclasse les systèmes de rendu direct partitionné, particulièrement quand des techniques de tessellation matérielle par GPU sont employées. Il est totalement compatible avec les assets de texture conventionnels, indépendant des fonctionnalités graphiques spécifiques des fabricants et compatible avec toute la gamme de matériels graphiques acceptant DirectX 12. En associant les systèmes de culling et de rendu proposés, il est possible de rendre une scène complexe entière en quelques draw calls.

https://www.youtube.com/watch?v=plFBGkAEAxE

Remerciements

Nous tenons à remercier Francis Maheux, qui nous a fourni les assets du prototype, et Samuel Delmont et Uriel Doyon pour leur aide précieuse sur l’implémentation elle-même. Par ailleurs, nous souhaitons remercier Eidos-Montréal et Square Enix, qui nous ont permis de rendre publics les résultats de ce projet de recherche.

Avec Wolfgang Engel, Eidos-Montréal LABS travaille sur un article détaillé consacré à notre travail pour le livre GPU Zen, à paraître en 2017.

 

Eidos-Montréal cherche constamment de nouveaux talents pour nous aider à façonner la prochaine génération de jeux. Si vous pensez être à la hauteur, n’hésitez surtout pas à nous contacter. Consultez les postes disponibles chez Eidos-Montréal et rejoignez nos talentueuses équipes!

Références

[Billeter et autres 13] M. Billeter, O. Olsson et U. Assarsson. « Shading direct tuilé ». GPU Pro 4 : Techniques de rendu avancées. A. K. Peters, p. 99–114. 2013.

[Burns et Hunt 13] C. A. Burns et W. A. Hunt. “Tampon de visibilité : une approche du shading différé adaptée au cache”. Journal of Computer Graphics Techniques, Vol. 2, No. 2. 2013.

[Haar et Aaltonen 15] U. Haar et S. Aaltonen. “Pipelines de rendu par GPU”. Discussions lors de l’ACM SIGGRAPH 2015, ACM, Los Angeles, USA, SIGGRAPH ’15.

[Hill et Collin 11] S. Hill et D. Collin. “Visibilité dynamique et pratique dans les jeux”. GPU Pro 2, A K Peters, 2011, p. 329-347.

[McAuley 15] S. McAuley. “Rendu du monde de Far Cry 4”. Discussions lors de la Game Developer Conference 2015, San Francisco. 2015.

[Meyer et autres 10] Q. Meyer, J. Süßmuth, G. Sußner, M. Stamminger et G. Greiner. “Des vecteurs normaux à virgule flottante”. Eurographics Symposium on Rendering, Vol. 29, No. 4. 2010.

[Olsson et autres 12] O. Olsson, M. Billeter et U. Assarson. « Shading direct et différé partitionné ». HPG 12 : Compte-rendu de la quatrième conférence ACM SIGGRAPH/ Eurographics sur les graphismes haute performance, ACM, p. 87–96. 2012.

[Kubisch et Tavenrath 14] C. Kubisch et M. Tavenrath. “Techniques de rendu de scène avec OpenGL 4.4”. Présentation de la GPU Technology Conference 2014, NVIDIA, San Jose, USA, page 50.

[Reed 14] N. Reed. “Texturage différé”. Article de blog, 2014, http://www.reedbeta.com/blog/2014/03/25/deferred-texturing

Llama