1 / 71

Ombres en temps-réel

Ombres en temps-réel. Nicolas Holzschuch Cours d’Option Majeure 2 Nicolas.Holzschuch@imag.fr. Ombres en temps-réel. Pourquoi faire ? Les ombres Shadow maps Shadow volumes Ombres douces. Les ombres : pourquoi ?. Réalisme accru Positionnement spatial Information sur les objets

mariko-ryan
Download Presentation

Ombres en temps-réel

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

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

More Related