La perception de la couleur de la surface d'un objet du monde réel dépend de la distribution de l'énergie des photons qui partent de cette surface et qui arrivent aux cellules de la rétine de l'oeil. Chaque objet réagit à la lumière en fonction des propriétés matérielles de sa surface.
Le modèle d'éclairage d'OpenGL considère qu'un objet peut émettre une lumière propre, renvoyer dans toutes les directions la lumière qu'il reçoit, ou réfléchir une partie de la lumière dans une direction particulière, comme un miroir ou une surface brillante.
Les lampes, elles, vont envoyer une lumière dont les caractéristiques seront décrites par leurs trois
composantes : ambiante, diffuse ou spéculaire.
OpenGL distingue quatre types de lumières :
Lumière émise
Ne concerne que les objets
Les objets peuvent émettre une lumière propre, qui augmentera leur intensité,
mais n'affectera pas les autres objets de la scène.
Lumière ambiante
Concerne les objets et les lampes
C'est la lumière qui a tellement été dispersée et renvoyée par l'environnement
qu'il est impossible de déterminer la direction d'où elle émane.
Elle semble venir de toutes les directions.
Quand une lumière ambiante rencontre une surface, elle est renvoyée dans toutes les directions.
Lumière diffuse
Concerne les objets et les lampes
C'est la lumière qui vient d'une direction particulière, et qui va être plus brillante si elle arrive
perpendiculairement à la surface que si elle est rasante. Par contre, après avoir rencontré la
surface, elle est renvoyée uniformément dans toutes les directions.
Lumière spéculaire
Concerne les objets et les lampes
La lumière spéculaire vient d'une direction particulière et est renvoyée par la surface dans une
direction particulière. Par exemple un rayon laser réfléchi par un miroir.
Brillance
Ne concerne que les objets
Cette valeur entre 0.0 et 128.0 détermine la taille et l'intensité de la tâche de réflexion spéculaire. Plus la valeur est grande, et plus la taille est petite et l'intensité importante.
Nombre de lampes
OpenGL offre d'une part une lampe qui génère uniquement une lumière ambiante (lampe d'ambiance), et d'autre part au moins 8 lampes (GL_LIGHT0, ... , GL_LIGHT7) que l'on peut placer dans la scène et dont on peut spécifier toutes les composantes.
La lampe GL_LIGHT0 a par défaut une couleur blanche, les autres sont noires par défaut.
La lampe GL_LIGHTi est allumée par un glEnable(GL_LIGHTi)
Il faut également placer l'instruction glEnable(GL_LIGHTING) pour indiquer à OpenGL qu'il devra prendre en compte l'éclairage.
Couleur des lampes
Dans le modèle d'OpenGL, la couleur d'une composante de lumière d'une lampe est définie par
les pourcentages de couleur rouge, verte, bleue qu'elle émet.
Par exemple voici une lampe qui génère une lumière ambiante bleue :
GLfloat bleu[4] = { 0.0, 0.0, 1.0, 1.0 };
glLightfv(GL_LIGHT0, GL_AMBIENT, bleu);
Il faut donc définir pour chaque lampe la couleur et l'intensité des trois composantes ambiante, diffuse et spéculaire.
Voici un exemple complet de définition de la lumière d'une lampe :
GLfloat bleu[4] = { 0.0, 0.0, 1.0, 1.0 };
glLightfv(GL_LIGHT0, GL_AMBIENT, bleu);
glLightfv(GL_LIGHT0, GL_DIFFUSE, bleu);
glLightfv(GL_LIGHT0, GL_SPECULAR, bleu);
Lampes directionnelles
Il s'agit d'une lumière qui vient de l'infini avec une direction particulière.
La direction est spécifiée par un vecteur (x,y,z)
GLfloat direction[4];
direction[0]=x; direction[1]=y; direction[2]=z;
direction[3]=0.0; /* notez le zéro ici */
glLightfv(GL_LIGHT0, GL_POSITION, direction);
Lampes positionnelles
La lampe se situe dans la scène au point de coordonnées (x,y,z)
GLfloat position[4];
position[0]=x; position[1]=y; position[2]=z;
position[3]=1.0; /* notez le un ici */
glLightfv(GL_LIGHT0, GL_POSITION, position);
Modèle d'éclairage
Il faut indiquer avec glLightModel*() si les calculs d'éclairage se font de la même façon ou non sur l'envers et l'endroit des faces des objets.
Il faut également indiquer si OpenGL doit considérer pour ses calculs d'éclairage que l'oeil est à l'infini ou dans la scène. Dans ce dernier cas, il faut calculer l'angle entre le point de vue et chacun des objets, alors que dans le premier cas, cet angle est ignoré ce qui est moins réaliste, mais moins coûteux en calculs. C'est le choix par défaut. Il est modifié par l'instruction glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE).
C'est avec cette même fonction que l'on définit la couleur de la lampe d'ambiance glLightModelfv(GL_LIGHT_MODEL_AMBIENT, couleur)
Atténuation de la lumière
Dans le monde réel, l'intensité de la lumière décroit quand la distance à la source de lumière augmente. Par défaut le facteur d'atténuation d'OpenGL vaut un (pas d'atténuation), mais vous pouvez le modifier pour atténuer la lumière des lampes positionnelles.
La formule est : facteur_d_atténuation = 1.0 / (kc + kl*d + kq*d*d), où
d est la distance entre la position de la lampe et le sommet
kc = GL_CONSTANT_ATTENUATION
kl = GL_LINEAR_ATTENUATION
kq = GL_QUADRATIC_ATTENUATION
exemple de modification du coefficient d'atténuation linéaire pour la lampe 0 :
glLightf(GL_LIGHT0, GL_LINEAR_ATTENUATION, 2.0);
Lampes omnidirectionnelles et spots
Par défaut, une lampe illumine l'espace dans toutes les directions.
L'autre type de lampe proposé par OpenGL est le spot.
Un spot est caractérisé, en plus de sa position, par sa direction, le demi angle du cône de lumière et l'atténuation angulaire de la lumière.
La direction par défaut est {0.0, 0.0, -1.0}, c'est le demi-axe -z.
GLfloat direction[]={-1.0, -1.0, 0.0};
glLightf(GL_LIGHT0, GL_SPOT_CUTOFF, 45.0); /* ce spot éclairera jusqu'à 45° autour de son axe */
glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, direction);
glLightf(GL_LIGHT0, GL_SPOT_EXPONENT, 0.5);/* coefficient d'atténuation angulaire */
Un vecteur normal (aussi appelé normale ) à une surface en un point de cette surfave est un vecteur dont la direction est perpendiculaire à la surface. Ce vecteur est utile pour le calcul de l'éclairage.
Pour une surface plane, les vecteurs normaux en tous points de la surface ont la même direction. Ce n'est pas le cas pour une surface quelconque.
C'est grâce au vecteur normal que l'on peut spécifier l'orientation de la surface dans l'espace, et en particulier l'orientation par rapport aux sources de lumière.
L'appel à glNormal*() donne une valeur à la normale courante. Elle sera associée aux points spécifiés par les appels suivants à glVertex*().
Dans le modèle d'OpenGL, la couleur que l'on perçoit d'un objet dépend de la couleur propre de l'objet et de la couleur de la lumière qu'il reçoit.
Par exemple, un objet rouge renvoie toute la lumière rouge qu'il reçoit et absorbe toute la lumière verte et bleue qu'il reçoit.
-
Si cet objet est éclairé par une lumière blanche (composé en quantités égales de rouge, vert et bleu), il ne renverra que la lumière rouge et apparaîtra donc rouge.
-
Si cet objet est éclairé par une lumière verte, il apparaîtra noir, puisqu'il absorbe le vert et n'a pas de lumière rouge à réfléchir.
Propriétés matérielles d'un objet
Les propriétés matérielles d'un objet sont celles qui ont été évoquées dans la partie Modèle d'éclairage OpenGL : la lumière émise, la réflexion ambiante, diffuse et spéculaire du matériau dont est fait l'objet. Elles sont déterminées par des instructions :
glMaterial*(GLenum face, GLenum pname, TYPE param)
Où pname vaut GL_AMBIENT, GL_DIFFUSE, GL_AMBIENT_AND_DIFFUSE, GL_SPECULAR, GL_SHININESS, ou GL_EMISSION.
N.B. Le mode GL_COLOR_MATERIAL permet d'utiliser la fonction glColorMaterial*(GLenum face, GLenum mode) pour spécifier les propriétés matérielles.
ex.
glEnable(GL_COLOR_MATERIAL);
glColorMaterial(GL_FRONT_, GL_AMBIENT_AND_DIFFUSE);
glColor3f(.2, .5, .3); //Dans ce contexte, la fonction glColor permet de spécifier la réflexion ambiante et diffuse du matériau.
Combinaison des coefficients
- Pour une lampe, les coefficients RVB correspondent à un pourcentage de l'intensité totale pour chaque couleur.
Par exemple R=1.0, V=1.0, B=1.0 correspond au blanc de plus grande intensité, alors que R=0.5, V=0.5, B=0.5 correspond à un blanc d'intensité moitié moins grande, qui est donc un gris.
- Pour un objet, les nombres correspondent à la proportion de la lumière renvoyée pour chaque couleur.
Si une lampe qui a comme coefficients (LR, LV, LB) éclaire un objet (OR, OV, OB), la couleur perçue sera (LR*OR, LV*OV, LB*OB).
- La combinaison de deux lampes de coefficients (R1, V1, B1) et (R2, V2, B2) produit une lumière (R1+R2, V1+V2, B1+B2) (et les valeurs supérieures à 1 sont ramenées à 1).
Transparence
La transparence est obtenue en indiquant pour un objet une couleur diffuse RVBA ou la valeur A sur le canal alpha est strictement plus petite que un.
Chaque facette d'un objet peut être affichée d'une unique couleur (ombrage plat) ou à l'aide de plusieurs couleurs (ombrage lissé). OpenGL implémente une technique de lissage appelée Ombrage de Gouraud. Ce choix s'effectue avec glShadeModel(GLenum mode).
Dans l'image de gauche un rendu à plat, et à droite, avec ombrage de Gouraud.


