fragment

Transcription

fragment
Transparence et réflexions
[email protected]
Problématiques du rendu d'une scène 3D
Quelle est la couleur de chaque pixel de la caméra ?
?
lumière
nt
e
m
ne
n
o
vir
n
e
?
– Interactions lumières/matières
• Propriétés de la surface et des sources
– Transport de la lumière
• Ombres portées (visibilité sources-point)
• Réflexions (diffuses, spéculaires)
• Réfractions (« transparence »)
– Quelle est le point de la scène correspondant ?
• Quelles sont ses propriétés ?
– Normale, matériau, « couleur » (texture)
vis
ibl
e •
?surface
réf
r
act
ion
Pipeline Graphique sur GPU
Sommets
(+couleurs, coord.
de textures,
normales, ...)
Vertex
Shader
Mémoire vidéo (buffers)
textures
textures
textures
Assemblage
Raster
(programmable)
Paramètres
Matrices
de transf.
Fragment
Shader
(programmable)
Topologie
(points, triangles, ...)
Application
Paramètres
matériaux,
lumières,...
Frame
Frame
Frame
Buffer
Buffer
Buffer
Per
fragment
operations
Pipeline Graphique sur GPU
Frame
Frame
Frame
Buffer
Buffer
Buffer
Vertex
Shader
(programmable)
Assemblage
Raster
Fragment
Shader
(programmable)
Per
fragment
operations
Fragment Pipeline (vue simplifiée)
Depth
Buffer
fragment
- RGBA
-z
Alpha
Test
Depth
Test
Blending
Color
Buffer
Display
Alpha test
•
Test alpha
– Supprime le fragment si la composante transparence (alpha,a) ne satisfait pas
un certain critère
– Critère = comparaison à une valeur de référence
– ex : grillage, feuilles des arbres, …
– OpenGL:
• glAlphaFunc(GLenum func, GLclampf ref)
• func = GL_NEVER, GL_ALWAYS, GL_LESS, GL_GREATER, GL_EQUAL, GL_LEQUAL,
GL_NOTEQUAL, GL_GEQUAL
• glEnable/Disable(GL_ALPHA_TEST)
Frame
Frame
Frame
Buffer
Buffer
Buffer
Compositing
Vertex
Shader
Assemblage
(programmable)
Raster
Fragment
Shader
(programmable)
Per
fragment
operations
Depth
Buffer
fragment
- RGBA
-z
Alpha
Test
Depth
Test
Blending
Color
Buffer
Display
Compositing
•
Blending
– Les fragments sont mélangés avec les pixels du color buffer
• Cpixel = Cfrag*factorsrc + Cpixel*factordst
– permet de simuler la transparence
– OpenGL:
• glBlendFunc(GLenum source, GLenum destination)
• Activé par : glEnable/Disable(GL_BLEND)
Blending avancé
•
Contrôle de l'opération de mélange
RGB_pixel = func(RGB_frag * fRGB_src, RGB_pixel * fRGB_dst)
A_pixel = func(A_frag * fA_src, A_pixel * fA_dst)
– func = FUNC_ADD, FUNC_SUBTRACT, FUNC_REVERSE_SUBTRACT, MIN, MAX
– f* = GL_{SRC, DST, CONSTANT}_{ALPHA, COLOR},
GL_ONE_MINUS_{SRC, DST, CONSTANT}_{ALPHA, COLOR}
Rendu des objets transparents
•
alpha-blending
pixel = frag_rgb * frag_alpha + pixel * (1-frag_alpha)
– OpenGL : glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
– utilise l'alpha du fragment
– méthode de rendu :
• tracer les objets opaques
• activer le blending
• tracer les objets transparents du plus profond au moins profond
– => trier les objets !! pb. d'auto intersection => découpage !!
• ou bien trier les fragments....
•
addition :
pixel = pixel + fragment
– utilisé pour les phénomènes lumineux (flares, lumière, fantômes,...)
Réflexions planaires : le miroir
•
Miroir = surface planaire réfléchissante
•
Tracer la scène une deuxième fois,
réfléchi par rapport au plan du miroir
– concaténer la matrice de réflexion avec la matrice de vue
•
Utilisation du stencil pour limiter la réflexion au polygone du miroir
•
Exercice : calculer la transformation de réflexion :
équation du plan receveur :
Ax + By +Cz +D = 0
1 – 2A² -2AB -2AC -2AD
-2BA 1 – 2B² -2BC -2BD
-2CA -2CB 1 – 2C² -2CD
0 0 0 1
Miroir exemple
•
Mettre le stencil buffer à 0
•
Dessiner le polygone du miroir en mettant le stencil à 1
•
Dessiner la scène réfléchie seulement là où le stencil est à 1
Frame
Frame
Frame
Buffer
Buffer
Buffer
Stencil buffer
Vertex
Shader
Assemblage
(programmable)
Raster
Fragment
Shader
(programmable)
Per
fragment
operations
Stencil
Buffer
Depth
Buffer
fragment
- RGBA
-z
Alpha
Test
Stencil
Test
Depth Blending
Test
Color
Buffer
Display
Utilisation du stencil buffer
•
Test par pixel sur la valeur du stencil buffer
• Fragment rejeté si test raté
• Test effectué avant le test de profondeur
Test = func (ref & mask , svalue & mask)
•
•
•
•
& = ET logique bits à bits
mask = entier 32 bits
ref = valeur de référence (! ce n'est pas un attribut du fragment !)
func = GL_{ALWAYS, NEVER, LESS, EQUAL, GREATER,
NOTEQUAL, GEQUAL, LEQUAL}
• svalue = valeur dans le stencil buffer
• voir : glStencilFunc(), glEnable/Disable(GL_STENCIL_TEST), etc.
Utilisation du stencil buffer
•
Différentes opérations sur la valeur dans le stencil buffer selon
•
•
•
•
•
test de stencil raté (fail)
test de profondeur raté (zfail)
test de profondeur réussi (zpass)
glStencilOp(fail, zfail, zpass)
Opérations possibles :
•
•
•
•
GL_KEEP : garder la valeur
GL_REPLACE : remplacer par la valeur référence
GL_ZERO : remplacer par zéro
GL_INCR, GL_DECR : incrémenter, décrémenter
(avec saturation, càd: 255++ => 255 et 0-- => 0)
• GL_INVERT : inverser bit à bit
• GL_INCR_WRAP, GL_DECR_WRAP : incrémenter, décrémenter
(avec bouclage sur l'octet, càd: 255++ => 0 et 0-- => 255)
Exemple : le miroir
glStencilFunc(GL_ALWAYS, 1, 255);
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
glEnable(GL_STENCIL_TEST);
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
glDepthMask(GL_FALSE);
// tracer le plan dans le stencil uniquement
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
glDepthMask(GL_TRUE);
// activer un vertex shader avec calcul de la symétrie
// et de la distance de clipping
glStencilFunc(GL_EQUAL, 1, 255);
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
// tracer la scène
glDisable( GL_STENCIL_TEST );
// tracer le plan avec blending
// ou seulement dans le tampon de profondeur)
Miroir et plan de clipping
•
Miroir
Problème :
Observateur
Scène
Scène réfléchie
Le miroir est caché
par le mur réfléchi !
•
Solution : ne pas tracer ce qui est derrière le miroir lors du tracé de
la scène réfléchie
•
Utilisation des plans de clipping supplémentaires :
Vertex shader output : gl_ClipDistance[i]
glEnable/Disable(GL_CLIP_DISTANCEi)
Réflexions sphériques
•
Utilisation
– texture d'environnement mappée sur une (hémi)sphère
– calcul des coordonnées de textures à la volé
• calculer le vecteur réfléchi
– r = u – 2 n n^T u
• puis mapping 3D unitaire → 2D
– différentes possibilités (1 hémisphère, 2 hémisphères, etc.)
– par sommet (vertex shader) ou par fragment (fragment shader)
•
Réflexions sphériques :
– qualité dépend de la paramétrisation
• fortes déformations =>
réflexions bas de gamme
• texture d'environnement
difficile à générer
Cube mapping
•
Paramétrisation de la sphère par un cube = cube mapping
– Un "cube map" est composé de six textures carrées de même taille,
représentant un cube centré à l’origine :
Top
Left
Front
Right
Back
Bottom
– Chaque texture du cube
correspond à une direction :
+X, -X, +Y, -Y, +Z, -Z
– Équivalent à 6 textures 2D avec
un accès particulier...
+Y
+
X
Z
Cube mapping
•
Le cube map est accédé par des coordonnées de textures 3D (r x, ry, rz)
•
Une transformation 3D->2D est réalisée (automatiquement) pour
accéder à une des six textures 2D :
– sélectionner la texture par la composante la plus grande :
soit T la plus grande et (sc, tc) les deux autres
– calculer s et t :
• s = 0.5 * (sc / abs(T) + 1 )
• t = 0.5 * (tc / abs(T) + 1 )
– utiliser (s,t) pour accéder au texel de la texture sélectionnée
Cube mapping en pratique
•
OpenGL
– Nouveaux paramètres de destination :
GL_TEXTURE_CUBE_MAP_{POSITIVE,NEGATIVE}_{X,Y,Z}
– Exemple :
glTexImage2D( GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0,GL_RGB, w, h,
0, GL_RGB, GL_UNSIGNED_BYTE, face_px );
glTexImage2D( GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0,GL_RGB, w, h,
0, GL_RGB, GL_UNSIGNED_BYTE, face_nx );
/* idem pour les 2 autres directions */
•
Shader
– Déclaration du sampler :
uniform samplerCube cubemap ;
– Utilisation :
vec3 r = …. ; // ex : calcul du vecteur réfléchi
vec4 color = texture(cubemap, r) ;
Reflexions avec le Cube mapping
•
Pour chaque image
– Générer les six vues du cube, ex. pour la 1ère :
• positionner la caméra au centre de l'objet/scène
– angle d'ouverture de 90°
– direction : +X
• activer le rendu dans la 1ère image du cube map (FBO)
glFramebufferTexture2D(fbo_id,GL_COLOR_ATTACHMENT0,
GL_TEXTURE_CUBE_MAP_POSITIVE_X,cubemap_id,0,0) ;
–
–
–
–
• tracer le reste de la scène
activer la caméra principale
tracer le reste de la scène
activer le cube map et le shader correspondant
(avec calcul du vecteur réfléchi)
tracer l'objet
Cube map : exemple
-z
+x
py
+y
nx
+y
+z
+y
+x
pz
+z
ny
+x
px
+y
-z
nz
-x
Cube map : exemple

Documents pareils