IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

OpenGL Discussion :

glEnable(GL_NORMALIZE)


Sujet :

OpenGL

  1. #1
    Membre chevronné
    Avatar de Edouard Kaiser
    Profil pro
    Inscrit en
    Février 2004
    Messages
    521
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Février 2004
    Messages : 521
    Par défaut glEnable(GL_NORMALIZE)
    Bonjour à tous,
    Pourquoi est il déconseillé d'utiliser glEnable(GL_NORMALIZE) et donc plutot calculer soit même les normales des polygones ?
    Il faut bien les calculer ces normales, donc pourquoi en laissant faire à OpenGL le travail, cela attenuerai les performances ?

  2. #2
    Membre chevronné
    Avatar de bigquick
    Profil pro
    Inscrit en
    Août 2002
    Messages
    356
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2002
    Messages : 356
    Par défaut
    Je pense que c'est parcequ'OpenGL va normaliser les normales à chaque affichage:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    glEnable(GL_NORMALIZE);
     
    glBegin(...);
       glNormal3f(x,y,z);   // hop il la normalise pour que sa norme = 1
    glEnd();
    Alors que toi, tu peux les normaliser juste après les avoir calculé (donc après le chargement du modèle), et appeler glNormal3f avec une normale déjà unitaire

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    glDisable(GL_NORMALIZE);
     
    glBegin(...);
       glNormal3f(x,y,z);   // pas de calcul pour la normaliser
                            // donc ca va plus vite
                            // mais il faut bien sur passer une normale unitaire pour ne pas avoir de surprises :)
    glEnd();

    edit : en relisant ton post, je crois avoir compris: il y a confusion avec le terme "normalize" : ca ne sert pas à calculer les normales, mais à les rendre unitaires (au coût d'une racine carrée et de 3 divisions)

    2ème édit :
    Par contre, si la matrice ModelView contient des transformations de type "scale", les normales que tu vas passer seront scalées en conséquence, même si elles étaient unitaires. Tu peux alors utiliser
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    glEnable(GL_RESCALE_NORMAL);
    pour que les normales soient rescalées à l'inverse, selon la valeur du scale actuellement dans la ModelView (ce qui est bien moins couteux qu'une normalisation, puisque pas de racine carrée).

  3. #3
    Membre chevronné
    Avatar de Edouard Kaiser
    Profil pro
    Inscrit en
    Février 2004
    Messages
    521
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Février 2004
    Messages : 521
    Par défaut
    Je dois avouer que je n'ai pas tout saisi
    Il faut vraiment que je me replonge dans les lumieres et que je trouve un tutorial bien clair

  4. #4
    Membre chevronné
    Avatar de bigquick
    Profil pro
    Inscrit en
    Août 2002
    Messages
    356
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2002
    Messages : 356
    Par défaut
    Désolé je vais essayer d'être plus clair

    Alors

    ----------

    1. Pour pouvoir gérer correctement les lumières, OpenGL doit connaitre la normale pour chaque face ou vertex affiché. Il ne peut pas la calculer lui-même, puisqu'elle dépend de la position des vertex voisins, enfin peut-être qu'il pourrait, mais avec des calculs montres, donc il ne le fait pas

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    glNormal3f();  // la normale du vertex 1
    glVertex3f();  // le vertex 1
    ...
    glNormal3f();  // la normale du vertex 2
    glVertex3f();  // le vertex 2
    Donc avant chaque vertex, tu spéficie la normale correspondante. Si tu veux seulement une normale par face ("flat shading", cf le dessin ci-dessous), tu peux ne spécifier qu'une normale avant les 3 vertex. Par contre, si tu ne donnes jamais aucune normale, tes lumières ne sont pas bonnes du tout

    ----------

    2. L'idée est donc de calculer les normales après avoir chargé ton objet. Pour 1 normale par face ("flat shading") une passe suffit: pour chaque face tu effectues un simple calcul de normal. Pour un éclairage réaliste, on va calculer 1 normale par vertex, celle-ci étant la moyenne des normales des faces dont il fait partie. Il faudra donc d'abord calculer les normales des faces, puis refaire une passe pour calculer celle de chaque vertex.

    Pour plus d'info, cherche "Gouraud shading" sur Google !




    ----------

    3. Pour que les lumières soient correctes, il faut en plus que ces normales soient unitaires (de norme 1). Si ce n'est pas le cas, il y aura un effet d'attenuation ou d'accentuation de la lumière (pour une norme < ou > à 1).

    Là, 2 solutions:

    tu laisses OpenGL le faire avec glEnable(GL_NORMALIZE); , en lui passant des normales quelconques (donc peut-être pas unitaires), et il se chargera de les normaliser à chaque appel à glNormal3f().

    tu t'arranges pour passer des normales unitaires, c'est quand même mieux puisque de toute façon tu as calculé ces normales, donc pendant que tu y étais tu pouvais les rendre unitaires sur le coup. Tu imagines le gain puisque c'est fait 1 fois pour toute

    ----------

    4. Par contre (hé oui, il fallait bien un "par contre")

    Si tu scale ton univers en faisant par exemple tout sera scalé 5 fois plus grand .... y compris tes normales que tu avais soigneusement rendues unitaires
    Pour palier ça, tu as
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    glEnable(GL_RESCALE_NORMAL);
    qui va, à chaque appel à glNormal3f(), rescaler la normale selon l'inverse du scale de la ModelView: donc ici, 1/5 ! Et tou va bien, on retrouve notre normale unitaire

    Et évidemment, c'est moins couteux qu'un GL_NORMALIZE, puisqu'il s'agit de simples divisions, et non pas de racine carrée ....


    ----------


    Voilà, j'espère que c'était un peu plus compréhensible !

  5. #5
    Membre chevronné
    Avatar de Edouard Kaiser
    Profil pro
    Inscrit en
    Février 2004
    Messages
    521
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Février 2004
    Messages : 521
    Par défaut
    C'est génial, j'ai tout compris, ton explication est claire, simple, félicitation, tu es trés pédagogue
    Merci beaucoup !

  6. #6
    Membre chevronné
    Avatar de bigquick
    Profil pro
    Inscrit en
    Août 2002
    Messages
    356
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2002
    Messages : 356
    Par défaut
    Pas de problème, content que tu aies compris

  7. #7
    Membre Expert
    Avatar de shenron666
    Homme Profil pro
    avancé
    Inscrit en
    Avril 2005
    Messages
    2 578
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : avancé

    Informations forums :
    Inscription : Avril 2005
    Messages : 2 578
    Par défaut
    J'ajouterai juste que glEnable(GL_NORMALIZE) ne génère pas les normales, il les normalise, donc puisqu'il faut bien transmettre les normales autant les transmettre normalisées
    Tutoriels OpenGL
    Je ne répondrai à aucune question en MP
    - Si c'est simple tu dis que c'est compliqué et tu le fait
    - Si c'est compliqué tu dis que c'est simple et tu le sous-traite ou le fait faire par un stagiaire.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Problème : glEnable (GL_TEXTURE_2D)
    Par bipcpp dans le forum OpenGL
    Réponses: 8
    Dernier message: 05/12/2008, 22h34
  2. Réponses: 2
    Dernier message: 28/08/2008, 13h24
  3. Question sur glEnable(GL_TEXTURE_2D)
    Par lia dans le forum OpenGL
    Réponses: 6
    Dernier message: 27/08/2006, 21h31

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo