Combien de polygones dans une scène le matériel moderne peut-il atteindre tout en maintenant en temps réel et comment y arriver?

11

Une question assez basique, à certains égards, mais à laquelle beaucoup de gens, moi y compris, ne connaissent pas vraiment la réponse. Les fabricants de GPU citent souvent des nombres extrêmement élevés, et l'écart entre les nombres de polygones que divers moteurs de jeu prétendent prendre en charge s'étend souvent sur plusieurs ordres de grandeur, puis dépend encore fortement de nombreuses variables.

Je sais que c'est une question large et à peu près ouverte, et je m'en excuse, je pensais simplement que ce serait une question intéressante à poser ici.

Llamageddon
la source
2
Je ne pense pas que la question soit nécessairement trop ouverte, mais toute réponse numérique sera fausse dans les 12 mois.
Dan Hulme
@DanHulme Oui, mais les approches utilisées pour atteindre ce type d'efficacité restent les mêmes. Et quand ce n'est pas le cas, j'ai vu des questions nécessitant une mise à jour périodique des réponses sur d'autres sites stackexchange, donc je pense que c'est bien.
Llamageddon
7
C'est vraiment impossible de répondre. Tout d'abord, qu'est-ce que le «temps réel» - 60 ips? 30? Moins? Deuxièmement, la réponse variera énormément en fonction du GPU dont vous disposez et de la résolution à laquelle vous effectuez le rendu. Troisièmement, la réponse variera énormément en fonction des détails du fonctionnement du rendu. Les limites de la complexité des scènes sont plus compliquées que le seul nombre de polygones en soi, mais impliquent des choses telles que le nombre d'appels de dessin, les changements d'état, les passes de rendu, etc., qui sont affectés par le fonctionnement du moteur, la façon dont les artistes ont construit le scène, et ainsi de suite ...
Nathan Reed
1
@Llamageddon Compte tenu de vos commentaires, je ne sais pas trop ce que vous demandez réellement. D'une part, le titre de votre question est assez clair (géométrie maximale et comment le faire), mais comme Nathan l'a souligné, il est impossible de répondre. D'autre part, dans vos commentaires, vous dites que vous voulez savoir comment minimiser le coût par image. C'est une question extrêmement large, car vous pourriez améliorer / optimiser vos shaders, graphes de scène, modèles, textures, utilisation de l'API, tout simplement tout ce qui fait une partie de votre rendu. Vous pourriez probablement écrire des livres entiers à ce sujet (si ce n'est déjà fait par quelqu'un).
Nero
1
c'est un peu tard, mais ici vous pouvez voir un maillage STATIQUE avec 24.000.000 sommets dans Blender. Et je peux le faire tourner en douceur avec 40 FPS. Je pense que c'est tout simplement incroyable ce que les cartes graphiques modernes peuvent faire.
user6420

Réponses:

5

Je pense qu'il est communément admis que le temps réel est tout ce qui est au-dessus de l'interactivité. Et interactif est défini comme "répond à l'entrée mais n'est pas fluide dans le fait que l'animation semble irrégulière".
Le temps réel dépendra donc de la vitesse des mouvements à représenter. Le cinéma projette à 24 FPS et est suffisamment temps réel pour de nombreux cas.

Ensuite, combien de polygones une machine peut traiter est facilement vérifiable en vérifiant par vous-même. Il suffit de créer un petit patch VBO comme test simple et un compteur FPS, de nombreux échantillons DirectX ou OpenGL vous donneront le banc d'essai parfait pour cette référence.

Vous verrez si vous avez une carte graphique haut de gamme que vous pouvez afficher environ 1 million de polygones en temps réel. Cependant, comme vous l'avez dit, les moteurs ne revendiqueront pas la prise en charge si facilement car les données de scènes réelles entraîneront un certain nombre de porcs de performance qui ne sont pas liés au nombre de polygones.

Vous avez:

  • taux de remplissage
    • échantillonnage de texture
    • Sortie ROP
  • dessiner des appels
  • rendre les commutateurs cibles
  • mises à jour du tampon (uniformes ou autres)
  • à découvert
  • complexité du shader
  • complexité du pipeline (toute rétroaction utilisée? ombrage de géométrie itérative? occlusion?)
  • points de synchronisation avec le CPU (relecture des pixels?)
  • richesse en polygones

En fonction des points faibles et forts d'une carte graphique particulière, l'un ou l'autre de ces points va être le goulot d'étranglement. Ce n'est pas comme si vous pouviez dire avec certitude "là, c'est celui-là".

ÉDITER:

Je voulais ajouter que, on ne peut pas utiliser la figure de spécification GFlops d'une carte spécifique et la mapper linéairement à la capacité de poussée du polygone. En raison du fait que le traitement polygonal doit passer par un goulot d'étranglement séquentiel dans le pipeline graphique, comme expliqué en détail ici: https://fgiesen.wordpress.com/2011/07/03/a-trip-through-the-graphics -pipeline-2011-part-3 /
TLDR: les sommets doivent tenir dans un petit cache avant l'assemblage primitif qui est nativement une chose séquentielle (l'ordre des tampons des sommets est important).