Ces images sont issues de l'exécution du programme scene.c. Changez de mode de rendu avec les touches 's' et 'S'.
- Copiez et compilez le programme colormat.c. Il permet de modifier
indépendamment les quatre composants du matériau de la sphère.
- Ajoutez une lampe en (-1,1,1) qui émet une lumière ambiante verte, une lumière diffuse bleue, et une lumière spéculaire rouge.
Utilisez les touches '0' (resp. '1') pour allumer et éteindre la lampe 0 (resp. 1).
TD Jeux de lumière
Pour contrôler la position et l'orientation d'une lampe dans la scène,
il suffit de savoir que la matrice de transformation courante est prise en compte
pour le placement et l'orientation de la lampe.
Exemple des lampes positionnelles
La lampe se situe dans la scène au point de coordonnées (x,y,z)
GLfloat position[4];
position[0]=0; position[1]=0; position[2]=0;
position[3]=1.0; /* notez le un ici */
glTranslatef(x, y, z);
glLightfv(GL_LIGHT0, GL_POSITION, position);
Rappel de la définition d'un spot
Un spot est caractérisé, en plus de sa position, par sa direction,
le demi angle du cône de lumière et l'atténuation angulaire
de la lumière.
La direction par défaut est {0.0, 0.0, -1.0}, c'est le demi-axe -z.
GLfloat direction[]={-1.0, -1.0, 0.0};
glLightf(GL_LIGHT0, GL_SPOT_CUTOFF, 45.0); /* ce spot éclairera jusqu'à 45° autour de son axe */
glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, direction);
glLightf(GL_LIGHT0, GL_SPOT_EXPONENT, 0.5);/* coefficient d'atténuation angulaire */
Exercice 2 : L'anneau de lumière
- Créez la fonction AnneauJauneOmnidirectionnel( float rayon, float
teta) qui place dans la scène une lampe omnidirectionnelle placée
dans le plan xz sur un anneau de rayon "rayon" centré sur le repère
local, à la coordonnée angulaire "teta".
Exercice 3 : Le gyrophare
- Créez la fonction GyrophareBleu(float teta, float cutOff) qui place
dans la scène une lampe de type gyrophare posé dans le plan
xy, à l'origine du repère local. Ce gyrophare est un spot d'angle
maximal cutOff, dont la direction est donnée par l'angle teta.
Exercice 4 : La poursuite montée sur un anneau
- Créez trois versions de la fonction PoursuiteRougeSurAnneau( float
rayon, float teta, float cutOff ) qui place dans la scène un spot Rouge
d'angle maximal "cutOff" monté sur un anneau de rayon "rayon" situé
dans le plan xy à l'origine du repère local.
- a. Le spot doit toujours éclairer le point origine du repère
local (0.0, 0.0, 0.0 ).
- b. Le spot doit toujours éclairer dans la direction des x négatifs
dans le repère local.
- c. Le spot doit toujours éclairer le point de coordonnées
dans le repère local (x, y, 0.0 ).
17 décembre 2012