Exemples d`effets avec stencil
Transcription
Exemples d`effets avec stencil
Chapitre VI : Exemples d’effets avec stencil Programmation 3D Fabrice Aubert [email protected] Licence/Master USTL - IEEA 2008-2009 F. Aubert (LS6/MS2) P3D/ VI Effets avec stencil 2008-2009 1 / 28 1 Miroir plan 2 Localisation de points dans un volume (exemple de la coupe) 3 Ombres F. Aubert (LS6/MS2) P3D/ VI Effets avec stencil 2008-2009 2 / 28 1 Miroir plan F. Aubert (LS6/MS2) P3D/ VI Effets avec stencil 2008-2009 3 / 28 Principe Le miroir est un plan qui réfléchit toute la scène La scène réfléchie (i.e « virtuelle » ) correspond à la scène répétée symétriquement par rapport au miroir. Principe : Tracer toute la scène « virtuelle » par rapport au miroir (i.e. symétrique) Limiter ce tracé aux seuls pixels du miroir (stencil) Mélanger les couleurs. F. Aubert (LS6/MS2) P3D/ VI Effets avec stencil 2008-2009 4 / 28 Analyse Tracer 2 fois la scène (la scène et son symétrique). Le plan ne doit pas occulter la scène virtuelle (⇒ manipulation du depth buffer ?). Le plan doit occulter ce qui est tracé derrière le plan (⇒ obligation de sélectionner « à la main » ce qui se réfléchit, i.e ce qui se trouve devant le miroir). Si le miroir est visible (couleur, texture), il faut mélanger la couleur du plan avec la réflexion. Le symétrique ne doit pas dépasser du miroir : Conditionner le tracé de la réflexion par le miroir. Gestion de l’éclairement (non traité ici) : la scène réfléchie est éclairée avec les sources réfléchies (par ailleurs les sources réfléchies participent à l’éclairement total (...)). ⇒ Etudier l’ordre de tracé pour résoudre toutes ces contraintes. F. Aubert (LS6/MS2) P3D/ VI Effets avec stencil 2008-2009 5 / 28 Ordre de tracé Stencil : tracer plan avant réflexion (pour conditionner). Mélange : tracer réflexion avant plan (il ne faut pas faire le mélange quand la réflexion se trace ⇒ la réflexion se mélangerait avec elle-même). Parties cachées : tracer plan après réflexion (inutile de manipuler le depth buffer : la réflexion se trouve nécessairement derrière le miroir). Tracer la scène « normale » après l’effet. ⇒ Tracer plusieurs fois le miroir pour répondre aux contraintes (d’abord pour le stencil, et ensuite pour le mélange). F. Aubert (LS6/MS2) P3D/ VI Effets avec stencil 2008-2009 6 / 28 Une solution 1 Tracer miroir avec mise à jour du stencil (sans mises à jour depth et couleur). 2 Tracer la scène symétrique avec test du stencil (application d’une transformation à la scène « normale » ). 3 Tracer le miroir avec mélange (mise à jour couleurs, et depth). 4 Tracer la scène « normale » . Remarque : le mélange doit traduire qu’il s’agit de la scène réfléchie qui est plus ou moins atténuée sur le miroir (ne doit pas influencer la couleur propre du miroir) ⇒ glBlendFunc(GL_ONE_MINUS_DST_ALPHA, GL_DST_ALPHA) (sur l’exemple la vache réfléchie est tracé avec un alpha à 0.4). F. Aubert (LS6/MS2) P3D/ VI Effets avec stencil 2008-2009 7 / 28 2 Localisation de points dans un volume (exemple de la coupe) F. Aubert (LS6/MS2) P3D/ VI Effets avec stencil 2008-2009 8 / 28 Le problème On considère un volume représenté par son bord (i.e. polygones bien orientés) On veut afficher une coupe de ce volume (coupe par un plan). ⇒ Tracer uniquement les pixels du plan qui sont intérieurs au volume. F. Aubert (LS6/MS2) P3D/ VI Effets avec stencil 2008-2009 9 / 28 Localisation Soit un point P de l’espace. Soit V un volume représenté par son bord B. On considère une demi-droite D quelconque d’origine P. ⇒ Le point P est intérieur à un volume si et seulement si le nombre d’intersection de D avec B est impair. Remarque : Tous les cas particuliers (tangences, et appartenances à P) peuvent être traités algorithmiquement en forçant le fait que D ne passe jamais par un sommet. F. Aubert (LS6/MS2) P3D/ VI Effets avec stencil 2008-2009 10 / 28 Principe en OpenGL Lorsqu’un pixel Pi se trace, cela correspond à la projection d’un point 3D P. Si Pi est un pixel du plan de coupe : doit-on l’afficher ou non ? (est-il intérieur ou non à V ?). On peut alors raisonner sur la demi-droite D = (PPi ). ⇒ Combien de fois rencontre-t-on le bord B entre P et Pi ? F. Aubert (LS6/MS2) P3D/ VI Effets avec stencil 2008-2009 11 / 28 Principe en OpenGL Il suffit de compter tout ce qui se trace entre P et Pi . C’est-à-dire compter tous les points de B qui sont entre P et Pi . C’est-à-dire compter tous les pixels de B qui se tracent en Pi (⇒ comptage avec stencil). F. Aubert (LS6/MS2) P3D/ VI Effets avec stencil 2008-2009 12 / 28 Remarques F. Aubert (LS6/MS2) P3D/ VI Effets avec stencil 2008-2009 13 / 28 Etapes de la solution // Mise à jour des profondeurs du plan (tracer le plan dans le depth uniquement) : Désactiver(Couleur Maj) ; Tracer(Plan) ; // Compter : Désactiver(Depth Maj) ; // pas d’occultations de l’objet sur lui-même Remarque : le test est toujours actif (l’objet subit l’élimination par le plan). Activer(Stencil Maj, +1) ; // incrémenter (si depth et stencil passent) Tracer(Objet) ; // Résultat : Désactiver(Stencil Maj) ; Activer(Couleur Maj) ; Activer(Stencil Test, = impair) ; Désactiver(Depth Test) ; // utile pour éviter le z-fighting Tracer(Plan) ; F. Aubert (LS6/MS2) P3D/ VI Effets avec stencil 2008-2009 14 / 28 Pollution A la fin du tracé, le depth buffer contient tout le plan de coupe (y compris les pixels non intérieurs à l’objet, i.e. y compris les pixels du plan qui ne sont pas vus). Pose un problème, si on veut tracer des choses après (subiraient l’occultation par tout le plan). ⇒ Effacer tout le depth buffer avant de tracer le résultat (en activant la mise à jour du depth). Et si des choses sont tracées avant l’effet de coupe ? ⇒ copier le contenu du depth buffer. F. Aubert (LS6/MS2) P3D/ VI Effets avec stencil 2008-2009 15 / 28 Test de parité Le test de parité peut s’obtenir en testant le premier bit avec le masque ⇒ glStencilFunc (GL NOTEQUAL,0,0x1); : Stencil Test passe si valeur impaire F. Aubert (LS6/MS2) P3D/ VI Effets avec stencil 2008-2009 16 / 28 3 Ombres F. Aubert (LS6/MS2) P3D/ VI Effets avec stencil 2008-2009 17 / 28 Ombre par projection sur un plan Consiste à tracer l’ombre comme un ensemble de polygones. L’ombre est constituée des polygones de l’objet qui sont projetés sur le plan (objet « écrasé » sur le plan). ⇒ Il suffit de : Appliquer la matrice de projection correcte Tracer l’objet en noir en limitant au plan le tracé de l’ombre (stencil) F. Aubert (LS6/MS2) P3D/ VI Effets avec stencil 2008-2009 18 / 28 Calcul de la matrice de projection Différencier les sources ponctuelles et directionnelles. Equation du plan de projection : a x + b y + c z + d = 0 → − P : un des sommets de l’objet à projeter, L : vecteur directionnel d’une source de lumière, L : position d’une source ponctuelle Comment calculer les points P’ ? L P P' P'2 L P P2 P2 P' P'2 Source directionnelle Source ponctuelle Exercice : trouver l’équation d’un plan à partir de sa normale et d’un point lui appartenant F. Aubert (LS6/MS2) P3D/ VI Effets avec stencil 2008-2009 19 / 28 Cas de la source directionnelle Calcul intersection droite et plan ( → − P0 = P + α L ax +b y +c z +d =0 on en déduit α = − a Px +b Py +c Pz +d a Lx +b Ly +c Lz et la matrice de projection b Ly + c Lz −b Lx −a Ly a L x + c Lz −a Lz −b Lz 0 0 F. Aubert (LS6/MS2) −c Lx −c Ly a Lx + b Ly 0 P3D/ VI Effets avec stencil −d Lx −d Ly −d Lz a Lx + b Ly + c Lz 2008-2009 20 / 28 Cas de la source ponctuelle Calcul intersection droite et plan P 0 = P + α (P − L) ax +b y +c z +d =0 a P +b P +c P +d x y z on en déduit α = − a (Px −Lx )+b (Py −Ly )+c (Pz −Lz ) et la matrice de projection b Ly + c Lz + d −a Ly −a Lz −a F. Aubert (LS6/MS2) −b Lx a Lx + c Lz + d −b Lz −b −c Lx −c Ly a Lx + b Ly + d −c P3D/ VI Effets avec stencil −d Lx −d Ly −d Lz a Lx + b Ly + c Lz 2008-2009 21 / 28 Remarques Eviter le z-fighting en décalant légèrement l’ombre par rapport au plan. Si on veut une ombre moins franche, il faut mélanger la couleur de l’ombre avec celle du plan : Attention aux mélanges multiples de l’ombre avec elle-même ... utiliser le stencil ! Réalisable quand le récepteur de l’ombre est un plan (projeter l’ombre sur chacun des polygones d’un récepteur complexe serait beaucoup trop lourd). F. Aubert (LS6/MS2) P3D/ VI Effets avec stencil 2008-2009 22 / 28 La solution en OpenGL g l S t e n c i l F u n c (GL ALWAYS , 1 , 1 ) ; AffichePlan (); g l E n a b l e ( GL BLEND ) ; // Pour une ombre m o i n s f r a n c h e g l B l e n d F u n c ( GL SRC ALPHA , GL ONE MINUS SRC ALPHA ) ; g l D i s a b l e ( GL LIGHTING ) ; // p a s d ’ é c l a i r e m e n t p o u r l ’ ombre . . . g l P u s h M a t r i x ( ) ; // s a u v e g a r d e m a t r i c e c o u r a n t e C a l c u l M a t r i c e P r o j e c t i o n (mp , l p o s ) ; // mp e s t a f f e c t é e à l a m a t r i c e de // p r o j e c t i o n en f o n c t i o n de l ’ é c l a i r a g e l p o s g l T r a n s l a t e f ( . . . ) ; // Pour é v i t e r l e z−f i g h t i n g g l M u l t M a t r i x f (mp ) ; g l S t e n c i l F u n c ( GL EQUAL , 1 , 1 ) ; // E v i t e mé l a n g e de l ’ ombre a v e c e l l e −m g l S t e n c i l O p ( GL KEEP , GL KEEP , GL ZERO ) ; g l C o l o r 4 f ( 0 , 0 , 0 , 0 . 4 ) ; // Ombre n o i r e AfficherObjet (); glPopMatrix ( ) ; g l E n a b l e ( GL LIGHTING ) ; g l D i s a b l e ( GL BLEND ) ; glColor4f ( . . . ) ; A f f i c h e r O b j e t ( ) ; // A f f i c h e o b j e t r é e l F. Aubert (LS6/MS2) P3D/ VI Effets avec stencil 2008-2009 23 / 28 Volume d’ombre (Shadow Volumes) « Assombrir » tous les points de la scène (récepteur) qui sont dans le volume d’ombre. Utilisation du test de localisation par stencil. F. Aubert (LS6/MS2) P3D/ VI Effets avec stencil 2008-2009 24 / 28 Plusieurs polygones émetteurs Tracer la scène avec éclairement quand le stencil est pair, et sans éclairement sinon (scène tracée 3 fois en tout). Le cumul du test de localisation par parité dans les volumes d’ombre en intersection pose un problème ! F. Aubert (LS6/MS2) P3D/ VI Effets avec stencil 2008-2009 25 / 28 Problème du test de parité ⇒ Utiliser une variante de la propriété de localisation : En partant de l’observateur (qu’on suppose extérieur au volume), la demi-droite D entre nécessairement dans V par une facette frontale, et sort nécessairement par une facette arrière. ⇒ Il suffit de compter +1 pour une facette frontale et −1 pour une facette arrière (attention : il y a utilisation du « wrap around » des valeurs de stencil). Le test devient glStencilFunc(GL_NOT_EQUAL,0,0xFFFFFFFF) F. Aubert (LS6/MS2) P3D/ VI Effets avec stencil 2008-2009 26 / 28 Solution // Mettre à jour les profondeurs du récepteur (tracer le récepteur dans le depth uniquement) : Désactiver(Couleur Maj) ; Tracer(Récepteur) ; // Compter : Désactiver(Depth Maj) ; // pas d’occultations de l’objet sur lui-même Remarque : le test est toujours actif (le volume d’ombre subit l’élimination par le récepteur). Activer(Stencil Maj, +1) ; Activer(Culling, Faces arrières) ; Tracer(Volume d’ombre) ; Activer(Stencil Maj, -1) ; Activer(Culling, Faces frontales) ; Tracer(Volume d’ombre) ; // Résultat : Effacer(Depth buffer) ; // si rien n’est tracé avant l’effet Activer(Depth buffer) ; Désactiver(Stencil Maj) ; Activer(Couleur Maj) ; Désactiver(Culling) ; Activer(Stencil Test, 6= 0) ; Tracer(Récepteur) ; // seulement en Ambiant (partie dans l’ombre) Activer(Stencil Test, = 0) ; Tracer(Récepteur) ; // avec éclairement diffus (partie éclairée). F. Aubert (LS6/MS2) P3D/ VI Effets avec stencil 2008-2009 27 / 28 Remarques Il faut construire pour chaque polygone émetteur son volume d’ombre (chaque arête génère une face). Constuire les volumes d’ombre avec une orientation correcte (il faut déterminer l’orientation de l’émetteur par rapport à la source). Optimisation : détermination géométrique de la silhouette d’un objet émetteur complexe. F. Aubert (LS6/MS2) P3D/ VI Effets avec stencil 2008-2009 28 / 28