Si vous comparez la GeForce 7800 (9 ans?) À la 980 de cette année, il semble que le nombre d'opérations par seconde dont elle est capable ait été multiplié par mille. Mais vous pouvez parier que cela ne va pas pousser les polygones mille fois plus vite (ce qui représenterait environ 200 milliards de secondes par cette simple métrique).

EDIT2:

Répondre à la question "que peut-on faire pour optimiser un moteur", comme dans "ne pas perdre trop d'efficacité dans les commutateurs d'état et autres frais généraux".
C'est une question aussi ancienne que les moteurs eux-mêmes. Et devient de plus en plus complexe à mesure que l'histoire progresse.

En effet, en situation réelle, les données de scène typiques contiendront de nombreux matériaux, de nombreuses textures, de nombreux shaders différents, de nombreuses cibles et passes de rendu, et de nombreux tampons de vertex, etc. Un moteur avec lequel j'ai travaillé a fonctionné avec la notion de paquets:

Un paquet est ce qui peut être rendu avec un seul appel de tirage.
Il contient des identifiants pour:

  • tampon de sommet
  • tampon d'index
  • caméra (donne la passe et la cible de rendu)
  • identifiant du matériau (donne le shader, les textures et UBO)
  • distance aux yeux
  • est visible

Ainsi, la première étape de chaque trame consiste à exécuter un tri rapide sur la liste de paquets à l'aide d'une fonction de tri avec un opérateur qui donne la priorité à la visibilité, puis à passer, puis au matériau, puis à la géométrie et enfin à la distance.

Dessiner des objets proches obtient la priorité pour maximiser l'abattage précoce du Z.
Les passes sont des étapes fixes, nous n'avons donc pas d'autre choix que de les respecter.
Le matériau est la chose la plus coûteuse à changer d'état après les cibles de rendu.

Même entre différents ID de matériaux, un sous-ordre peut être effectué en utilisant un critère heuristique pour diminuer le nombre de changements de shader (le plus cher dans les opérations de changement d'état des matériaux), et deuxièmement les changements de liaison de texture.

Après tout cet ordre, on peut appliquer une méga texturation, une texturation virtuelle et un rendu sans lien ( lien ) si cela est jugé nécessaire.

À propos de l'API du moteur, une chose courante consiste également à différer l'émission des commandes de définition d'état requises par le client. Si un client demande "définir la caméra 0", il est préférable de simplement stocker cette demande et si plus tard le client appelle "définir la caméra 1" mais sans aucune autre commande entre les deux, le moteur peut détecter l'inutilité de la première commande et la supprimer. . Il s'agit de l'élimination de la redondance, qui est possible en utilisant un paradigme "entièrement conservé". Par opposition au paradigme "immédiat", qui serait juste un wrapper au-dessus de l'API native et émettrait les commandes comme ordonné par le code client. ( exemple: virtrev )

Et enfin, avec du matériel moderne, une étape très coûteuse (à développer), mais potentiellement très gratifiante, consiste à passer l'API au style metal / mantle / vulkan / DX12 et à préparer les commandes de rendu à la main.

Un moteur qui prépare les commandes de rendu crée un tampon qui contient une "liste de commandes" qui est écrasée à chaque image.

Il y a généralement une notion de «budget» de trame, un jeu peut se le permettre. Vous devez tout faire en 16 millisecondes, donc vous partitionnez clairement le temps GPU "2 ms pour le passage lightpre", "4 ms pour le passage des matériaux", "6 ms pour l'éclairage indirect", "4 ms pour les post-processus" ...

v.oddou
la source
1
Un million me semble un peu bas.
joojaa
il suffit de prendre le nombre de MPoly / s dont la carte est capable, et c'est le FPS auquel elle rendra 1 million. Je viens de rappeler une expérience pour un rendu de terrain sur un ATI4800HD. Si vous prenez cette liste en.wikipedia.org/wiki/List_of_Nvidia_graphics_processing_units, ils ne donnent pas d'informations sur Vertices / s à partir de l'ère de l'architecture unifiée. mais le matériel vieux de 10 ans semble annoncer environ 40 FPS pour 1 million de triangles. + cf edit dans ma réponse
v.oddou
@ v.oddou Oui, mais pour se rapprocher de ce nombre, vous devez faire un batch de géométrie, ou une instanciation, dans le cas de scènes dynamiques, et c'est ce que je demande. Comment ne pas vous goulot d'étranglement 2% du chemin vers ce que le matériel peut faire.
Llamageddon
@Llamageddon aaah, je vois, c'est effectivement une question. Laissez-moi voir ce que je peux en dire. (EDIT2)
v.oddou
Grande réponse en profondeur! J'ai fait quelques modifications mineures, en tant qu'utilisateur plutôt qu'en tant que modérateur. N'hésitez pas à annuler tout / tout si elles ne correspondent pas à votre intention.
trichoplax