Voir en 3D : termes importants
-
world coordinates: repère du "monde", le point de repère
global de la scène
-
world coordinate window: partie du monde que l'on désire
visualiser
-
screen (device) coordinates: coordonnées en pixels utilisées
par le dispositif d'affichage (écran...)
-
viewport: partie de l'écran dans laquelle on va afficher
la world coordinate window
-
remarque: on a aussi le système de coordonnées à l'écran.
Pour nous ce sera la fenêtre OpenGL.
-
le viewport sera la partie de la fenêtre OpenGL utilisée
-
on le spécifie à l'aide de la fonction OpenGL glViewport
-
clipping: dessiner uniquement la partie du monde qui se trouve dans
le viewport
-
-
wireframe, flat shading, gouraud shading, etc...: mode de rendu
des objets. Wireframe = file de fer, etc...
Voir en 3D : principes
-
Pour dessiner des objets 3D, il faut les projeter sur une surface 2D, qui
pourra être visualisée sur notre hardware (écran)
-
Remarque : lorsque les écrans holographiques seront au point, ce
ne sera plus nécessaire
-
Projection : transformer un point de l'espace 3D vers un plan 2D
-
Il existe aussi des transformations en 4D, 5D etc (fractales)
-
exemple pour projeter un segment de droite 3D sur un plan 2D
-
1. projeter ses deux extrêmités en 2D
-
2. relier les deux extrêmités 2D pour former le segment 2D
projeté.
-
Projection perspective pour la visualisation 3D : centre optique,
plan focal.
-
On intersecte les rayons allant du centre optique aux extrêmités
d'un segment 3D avec le plan focal
-
Il existe d'autres types de projections que l'on obtient en changeant la
position du centre optique et du plan focal (pour obtenir par exemple plusieurs
points de fuite
Voir en 3D : principes (2)
-
Le centre de projection est souvent"l'oeil de l'observateur", soit le centre
otpique d'une caméra
-
Le plan de projection est l'écran
-
Les projections non planaires sont possibles: projection sur des spheres,
etc.
-
Les étapes pour voir en 3D:
-
Clipping 3D des objets de la scène sur la pyramide de vue (frustum)
-
Projeter le contenu de la pyramide de vue sur le plan focal (repère
du monde)
-
Passer du repère du monde au repère de la caméra
-
Passer du repère caméra au repère de l'écran
-
Dessiner le résultat dans la fenêtre graphique
Principaux types de projections planaires:
-
1. Les projections parallèles: le centre de projection est à
l'infini
-
ce type de projection préserve les lignes, les distances, les angles
-
cependant, on perd toute information de profondeur. L'oeil humain ne voit
pas comme ça !
-
2. Les projections perspectives: Le centre de projection est à une
distance finie des objets
-
un bon modèle de l'oeil humain ou d'un appareil photo
-
respecte l'effet de perspective : plus un objet est loin plus il est petit
-
préserve les lignes mais pas les angles ni les distances
-
remarque: en fait l'oeil humain ne fonctionne pas exactement comme ça
: projection sur la rétine non plane
Les projections parallèles (1)
-
Aussi appelées "projections orthographiques" : tous les rayons sont
parallèles et orthogonaux au plan de projection
-
Simples à implémenter, on supprime juste une coordonnée
pour tous les points
(x, y, z) --> drop z coordinate --> (x, y) : projects onto x-y
plane
-
Les lignes sont préservées:
-
exemple : le segment (x1, y1, z1), (x2, y2, z2) ---> segment (x1,
y1), (x2, y2)
-
pour obtenir différentes vues (face, profil, haut...), supprimer
soit la coordonnée X, Y ou Z
Les projections parallèles (2)
-
L'orientation des axes est basée sur un repère orienté
main-droite
-
Tout sens de la profondeur est perdu:
-
Avec 3DS si on tourne un objet dans la vue 3D, ça fait bizarre dans
les vues de face/dessus/côté
Les projections parallèles: avec OpenGL
-
Important: n'oubliez pas d'appeler glMatrixMode(GL_PERSPECTIVE)
avant d'initialiser l'environnement de visualisation. Ceci vous permettra
d'effectuer des translations (glRotate, etc) pour déplacer
la caméra. Retournez sur le mode GL_MODELVIEW avant de manipuler
le modèle.
-
Il faut appeler glLoadIdentity() pour initialiser la matrice
de visualisation. Utilisez alors glOrtho et les autres fonctions
de la même famille pour initialiser le type de projection.
glOrtho(GLdouble Xmin, Xmax, Ymin, Ymax, Zmin, Zmax)
-
intuitivement: glOrtho(left, right, top, bottom, near, far)
-
Ceci définit un volume 3D : les objets (ou les bouts d'objets) à
l'extérieur de ce volume seront clippés. Les autres seront
projetés sur le plan XY
-
Les valeurs de Z (near, far) seront interprétées comme négatives:
le plan de projection est X-Y, et le Z de la caméra ne regarde pas
vers la scène avec OpenGL, le Y est vers le haut
-
gluOrtho2D(GLdouble left, right, top, bottom): équivalent
2D
Projection perspective
-
Dans cet exemple: L'oeil est sur l'axe des Z, et on projette sur le plan
XY
Projection perspective (2)
-
L'oeil est à une distance finie de l'objet
-
On suppose l'objet devant l'oeil
-
L'oeil est à une distance E de l'origine sur l'axe des Z (distance
focale)
On a : y/(E-z) = (y'/E)
ainsi
y' = Y*E / (E-z) = y*(E/(E-z)) = y*(1/(1-(z/E)))
S = 1/(1-(z/E)) <-- facteur de perspective
So... y'= y*S = y/(1-z/E), x' = x*S = x/(1-z/E)
-
Remarque:
-
(1) lorsque les objets s'éloignent, le terme (1-z/E) tend
vers l'infini et le facteur de perspective tend vers 0
-
(2) Lorsque les objets sapprochent, (1-z/E) tend vers 1, les objets sont
plus grands sur l'écran, le facteur altère moins les coordonnées
X et Y projetées
Projection perspective (3)
-
Lorsqu'un point est loin de l'oeil (grande valeur de "-Z"), alors S est
très petit, ceci va donner de petits x' et y' (ils s'approchent
d'un point de fuite au loin)
-
L'objet apparait petit et "écrasé" lorsqu'il s'éloigne
-
Les points près du plan Z=0 voient x' et y' proches de X et Y
-
Donc plus un objet est près plus il est gros
-
OpenGL: le repère caméra est inversé par rapport à
ce que nous avions vu l'an dernier
Projection perspective : un exemple
-
On positionne l'oeil en (-1, 0, 0), on suppose la distance focale E=1 et
l'oeil regarde vers l'axe -Z
|
Point
|
Coords
Monde
|
Coords
Orthographiques
|
Facteur de perspective S
|
Coords
perspectives
|
|
A
|
(2,1,0)
|
(2,1)
|
1.0
|
(2,1)
|
|
B
|
(2,1,-10)
|
(2,1)
|
0.09
|
(0.18, 0.09)
|
|
C
|
(2,1,-100)
|
(2,1)
|
0.001
|
(0.02, 0.001)
|
|
D
|
(2,-5,-100)
|
(2,-5)
|
0.001
|
(0.02, -0.05)
|
|
E
|
(-50,-50,-100)
|
(-50,-50)
|
0.001
|
(-0.49, -0.49)
|
Point de fuite : Lim(z -> -inf) (1/(1-(z/E)) = Lim(z -> -inf) (1/(1-z))
= 0
-
par conséquent: x' = x*S = x*0 = 0, y' = 0 --> (0,0)
projection perspective: OpenGL

-
4 plans: left, right, top, bottom, near, far
-
définit une pyramide qui a le haut tronqué : le "frustum"
Projection perspective: OpenGL (2)
gluPerspective(GLdouble fovy, aspect, zNear, zFar)
-
fovy: champ de vision - angle (en 10èmes) donné par le top
et le bottom des "fenêtres de clipping"
-
aspect ratio: ratio entre la dimension en X et en Y de cette fenêtre
de clipping (XD / YD)
-
Le même que le ratio entre les dimensions de la fenêtre graphique
: utiliser
getsize(X, Y) pour le calculer
-
pour une fenêtre carée --> aspect=1.0
-
znear, zfar - distance des near clipping planes et far clipping
planes
-
plus grand est fovy: plus on a un grand angle !
Changer le point de vue en OpenGL
1. Déplacer la caméra "à la main"
-
utiliser glRotate, glTranslate, et d'autres transformations
pour déplacer la caméra à l'endroit désiré
-
Déplacer un objet ou déplacer la caméra revient à
utiliser les mêmes matrices de transformation (mais dans des directions
opposées)
-
Pour déplacer la caméra : effectuer ces transformations lorsqu'on
est dans le mode glMatrixMode(GL_PERSPECTIVE), initialiser les matrices
avec glLoadIdentity()
-
Rappelez-vous de vous mettre en mode glMatrixMode(GL_MODELVIEW)
avant de déplacer les objets (ou bien ils se déplaceront
dans le sens inverse de celui que vous souhaitez)
Déplacer le point de vue en OpenGL (2)
2. gluLookAt(GLdouble eyeX, eyeY, eyeZ, centerX, centerY, centerZ, upX,
upY, upZ)
-
eyeX, eyeY, eyeZ: coordonnées de la caméra (position de vue)
-
centerX, centerY, centerZ: un point sur la ligne de vue. Point de visée
-
upX, upY, upZ: direction du vecteur "up" (colinéaire a Y de la caméra)
Example de programme OpenGL
-
Le programme cube_persp.c
-
Remarquez que le coin le plus éloigné du cube est clippé
Example de programme OpenGL (2)
#include <GL/gl.h>
#include <GL/glut.h>
long v[8][3] = {
{-1, -1, -1},
{-1, -1, 1},
{-1, 1,
1},
{-1, 1, -1},
{ 1, -1, -1},
{ 1, -1, 1},
{ 1, 1,
1},
{ 1, 1, -1}
};
int path[16] = {
0, 1, 2, 3,
0, 4, 5, 6,
7, 4, 5, 1,
2, 6, 7, 3
};
void drawcube() {
int i;
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(0.0, 0.0,
0.0);
glBegin(GL_LINE_STRIP);
for (i=0; i < 16;
i++)
glVertex3i(v[path[i]][0], v[path[i]][1], v[path[i]][2]);
glEnd();
glFlush();
}
main(int argc, char **argv) {
glutInit(&argc,
argv);
glutInitWindowSize(600,
400);
glutInitDisplayMode(GLUT_RGB
| GLUT_SINGLE);
glutCreateWindow("glLookat
example");
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(30.0,
1.5, 0.1, 10.0);
gluLookAt(5.0, 4.0,
6.0, 1.0, 1.0, 1.0, 0.0, 1.0, 0.0);
glMatrixMode(GL_MODELVIEW);
glClearColor(1.0, 1.0,
1.0, 0.0); /* white */
glClear(GL_COLOR_BUFFER_BIT);
glutDisplayFunc(drawcube);
glutMainLoop();
return 0;
}
Références
-
OpenGL Programming Guide, OpenGL ARB, Addison-Wesley 1993, ISBN
0-201-63274-8. (chapter 3; see insight)