TP 3: Effets Spéciaux
But:
Dans ce TP, vous allez vous amuser avec quelques effets spéciaux.
Certains sont prévus directement dans OpenGL, comme le fog ou le
blending, certains autres ne sont pas vraiment prévus mais
peuvent être simulés sous certaines conditions (ombres portées et
reflets).
Description:
Le programme ouvre une fenêtre sur un environnement contenant les objets
du TP précédent (une sphère, les deux objets plans, et le plan horizontal
texturé). Le travail consistera à intégrer au code existant les effets
spéciaux suivants: fog, transparence des objets plans, ombres portées et
reflets des objets sur le plan horizontal.
Pendant l'exécution du programme, tous les effets spéciaux seront
activables par l'intermédiaire d'un menu accessible grâce au
bouton du milieu de la souris. La sélection d'un élément du menu
active ou désactive alternativement le paramètre correspondant. Le
menu est déjà en place, mais il n'a pour l'instant aucun effet
visible.
Le programme fourni comprend par ailleurs une solution aux deux TP
précédents (ombrage et déplacement), à ceci près que toutes les options
(du menu de droite) sont activées par défaut (lumières, matériaux,
textures).
Implémentation:
Fog:
-
Le fog doit avoir une couleur de (0.8, 0.8, 0.8). Utilisez un
mode linéaire. Le fog doit commencer à une distance de 1 du point de
vue, et être total à une distance de 30. Ces paramètres sont fixes,
donc peuvent se spécifier à l'initialisation d'OpenGL.
-
Vous avez également un travail à faire dans la fonction
middle_menu_handle
, pour activer ou désactiver le fog.
N'oubliez pas que pour un effet réaliste, la couleur de fond doit
être la même que celle du fog, quand celui-ci est activé.
Transparence:
Afin d'éviter le problème des color buffers ne supportant pas de
composante alpha, nous n'utiliserons que les composantes source alpha. À
cet effet, vous noterez que toutes les couleurs ont été modifiées par
rapport au TP précédent pour fournir une composante alpha de 0.5. La
texture de bois est déjà dotée de cette composante.
On décide de rendre les deux objets latéraux transparents; les autres
resteront opaques. Pour ce faire, le blending devra être utilisé, mais
attention: le blending sert aussi à d'autres choses (par exemple, les
reflets).
Le blending se fera par modulation de la source par sa
propre composante alpha, et modulation de la destination par 1
moins cette même composante.
Ombres Portées
Le tracé des ombres portées doit être fait dans la fonction
shadows_draw()
. Il s'agit de tracer les ombres issues des
objets, de la lumière globale seulement (pas de celle du point de vue)
et qui se projettent sur le plan.
-
La lumière a pour direction (0, -1, -0.5) et le plan a pour
équation y = -2. Pour éviter que les ombres et le plan ne soient
exactement à la même hauteur (ce qui produirait du "flickering"),
on les projettera à -1.99 plutôt qu'à -2. À vous de trouver la bonne
matrice de projection. Notez que ceci se fait normalement en utilisant
une fonctionnalité d'OpenGL appellée "Polygon Offset".
-
Pour calculer la couleur de l'ombre, on fera du blending vers le noir
en utilisant la composante alpha des objets pour moduler la couleur
du plan. Autrement dit, on ne tiendra pas compte de la couleur des
objets eux même (qui devrait normalement être prise en compte pour les
objets transparents).
-
N'oublions pas non plus de ne tracer les ombres que là où se
trouve le plan (il y a donc du travail de stencil à faire).
Reflets
Le tracé des reflets doit être fait dans la fonction
reflections_draw()
. Il s'agit de refléter les objets sur
le plan.
-
Les reflets doivent être tracés symétriquement par rapport au plan
horizontal.
-
N'oubliez pas que tout doit être inversé pour tracer les reflets:
non seulement les objets, mais aussi les lumières. Faites aussi
attention aux normales, au culling etc...
-
N'oublions pas non plus de ne tracer les reflets que là où se
trouve le plan (il y a donc du travail de stencil à faire).
Tracé du plan horizontal
En fonction de la présence de reflets ou d'ombres portées, le tracé du
plan horizontal pose des problèmes (qui ont tous des solutions :-).
-
Dans la fonction
window_redisplay
, il faut commencer
par tracer le plan dans le stencil buffer si des reflets ou des
ombres sont demandées. Mais attention: ne pas le tracer dans le
color buffer à ce moment.
-
Si des reflets sont demandés, ceux-ci sont tracés avant le plan
lui-meme. Donc, pour les voir apparaitre, le plan doit être tracé
avec du blending. Pour ce cas précis, on utilisera la couleur du
plan en plein (c'est à dire une modulation de 1) et une modulation
de destination correspondante à la composante alpha de la couleur
du plan.
-
Si les reflets ne sont pas actifs, le plan ne doit pas être tracé
avec blending
-
Enfin, n'oubliez pas de définir, dans la fonction
main
,
les paramètres initiaux pour le stencil buffer, et en particulier
la valeur de nettoyage.
Conseils:
-
Commencez par lire posément le code fourni, afin de vous
familiariser avec son architecture.
-
Le fog ne pose pas de problème. Commencez par là.
-
La transparence des deux objets plans peut se faire ensuite.
-
Pour ce qui concerne les ombres portées et les reflets, ne traitez
pas tout de suite le problème du stencil: commencez par tracer les
objets en ombre et en reflet au bon endroit, puis attaquez-vous au
problème du tracé du plan, et seulement à la fin, paufinez tout ça
avec l'utilisation du stencil buffer.
Fonctions utiles:
glClearStencil, glFog*, glBlendFunc, glStencilOp, glStencilFunc,
glDrawBuffer, glCullFace, glScalef, et toutes les anciennes...