J'apprends quelques bases d'OpenGL mais je me demande pourquoi il y a un appel glNormal
à définir la normale des sommets.
Si je crée un simple triangle comme celui-ci:
glBegin(GL_TRIANGLES);
glVertex3f(0,0,0);
glVertex3f(1,0,0);
glVertex3f(0,1,0);
glEnd();
Les normales ne devraient-elles pas être définies implicitement par le type de la primitive géométrique? Si je ne mets pas un normal, OpenGL le calculera?
Réponses:
Appeler
glNormal
plusieurs fois entreglBegin/End
vous permet de définir une normale par sommet au lieu de par primitive.Pour un maillage plus complexe composé de plusieurs triangles, vous voudriez que la normale à un sommet dépende des autres triangles de la géométrie environnante et pas seulement de la normale du triangle auquel elle appartient.
Voici un exemple de la même géométrie avec:
(0,0,1)
):Le modèle d'ombre par défaut (
GL_SMOOTH
) entraîne l'interpolation des normales des sommets de la face sur la face. Pour les normales par sommet, cela donne une sphère lisse et ombragée, mais pour les normales par face, vous vous retrouvez avec l'aspect caractéristique à facettes.la source
Non, GL ne calcule pas de norme pour vous. Il ne sait pas ce que devrait être la normale. Vos primitives ne signifient rien en dehors de la pixellisation (et quelques autres endroits). GL ne sait pas quelles faces (triangles) partagent un sommet (le calculer à l'exécution est très coûteux sans utiliser de structures de données différentes).
Vous devez prétraiter la "soupe triangulaire" d'un maillage pour trouver des sommets communs et calculer des normales. Cela devrait être fait avant que le jeu ne tourne pour la vitesse.
Il y a aussi des cas comme les bords durs où géométriquement il y a un sommet partagé au coin, mais vous voulez des normales séparées pour qu'il s'allume correctement. Dans le modèle de rendu GL / D3D, vous avez besoin pour cela de deux sommets séparés (à la même position), chacun avec une normale distincte.
Vous aurez également besoin de tout cela pour les UV et la cartographie des textures.
la source
La réponse courte est que vous n'avez pas du tout besoin de définir une normale. Les vecteurs normaux ne sont utilisés que si vous effectuez un éclairage OpenGL (ou peut-être un autre calcul qui peut en dépendre), mais si cela ne s'applique pas à vous (ou si vous utilisez une autre méthode pour faire de l'éclairage, par exemple des lightmaps ), alors vous pouvez très volontiers omettre tous les appels glNormal.
Supposons donc que vous faites quelque chose où la spécification de glNormal est logique et examinez-la un peu plus.
glNormal peut être spécifié par primitive ou par sommet. Avec des normales par primitives, cela signifie simplement que toutes les normales pour chaque sommet de la face primitive dans la même direction. Parfois, c'est ce que vous voulez, mais parfois ce n'est pas le cas - là où les normales par sommet sont utiles, c'est qu'elles permettent à chaque sommet d'avoir sa propre face.
Prenons l'exemple classique d'une sphère. Si chaque triangle dans une sphère avait la même normale, le résultat final serait tout à fait à facettes. Ce n'est probablement pas ce que vous voulez, vous voulez plutôt un ombrage lisse. Donc, ce que vous faites, c'est la moyenne des normales pour chaque triangle qui partage un sommet commun, et obtenez un résultat ombré lisse.
la source
Exemple minimal qui illustre certains détails du
glNormal
fonctionnement de la foudre diffuse.Les commentaires de la
display
fonction expliquent ce que signifie chaque triangle.Théorie
Dans OpenGL, chaque sommet a son propre vecteur normal associé.
Le vecteur normal détermine la luminosité du sommet, qui est ensuite utilisé pour déterminer la luminosité du triangle.
Lorsqu'une surface est perpendiculaire à la lumière, elle est plus lumineuse qu'une surface parallèle.
glNormal
définit le vecteur normal actuel, qui est utilisé pour tous les sommets suivants.La valeur initiale pour la normale avant nous tous
glNormal
est0,0,1
.Les vecteurs normaux doivent avoir la norme 1, sinon les couleurs changent!
glScale
modifie également la longueur des normales!glEnable(GL_NORMALIZE);
fait qu'OpenGL règle automatiquement sa norme à 1 pour nous. Ce GIF illustre cela magnifiquement.Bibliographie:
la source
Vous avez besoin de glNormal pour implémenter certaines fonctionnalités dépendant du codeur. Par exemple, vous souhaiterez peut-être créer des normales pour conserver les bords durs.
la source