L'instanciation améliore les performances (de manière significative) lors du rendu de plusieurs copies (des centaines de milliers?) Du même maillage à la fois. Mais combien de temps faut-il pour rendre exactement une copie avec un appel de tirage? Serait-ce une bonne ou une mauvaise idée d'utiliser l'instanciation pour toute la géométrie rendue par le moteur?
Edit: Disons que nous créons un jeu FPS. La plupart des objets n'ont qu'un seul exemple: un couteau, une arme à feu, une mitrailleuse, un bâtiment et une tour radio. Mais il y a aussi des objets avec plusieurs instances: des arbres (par exemple 3 types d'arbres avec des centaines d'instances), de l'herbe, etc. et l'herbe en utilisant l'instanciation, nous les rendons tous en utilisant l'instanciation. Donc, notre tour radio n'a qu'une seule instance (dont nous stockons les informations dans un tampon de données d'instance) et nous rendons cette tour en utilisant une sorte d' DrawInstanced()
appel avec un nombre d'instances égal 1
. Même chose avec tous les autres objets (bien sûr, les arbres et l'herbe ont plusieurs instances).
Ma question est donc: est-ce une mauvaise idée de dessiner une seule instance d'un objet en utilisant l'instanciation? L'instanciation a-t-elle trop de surcharge (en termes de mémoire et de performances) ou est-elle en aucune façon indésirable pour le rendu d'objets à instance unique?
la source
(Sur mon système, je ne l'ai testé nulle part ailleurs) Dans GL, l'instanciation d'un seul maillage (dessin avec count = 1) a des frais généraux désagréables, mais je ne sais pas d'où il vient. Je suggère fortement de ne pas le faire.
J'ai testé cela dans une application pratique il y a quelques mois. J'ai codé quelques algorithmes d'éclairage global dans la scène Crytek Sponza, qui se compose d'environ 350 mailles (je ne me souviens pas exactement), dont un couple partage une poignée d'exemples. Au début, je l'ai fait comme vous le suggérez, installez tout et dessinez le reste avec un nombre d'instances de 1, car cela simplifiait un peu le code de rendu.
Plus tard lors de l'optimisation du rendu, il suffit de revenir de l'instanciation des objets count = 1 à leur soumission de la manière habituelle, ce qui m'a sauvé 3,5 millisecondes par trame de temps sur un i7 3770k (et GTX 770). Changer les mailles avec plusieurs instances pour les faire simplement de la manière traditionnelle m'a fait gagner encore 0,5 ms. Globalement, l'application est passée de ~ 120 FPS à environ ~ 230 FPS.
Ces chiffres dépendent bien sûr toujours de l'endroit où se trouvent les goulots d'étranglement dans votre application, et les derniers 0,5 ms peuvent en fait devenir un ralentissement dans une application où vous êtes très lié à l'appel. Mais sinon, d'après mon expérience, l'instanciation a des frais généraux désagréables si vous ne dessinez pas beaucoup de choses à la fois.
la source
Vous pouvez être certain que dessiner un seul objet instancié est plus cher que de dessiner un seul objet normalement. Pour l'instanciation, le GPU se prépare à une grande quantité d'objets et cette préparation sera différente de celle d'un seul objet. Cependant, l'ampleur de cet écart de performances ne peut être trouvée qu'en expérimentant et dépend beaucoup de votre configuration de rendu réelle. La seule façon de savoir avec certitude est de le tester vous-même. L'analyse comparative d'un appel de tirage unique est difficile, voici plusieurs idées sur la façon de procéder.
la source
Cela fait 4 ans ... et je pense qu'il est prudent de dire qu'il est tout à fait correct de soumettre des appels de tirage "instanciés" avec 1. Comme vous l'avez peut-être remarqué, les nouvelles API DX12 et Vk ont toutes deux un nombre d'instances pouvant aller de 0 à NUM_INSTANCES . Notez également qu'il n'y a pas de DrawIndexed (...) .
ÉDITER
Par souci de prudence, ce qui précède est probablement correct avec ces API modernes, peut-être que l'utilisation de quelque chose de vieux comme Gl <3.3 ou peut-être DX11 nécessitera un profilage comme mentionné par d'autres utilisateurs.
la source