2010-01-09 4 views
0

Ok ... imaginez-je un solide relativement simple qui a six Normales distincts mais a fait près de 48 faces (8 faces par direction) et il y a Beaucoup de sommets partagés entre les visages. Quel est le moyen le plus efficace de rendre cela dans OpenGL? Je sais que je peux placer les vertices dans un tableau, puis utiliser un tableau d'index pour les rendre, mais je dois continuer à briser mes pas de rendu pour changer les normales (ie mettre normal 1 ... rendre 8 faces. .. set normal 2 ... render 8 faces, etc.) A cause de cela je dois maintenir un tableau de tableaux d'index ... un pour chaque normal! Pas bon! L'autre façon que je peux faire est d'utiliser des tableaux de normales et de vertex séparés (ou même de les entrelacer), mais cela signifie que j'ai besoin d'un ratio un-à-un pour les normales aux sommets, ce qui signifie que les normales seraient dupliqué 8 fois plus que nécessaire! Sur quelque chose avec une surface sphérique ou même courbée, tout normal est probablement différent, mais pour cela, cela semble vraiment être une perte de mémoire. Dans un monde parfait, j'aimerais que mon vertex et mes tableaux normaux aient des longueurs différentes, puis quand je dessine mes triangles ou mes quads Pour spécifier l'index de chaque tableau pour ce sommet. Maintenant, le format de fichier OBJ vous permet de spécifier exactement que ... un tableau de vertex et un tableau normal de longueurs différentes, puis lorsque vous spécifiez la face que vous affichez, vous spécifiez un vertex et un index normal (ainsi que une coordonnée UV si vous utilisez des textures aussi) qui semble être la solution parfaite! 48 vertices mais seulement 8 normales, puis des paires d'index définissant les faces des formes. Mais je ne suis pas sûr de savoir comment rendre cela dans OpenGL ES (encore une fois, notez les «ES».) Actuellement, je dois «dénormaliser» (désolé pour le jeu de mots SQL là-bas) les normales à un 1-à-1 avec le vertex array, puis render. Juste me gaspille de la mémoire.OpenGL ES avec Polygon Normales rendu (notez le 'ES!)

Toute personne aide? J'espère qu'il me manque quelque chose de très simple ici.

Marque

Répondre

1

Vous ne manquez rien. C'est ainsi que fonctionne la spécification car c'est ainsi que fonctionne la plupart des matériels (votre parfait n'est pas parfait). Je n'entrerai pas dans les complexités de l'implémentation matérielle qui supporterait un ensemble d'indices, mais je signalerai une optimisation que vous perdriez probablement: le GL utilise potentiellement l'index unique comme index dans un article -vertex transformer le cache, pour ne pas avoir à re-transformer le vertex à l'itération suivante. Vous rendez cette optimisation beaucoup plus complexe avec un ensemble d'indices.

En ce qui concerne les économies de mémoire: dans votre cas, vous parlez à peu près un cube chaque face en utilisant 4 quadriceps, 8 triangles. Nous parlons donc de 9 * 6 = 54 sommets uniques. si vous avez seulement la position et les normales, qui est 54 * 4 * 3 * 2 = 1.296 B de données de sommet + 2 * 48 * 3 = 288 B des données d'index (en supposant que quatre octets pour les types de base d'attributs et GLushort pour les indices). Grand total de 1584B. Cela suppose un format de données non optimal pour les positions et les normales. L'alternative est d'environ 26 * 4 * 3 (pos) + 8 * 4 * 3 (norme) + 2 * 48 * 3 * 2 = 312 + 96 + 576 = 984B. Donc, vous avez économisé environ 0,5 Ko sur ce cas artificiel. passer ce à d'autres types d'économie de mémoire pour les attributs, et vous obtenez à: 648 + 288 = 936 vs 156 + 48 + 576 = 780 ... La différence commence à être négligeable.

Pourquoi est-ce que je soulève cette question? parce que vous devriez regarder vos types de données d'attribut si vous voulez des optimisations de consommation de mémoire. Enfin, comme vous l'avez remarqué vous-même, dans les mondes 3d pratiques (c'est-à-dire pas dans le monde des boîtes), les économies d'un tel mécanisme seraient faibles: très peu d'attributs peuvent être partagés.

+0

Ok, simplifiez le modèle plus. Vous avez une bande de quads qui s'étendent comme un rouleau de ruban. Ajouter une seconde bande sur le bord comme un deuxième morceau de bande afin que tous les sommets sont partagés dans le 'pli' Mais à cause des normales, vous ne pouvez pas partager les sommets, vous avez maintenant un gain de 33% en mémoire. (c'est-à-dire que vous avez ab alors cd même si b et c sont exactement le même sommet, juste des normales différentes et techniquement, même dans les quads d'une seule bande vous auriez le même problème si vous ne vouliez pas que les faces soient lisse mais plutôt plate (lisser les vertices partagerait bien sûr les normales) – MarqueIV

+0

De plus, vous ne perdez aucune transformation de vertex car les sommets sont toujours au même endroit dans l'espace 3d. Je choisis de les dessiner avec les commandes qui ne les affectent pas Et n'est-ce pas exactement ce que fait la commande DrawElements? ..via indexes? Après tout, si j'ai un index que j'utilise dans dix opérations que je référence par index, n'est-ce pas juste un calcul/optimisation sur ce sommet par opposition à dix, étant l'exact opposé de votre déclaration ci-dessus? – MarqueIV

+0

Ce que vous décrivez ressemble à un terrain. sur les rouleaux de bande de terrain. Vouloir "plat" est plutôt le exception est ce que je disais dans mon message. Comme pour la transformation post-vertex: que se passe-t-il si la sortie de votre position de sommet dépend de la normale? Il n'est pas nécessairement calculé uniquement en fonction de la position d'entrée du sommet. Et je ne fais que décrire une optimisation que je connais actuellement (sa taille est généralement petite, d'ailleurs, vous ne la touchez pas toujours, surtout si vos bandes de terrain sont longues). – Bahbar