Download
ombres en temps r el n.
Skip this Video
Loading SlideShow in 5 Seconds..
Ombres en temps-réel PowerPoint Presentation
Download Presentation
Ombres en temps-réel

Ombres en temps-réel

134 Vues Download Presentation
Télécharger la présentation

Ombres en temps-réel

- - - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - - -
Presentation Transcript

  1. Ombres en temps-réel Nicolas Holzschuch Cours d’Option Majeure 2 Nicolas.Holzschuch@imag.fr

  2. Ombres en temps-réel • Pourquoi faire ? • Les ombres • Shadow maps • Shadow volumes • Ombres douces

  3. Les ombres : pourquoi ? • Réalisme accru • Positionnement spatial • Information sur les objets • Informations sur le système graphique : • Comment ça marche, pourquoi,… • Nombreuses extensions, additions,…

  4. Exemples + Vidéo

  5. Ombres dures/ombres douces • Vidéos

  6. Techniques • 2 méthodes : • Shadow mapping • Basé image • Shadow volumes • Basé objet • Démos

  7. Shadow mapping • Source lumineuse ponctuelle • Principe : • Carte de profondeur de la scène • Vue depuis la source lumineuse • Pour chaque pixel de l’image • Calculer position par rapport à la source • Calculer profondeur par rapport à la source • Comparer à la profondeur stockée • Égal : lumière, plus grand : ombre

  8. Shadow volume • Source lumineuse ponctuelle • Principe : • Silhouette des objets vus depuis la source • Plans infinis s’appuyant sur la source et sur chaque arête • Définit « volume d’ombre » • Pour chaque pixel de l’image : • Compter le nombre de plans entrants et sortants • Positif : ombre, nul : lumière

  9. Et maintenant, les détails

  10. Shadow mapping • Source lumineuse ponctuelle • Principe : • Carte de profondeur de la scène • Vue depuis la source lumineuse • Pour chaque pixel de l’image • Calculer position par rapport à la source • Calculer profondeur par rapport à la source • Comparer à la profondeur stockée • Égal : lumière, plus grand : ombre

  11. depth map image plane depth map Z = A lightsource eyeposition eye view image plane,aka the frame buffer fragment’slight Z = B Shadow mapping • A < B : ombre

  12. depth map image plane depth map Z = A lightsource eyeposition eye view image plane,aka the frame buffer fragment’slight Z = B Shadow mapping • A≈B : lumière

  13. Carte de profondeur • Comment la générer ? • Pourquoi c’est compliqué ? • back-buffer • pbuffers • Précision/coût • En xy • En z

  14. Carte graphique Mémoire Processeur graphique Pourquoi c’est compliqué ? Disque dur Mémoire CPU Écran Carte-mère

  15. Comment faire ? • Le CPU ne peut pas faire le travail : • Trop lent • Transfert trop lent • C’est le processeur graphique qui travaille • Comment faire pour dessiner la scène sans l’afficher ? • Deux solutions : back-buffer et pbuffers

  16. Double-buffering • L’affichage peut être lent • L’utilisateur voit la scène s’afficher morceau par morceau • Gênant • Idée : double-buffer • Deux buffers • On affiche le front-buffer • On dessine dans le back-buffer • Quand on est prêt : glutSwapBuffers();

  17. Double-buffering • Suppose que la carte soit équipée : • Coût mémoire supplémentaire (léger) • Automatique de nos jours • À demander à la création du contexte OpenGL glutInitDisplayMode(GLUT_DEPTH|GLUT_RGB|GLUT_DOUBLE); • Ne pas oublier d’échanger les buffers…

  18. Application aux ombres • On a un endroit pour dessiner ! • On dessine la scène une première fois : • Avec la matrice de projection de la lumière • Directement dans le back-buffer • Ensuite, transfert en mémoire • On dessine la scène une deuxième fois : • Avec la matrice de projection de la caméra • Toujours dans le back-buffer • Échange des buffers

  19. Problème • Résolution du back-buffer limitée : • À la résolution de la fenêtre • Problèmes d’aliasing • Si je veux d’avantage de résolution : • pbuffers • Possibilité de rendu sur la carte, par le processeur, dans une zone mémoire spécifique • Résolution plus grande que celle de la fenêtre • Mais pas illimitée • Pas toujours possible, dépend de la carte

  20. Pour chaque pixel • Génération de coordonnées de texture • Matrice de projection de la lampe + conversion • Résultat : (r,s,t) coordonnées de texture • r distance à la source • (s,t) coordonnées dans la carte de profondeur • Comparaison r / carteProfondeur(s,t) • Extension OpenGL : • GL_ARB_SHADOW ou GL_SGIX_SHADOW

  21. Extensions OpenGL • OpenGL : • Spécifications (www.opengl.org) • Liste de fonctionnalités (glBegin, glEnd…) • Architecture Review Board (ARB) • Extensions : • Nouvelles fonctionnalités • Décision par l’ARB (meetings) • Extensions « officielles » : • http://oss.sgi.com/projects/ogl-sample/registry/ • Spécifications approuvées, publiques • Nom et prototypes de fonctions publics • Différents niveaux d’intégration : • GL_ARB_EXTENSION, GL_EXT_EXTENSION, GL_CONSTRUCTEUR_EXTENSION

  22. Extensions OpenGL • Comment savoir si une extension est présente ? • glxinfo • http://www.delphi3d.net/hardware/index.php (liste cartes+drivers = extensions) • glutExtensionSupported("GL_SGIX_shadow"); • On y reviendra au prochain cours

  23. GL_SGIX_SHADOW glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_SGIX, GL_TRUE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_OPERATOR_SGIX, GL_TEXTURE_LEQUAL_R_SGIX); • Implémentation très simple

  24. Algorithme • Désactiver l’affichage des polygones • Dessiner la scène • Transférer le Z-buffer en mémoire • Ré-activer l’affichage des polygones • Affecter la carte de profondeur comme texture • Activer la shadow-map • Dessiner la scène • Échanger les buffers

  25. Algorithme • Désactiver l’affichage des polygones : • glColorMask(0,0,0,0); • glDisable(GL_LIGHTING); • Permet de gagner du temps • La carte graphique travaille moins • Dessiner la scène

  26. Algorithme • Récupérer le Z-buffer : glCopyTexImage2D(GL_TEXTURE_2D,0, GL_DEPTH_COMPONENT16_SGIX, 0,0,width,height,0); • Alternative : glReadPixels(0, 0, width, height, GL_DEPTH_COMPONENT, taille, pointeur); glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT16_SGIX, width, height, 0, GL_DEPTH_COMPONENT, taille, pointeur); • Double transfert CPU/carte graphique !

  27. Algorithme • Ré-activer l’affichage des polygones : glEnable(GL_LIGHTING); glColorMask(1,1,1,1); glViewport(0, 0, winWidth, winHeight); • Activer la shadow map • Dessiner la scène • Échanger les buffers

  28. Shadow mapping • Avantages : • Très simple à implémenter • Code compact • Marche toujours (scène quelconque) • Inconvénients : • Problèmes d’échantillonnage (xy et z) • Deux passes de rendu (vitesse divisée par deux) • Ne pas regénérer systématiquement la shadow map, seulement si la source se déplace • Besoin d’extensions OpenGL (disponibles ?)

  29. Échantillonnage • Principal inconvénient • Système discrétisé • Double discrétisation : caméra et source lum. • Conflit de précision

  30. Précision en xy • La plus visible • Solution : augmenter la résolution de la carte • Limite liée à la carte • Pas toujours suffisant : • Projection de la texture depuis la source • Pixels après projection déformés et agrandis • Cas idéal : source proche de la caméra • Cas le pire : source opposée à la caméra • Animal dans les phares (pas bon pour lui)

  31. Cas idéal : lampe de spéléo Caméra La couleur représente l’aire projetée d’un élément de surface Le fantôme représente l’ombre de l’objet Source

  32. Cas le pire : source opposée Caméra Source

  33. Source opposée

  34. Résolution en xy • Principale source d’erreur • Solutions : • Augmenter la résolution • Déformer la shadow map pour augmenter sa résolution près de l’œil • Résolution adaptative • Pas de solution idéale si la source est face à l’œil

  35. depth map image plane depth map Z = A lightsource eyeposition eye view image plane,aka the frame buffer fragment’slight Z = B Shadow mapping • A < B : ombre

  36. depth map image plane depth map Z = A lightsource eyeposition eye view image plane,aka the frame buffer fragment’slight Z = B Shadow mapping • A ≈ B : lumière

  37. Problèmes de précision

  38. Problème de précision • La carte de profondeur est aussi discrétisée en z • Besoin de précision : 16 bits, 24 bits… • Problèmes avec z voisins : • Auto-ombrage des surfaces • Solution : • Déplacer la carte de profondeur (bias) • Trouver la valeur idéale : • Trop peu : les surfaces s’ombrent elles-mêmes • Trop : les ombres disparaissent • glPolygonOffset();

  39. Variantes : ID-buffer • Pour éviter les problèmes d’auto-ombrage • Une couleur par objet • Objet = ? • Quelque chose qui ne peut pas s’ombrer • Convexes • Ombrage si ID objet ≠ ID dans buffer • Pas de problème de précision • Mais besoin nombreuses ID : 16 bits • Problème si objets proches les uns des autres

  40. Précision • La résolution effective dépend de la pyramide de vue de la lampe • Large cône de vue : résolution gaspillée • Plus la pyramide est proche des objets, plus on est précis • Rapprocher la pyramide de vue • En xy : faible angle d’ouverture • En z : front plane et far plane rapprochés

  41. Shadow Mapping : résumé • Avantages : • Très simple à implémenter, code compact • Marche toujours (scène quelconque) • Prix indépendant de la complexité de la scène • Nombreuses variantes pour améliorer la qualité • Inconvénients : • Problèmes d’échantillonnage (xy et z) • Deux passes de rendu • Artefacts visibles • Sources omni-directionnelles ?

  42. Shadow volume • Source lumineuse ponctuelle • Principe : • Silhouette des objets vus depuis la source • Plans infinis s’appuyant sur la source et sur chaque arête • Définit « volume d’ombre » • Pour chaque pixel de l’image : • Compter le nombre de plans entrants et sortants • Positif : ombre, nul : lumière

  43. Shadow volume

  44. Silhouette des objets • Travail sur le modèle • Pour chaque arête du modèle : • Identifier polygones qu’elle relie • Produit scalaire normale / vecteur vers la source • Si produits scalaires de signe différent : arête de silhouette • Besoin structure de données sur le maillage • Sur-ensemble de la silhouette des objets

  45. Volume d’ombre • Plans définis par (arête + source) • Définit volume d’ombre : • En fait, plusieurs volumes imbriqués • On est à l’ombre si on est à l’intérieur d’au moins un volume • Principe : pour chaque pixel, on compte les plans, de l’œil jusqu’à la surface affichée • Entrée/sortie dans le volume • Nombre total de plans croisés

  46. Compter les plans • Stencil buffer : • Autre fonctionnalité OpenGL • Buffer auxiliaire, jamais affiché • Opérations possibles : • Incrémenter/décrémenter le stencil buffer • Conditions sur le stencil buffer, actions sur l’écran • Multiples utilisations : • Ombres, réflexions, fenêtres… • Rendu conditionnel • Début de programmation de la carte

  47. Utilisation du stencil buffer • Premier rendu de la scène • Initialise le Z-buffer • Rendu du volume d’ombre • Pour chaque plan positif : glStencilOp(GL_KEEP,GL_KEEP,GL_INCR); • Pour chaque plan négatif : glStencilOp(GL_KEEP,GL_KEEP,GL_DECR); • Deuxième rendu de la scène : • glStencilFunc(GL_EQUAL, 0, ~0); • Pour la partie éclairée

  48. Algorithme : tracé du volume glDisable(GL_LIGHTING); drawScene(); /* La scène, écl. ambiant */ glDepthMask(0); /* Ne plus écrire ds Z-buffer */ glStencilFunc(GL_ALWAYS, 0, ~0); glEnable(GL_STENCIL_TEST); glEnable(GL_CULL_FACE); glCullFace(GL_BACK); glStencilOp(GL_KEEP, GL_KEEP, GL_INCR); glColorMask(0,0,0,0); /* pas modifier framebuffer */ draw_shadow_volume(); /* plans positifs */ glCullFace(GL_FRONT); glStencilOp(GL_KEEP, GL_KEEP, GL_DECR); draw_shadow_volume(); /* plans négatifs */ glColorMask(1,1,1,1); glDepthMask(1); /* On peut écrire ds Z-buffer */

  49. Algorithme : rendu de la scène glStencilFunc(GL_EQUAL, 0, ~0); glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); glEnable(GL_STENCIL_TEST); glDepthFunc(GL_EQUAL); glEnable(GL_LIGHTING); drawScene();

  50. Shadow volume • Avantages : • Ombres précises • Positions quelconques lumière/caméra • Inconvénients : • Calcul de la silhouette (sur CPU, év. long) • Besoin de modèles fermés, formés de convexes • Deux rendus de la scène, plus rendu du volume • fill-rate : tracé de nombreux polygones, qui couvrent l’écran. • Carte limitée en nb. pixels/seconde