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

Documents pareils