web-dev-qa-db-fra.com

Rendre les maillages avec plusieurs index

J'ai des données de sommet. Positions, normales, coordonnées de texture. Je l'ai probablement chargé à partir d'un fichier .obj ou d'un autre format. Peut-être que je dessine un cube. Mais chaque donnée de sommet a son propre index. Puis-je rendre ces données de maillage en utilisant OpenGL/Direct3D?

50
Nicol Bolas

Dans le sens le plus général, non. OpenGL et Direct3D n'autorisent qu'un seul index par sommet; l'index extrait de chaque flux de données de sommet. Par conséquent, chaque combinaison unique de composants doit avoir son propre index séparé.

Donc, si vous avez un cube, où chaque face a sa propre normale, vous devrez beaucoup reproduire la position et les données normales. Vous aurez besoin de 24 positions et de 24 normales, bien que le cube ne contienne que 8 positions uniques et 6 normales.

Votre meilleur choix est simplement d’accepter que vos données soient plus volumineuses. Un grand nombre de formats de modèles utilisent plusieurs index. vous devrez corriger ces données de sommet avant de pouvoir les restituer. De nombreux outils de chargement de maillage, tels que Open Asset Importer, effectueront cette correction pour vous.

GL 3.x et D3D10

Pour le matériel de type D3D10/OpenGL 3.x, il est possible d'éviter d'effectuer une correction et d'utiliser directement plusieurs attributs indexés. Toutefois, sachez que cela réduira probablement les performances de rendu.

La discussion suivante utilisera la terminologie OpenGL, mais Direct3D v10 et supérieur a des fonctionnalités équivalentes.

L'idée est d'accéder manuellement aux différents attributs de sommet du vertex shader. Au lieu d'envoyer les attributs de sommet directement, les attributs transmis sont en réalité les index de ce sommet particulier. Le vertex shader utilise ensuite les index pour accéder à l'attribut réel via une ou plusieurs textures de tampon .

Les attributs peuvent être stockés dans plusieurs textures de mémoire tampon ou dans une seule. Si ce dernier est utilisé, le shader aura besoin d'un décalage à ajouter à chaque index afin de rechercher l'index de départ de l'attribut correspondant dans la mémoire tampon.

Les attributs de sommet normaux peuvent être compressés de plusieurs manières. Les textures de mémoire tampon ont moins de moyens de compression, ce qui ne permet qu'un nombre relativement limité de formats de sommets (via les formats d'image qu'ils prennent en charge).

Veuillez noter à nouveau que l’une quelconque de ces techniques peut réduire les performances globales de traitement des sommets. Par conséquent, il ne doit être utilisé que dans les circonstances les plus limitées en mémoire, une fois que toutes les autres options de compression ou d'optimisation ont été épuisées.

OpenGL ES 3.0 fournit également des textures de tampon. Les versions OpenGL supérieures vous permettent de lire les objets de tampon plus directement via SSBOs plutôt que les textures de tampon, qui pourraient avoir de meilleures caractéristiques de performance.

65
Nicol Bolas

J'ai trouvé un moyen qui vous permet de réduire ce type de répétition qui va un peu à l'encontre de certaines des affirmations de l'autre réponse (mais ne correspond pas spécifiquement à la question posée ici). Il s’agit toutefois de ma question , qui était censée être une répétition de cette question.

Je viens tout juste d'apprendre l'existence de qualificatifs d'interpolation . Plus précisément "plat". Je crois comprendre que le qualificatif flat sur la sortie de votre vertex shader force uniquement le sommet provoquant à transmettre ses valeurs au fragment shader.

Cela signifie pour la situation décrite dans cette citation:

Donc, si vous avez un cube, où chaque face a sa propre normale, vous devrez beaucoup reproduire la position et les données normales. Vous aurez besoin de 24 positions et de 24 normales, bien que le cube ne contienne que 8 positions uniques et 6 normales.

Vous pouvez avoir 8 sommets, dont 6 contiennent les normales uniques et 2 valeurs normales sont ignorées, à condition de bien classer vos index de primitives de sorte que le "sommet provocant" contienne les données normales que vous souhaitez appliquer à la totalité du visage.

EDIT: Ma compréhension de la façon dont cela fonctionne:

enter image description here

enter image description here

enter image description here

enter image description here

0
gunfulker