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