Informatique Graphique Moteurs 3D temps réels OpenGL Guillaume Gilet Guillaume.Gilet@unilim.fr 2012-2013
Résumé des épisodes précédents Rasterisation Projection des sommets dans le plan image Rasterisation : Discretisation du plan image et remplissage Génère un ensemble de fragments Calcul d'une couleur (éq. du rendu) pour chaque fragment Elimination des parties cachées : Z Buer Transformations Coordonnées homogènes (vecteurs à 4 composantes en 3D) Une matrice de transformation (4x4) pour passer d'un repère 3D dans un autre Multiplication de matrice non-commutative!! X = M X La projection est (aussi) exprimée par une matrice de transformation
Le pipeline graphique
Aujourd'hui Fonctionnement du pipeline graphique Des exemples Des détails pratiques OpenGL Quelques fonctionnalités OpenGL Ex : glclear(...) : Nettoyage du Frame Buer Des détails pratique sur GobLim Moteur 3D développé au sein de l'équipe SIR OpenGL 4.2 A utiliser pour les TPs
Le pipeline graphique Principe Une liste de sommets Le pipeline graphique Une liste d'attributs (couleurs, normales...) Des relations d'adjacence + autres... (caméras, lumières, textures...) Une grille 2D de pixels
Le pipeline graphique minimal
Le pipeline graphique minimal
Le pipeline graphique Opérations par sommet En parallèle pour chaque sommet Programmable : Vertex Program Transformations géométriques et projection en 2D Déplacement des sommets (déformation de la géométrie) Au minimum Position de chaque sommet
Le pipeline graphique Assemblage de primitives Programmable : Geometry Program Information d'adjacence (Identique pour tous les sommets) Assemble les sommets 2D transformé Produit une primitive dans le plan 2D
Le pipeline graphique Rasterisation Discretisation des polygones, tracés de ligne Remplissage de polygones Algorithme de Bresenham Génère un ensemble de fragments Fragment Fragments de pixel Position xe dans l'espace 2D Peut disparaître, être mélangé Interpolation des attributs
Le pipeline graphique Opérations par fragment En parallèle pour chaque fragment Programmable : Fragment Program Calcul d'éclairage (eq. du rendu) Changement d'apparence La plupart des eets "`spéciaux"' Au minimum Couleur de chaque fragment
Le pipeline graphique Combinaison des fragments En parallèle pour chaque fragment Elimination des parties cachées Opérations de transparence Mélange des fragments avec le frame buer Remplissage du frame buer Pas de tri : Lecture/Ecriture
graphique A retenir Un sommet de la géometrie : Un triplet XYZ Opération par sommet : Vertex program Transformations géometriques Projections Assemblage et Rasterisation Fragment : Partie potentielle de pixel Opération par fragment : Fragment program Illumination Apparence Combinaison et remplissage du Frame Buer
OpenGL et GLSL
OpenGL et GLSL OpenGL OpenGL : Open Graphics Library Librairie graphique multi-plateforme bas niveau Communication avec le GPU Machine à états (pas de modication des états au cours de l'exécution du pipeline) De nombreuses évolutions majeures très récentes (version 4.3 : Aout 2012)
OpenGL et GLSL GLSL GLSL : OpenGL Shading Language Programmation du pipeline graphique Langage de haut niveau basé sur du C Des évolutions conjointes à OpenGL Shaders, Program et Ecrit en GLSL (ou HLSL, CG...) Peuvent être compilés au vol Doivent être liés (activés) avant le rendu Pour plus de facilité : Dans un chier à part
Execution en parallèle Shaders Suite d'opérations S'applique à tous les éléments Code identique éxécuté pour chaque élément entrant Programmation parallèle Indépendance des données Séparation des opérations Vertex Shader Pour chaque sommet entrant Fragment Shader Pour chaque fragment entrant
Shaders, Program et Program (OpenGL > 4.0) Un entier symbolisant un espace mémoire GPU Contient une chaine de caractère (code du shader) A un type : GL_VERTEX_SHADER,... Doit être compilé, lié (chargé en mémoire) Doit être activé à chaque utilisation du pipeline gluseprogram(glint program) Program (OpenGL > 4.2) Symbolise l'ensemble du pipeline graphique permet de dénir pour chaque stage un program S'occupe de la liaison entre shaders Permet des changements de program au vol
Shaders, Program et GLProgram Est une instance d'un Shader GLSL Chargé en mémoire graphique Une étape du pipeline graphique Possède son propre espace mémoire et un manager de variables GL Symbolise l'ensemble du pipeline graphique Pointe sur un ensemble de GLProgram S'occupe de la liaison Permet des changements de GLProgram au vol
Bases de GLSL Des types...proches du C oat : variable réelle vec avec 2, 3, 4 : vecteur de 2,3 ou 4 éléments réels ivec avec 2, 3, 4 : vecteur de 2,3 ou 4 éléments entiers mat x avec 2, 3, 4 : matrice de 2,3 ou 4 lignes (ou colonnes) Rq : On peut utiliser mat swizzle : var.xyz, var.yzx, var.yyy http ://www.khronos.org/les/opengl43-quick-reference-card.pdf
Bases de GLSL Des fonctionnalités proches du C Des boucles : while,for... Des branchements : if... then... else Dénition de fonctions ou procédures http ://www.khronos.org/les/opengl43-quick-reference-card.pdf
Bases de GLSL Des fonctionnalités orientées graphique Opérations vectorielles : dot, cross, length, normalize Opérations matricielles :, inverse, transpose Trigonométrie : cos, sin, tan Opérations sur les valeurs : clamp, step http ://www.khronos.org/les/opengl43-quick-reference-card.pdf3
Mécanismes de communication Comment échanger des informations? Entre les étapes du pipeline Entre l'application CPU et le GPU Des informations de natures diverses Nature des informations Des variables globales Flux de données Diérents attributs pour chaque élément (sommet,fragment)
Mécanismes de communication
Mécanisme de communication Communication Shader-Shader Qualicateur in Elements traversant le pipeline (ux de données) Une entrée du programme En lecture uniquement Ex : position, couleur d'un sommet Ex : couleur interpolée, profondeur d'un fragment Qualicateur out Elements traversant le pipeline (ux de données) Une sortie du programme En écriture uniquement Sera transmise à l'étape suivante du pipeline Ex : position projetée d'un sommet Ex : couleur,profondeur nale d'un fragment
Mécanisme de communication Communication CPU-Shader Qualicateur uniform Variable identique pour tous les éléments Transmise au shader par l'application Ex : matrice de projection Variables Uniform Changement d'état Fonction gluniform**(...) Ex : gluniform3f(int locgpu,oat a,oat b,oat c) glgetuniformlocation(int shader, string nom) Le shader doit être activé Attention au changement d'état Buers et blocs de données ( OpenGL > 3.2) Espace mémoire réservé (Uniform Buer Object) Direct State Access Un seul appel OpenGL pour charger le UBO
Mécanisme de communication Communication CPU-Shader Gestion des Uniform Un parser automatique de variables uniform Un GLProgram contient un manager de variables Un ensemble de GPUVariable : pointeurs sur la mémoire GPU (buer) Erreurs achées sur la console : pas de crash (en théorie) GPUVariable Des templates : GPUoat, GPUvec3, GPUmat4... Contient un pointeur sur le buer GPU correspondant Une fonction GPU* getgpu*(string nomgpu) pour l'initialiser Une fonction void Set(* v) pour écrire dans le buer GPU Contient une copie des données sur le GPU
Mécanisme de communication A retenir Qualicateur Uniform Variable globale Identique pour tous les éléments du pipeline Vient du CPU Qualicateur in Entrée du programme (RO) Qualicateur out Sortie du programme (WO) Variable out X d'une étape = Variable in X de l'étape suivante
Quelques exemples
Un premier exemple Modèle géométrique d'entrée
Un premier exemple Programme simple Un programme basique Équivalent du pipeline xe (pré-opengl 3.0) Objectif : Réaliser la projection de la géométrie sur le plan image Assigner une couleur unique à chaque sommet Assigner à chaque fragment la couleur interpolée de chaque sommet Données d'entrée du pipeline Un tableau de positions dans l'espace 3D (exprimées en fonction d'un repère local) Une matrice (transformation et projection) pour transformer depuis l'espace local jusqu'à l'espace 2D du plan image.
Un premier exemple Du coté CPU Récuperer la GPUVariable pointant sur la mémoire graphique Calculer et transmettre la matrice de transformation Activer le pipeline Envoyer la géométrie dans le pipeline Désactiver le pipeline Lors de l'initialisation modelviewproj = vp->uniforms()->getgpumat4("mvp") ; A chaque frame, pour un objet o mat4 M = o >frame() > g e t T r a n s f o r m M a t r i x ( ) ; modelviewproj >S e t (M) ; m_program >bind ( ) ; o >drawgeometry ( GL_TRIANGLES ) ; m_program >r e l e a s e ( ) ;
Un premier exemple Première étape : Vertex Program
Un premier exemple Première étape : Vertex Program Variables uniform du vertex program Une matrice de transformation MVP (identique pour toutes les occurences) Données d'entrée pour chaque occurence du vertex program In : La position 3D d'un sommet Données de sortie pour chaque occurence du vertex program Out : UNE position 2D dans le plan image : gl_position (obligatoire) Une couleur
Mécanismes de communication
Un premier exemple Vertex Program simple Main-VS.glsl #v e r s i o n 420 l a y o u t ( std140 ) uniform CPU { mat4 MVP; } ; l a y o u t ( l o c a t i o n = 0) i n vec3 P o s i t i o n ; out gl_pervertex { vec4 g l _ P o s i t i o n ; } ; out vec3 v_color ; v o i d main ( ) { g l _ P o s i t i o n = MVP vec4 ( P o s i t i o n, 1. 0 ) ; v_color = vec3 ( 0. 2, 0. 3, 0. 7 ) ; }
Un premier exemple Quatrième étape : Fragment Program
Un premier exemple Quatrième étape : Fragment Program Données d'entrée pour chaque occurence du fragment program In :La couleur (interpolée) d'un fragment Données de sortie pour chaque occurence du fragment program Out : Une couleur (nale) pour chaque fragment
Mécanismes de communication
Un premier exemple Fragment Program simple Main-FS.glsl #v e r s i o n 420 i n vec3 v_color ; out vec4 C o l o r ; v o i d main ( ) { C o l o r = vec4 ( v_color, 1. 0 ) ; }
Un premier exemple Résultat
Deuxième exemple Programme simple Et si on déni la couleur dans l'application?? Objectif : Réaliser la projection de la géométrie sur le plan image Assigner à chaque fragment une couleur dénie par l'application Données d'entrée du pipeline Un tableau de positions dans l'espace 3D (exprimées en fonction d'un repère local) Une matrice (transformation et projection) pour transformer depuis l'espace local jusqu'à l'espace 2D du plan image. Une couleur (dénie par l'application)
Deuxième exemple Du point de vue de l'application Calculer et transmettre au shader la couleur A chaque frame en OpenGL gluniform3fv(glgetuniformlocation(fp- >getprogram(),"cpucolor"),vec3(0.5,0.4,0.6))) ; Initialisation GPUvec3* couleur = fp->uniforms()->getgpuvec3("cpucolor") ; N'importe quand dans le code couleur->set(vec3(0.5,0.4,0.6)
Deuxième exemple Du point de vue des shaders Ou récuperer et assigner la couleur?? Dans le vertex program et interpolation pour chaque fragment? Dans le fragment program?
Deuxième exemple Quatrième étape : Fragment Program
Deuxième exemple Quatrième étape : Fragment Program Variables uniform du fragment program Une couleur globale (identique pour tous les fragments) Données d'entrée pour chaque occurence du fragment program Aucune Données de sortie pour chaque occurence du fragment program Out : Une couleur (nale) pour chaque fragment
Deuxième exemple Fragment Program simple Main-FS.glsl #v e r s i o n 420 l a y o u t ( std140 ) uniform CPU { vec3 CPUColor ; } ; out vec4 C o l o r ; v o i d main ( ) { C o l o r = vec4 ( CPUColor, 1. 0 ) ; }
Deuxième exemple Résultat
Troisième exemple Modèle géométrique d'entrée
Troisième exemple Une couleur spécique pour chaque sommet Visualisons l'information de normale Objectif : Réaliser la projection de la géométrie sur le plan image Assigner à chaque sommet une couleur particulière (par exemple la normale) Données d'entrée du pipeline Un tableau de positions dans l'espace 3D (exprimées en fonction d'un repère local) Un tableau d'attributs de sommet : La normale Une matrice (transformation et projection) pour transformer depuis l'espace local jusqu'à l'espace 2D du plan image.
Troisième exemple Première étape : Vertex Program
Troisième exemple Première étape : Vertex Program Variables uniform du vertex program Une matrice de transformation MVP (identique pour toutes les occurences) Données d'entrée pour chaque occurence du vertex program In : La position 3D d'un sommet In : La normale d'un sommet Données de sortie pour chaque occurence du vertex program Out : position 2D dans le plan image Out : couleur pour chaque sommet
Mécanismes de communication
Troisième exemple Vertex Program simple n 3 Main-VS.glsl #v e r s i o n 420 l a y o u t ( std140 ) uniform CPU { mat4 MVP; } ; l a y o u t ( l o c a t i o n = 0) i n vec3 P o s i t i o n ; l a y o u t ( l o c a t i o n = 2) i n vec3 Normal ; out gl_pervertex { vec4 g l _ P o s i t i o n ; } ; out vec3 v_color ; v o i d main ( ) { g l _ P o s i t i o n = MVP vec4 ( P o s i t i o n, 1. 0 ) ; v_color = abs ( Normal ) ; }
Troisième exemple Quatrième étape : Fragment Program
Troisième exemple Quatrième étape : Fragment Program Données d'entrée pour chaque occurence du fragment program In : La couleur (interpolée) d'un fragment Données de sortie pour chaque occurence du fragment program Out : Une couleur (nale) pour chaque fragment
Troisième exemple Fragment Program simple n 3 Main-FS.glsl #v e r s i o n 420 i n vec3 v_color ; out vec4 C o l o r ; v o i d main ( ) { C o l o r = vec4 ( v_color, 1. 0 ) ; }
Un premier exemple Résultat
Divers eets visuels Eclairage de Phong
Divers eets visuels Eclairage de Phong + couleur par sommet
Divers eets visuels Eet Cartoon
Divers eets visuels Reexions de l'environnement
Divers eets visuels Couleur procédurale + Ambiant Occlusion + Phong
Création de shader Préparation d'un shader Dénir l'eet visuel souhaité Dénition des ressources d'entrées Positions, attributs Informations données par l'application Méthode de calculs utilisées Préparation des étapes Pour chaque étape (VP et FP) Dénir les entrées et sorties Dénir où calculer les informations
Création de shader Calculs dans le vertex program Coût pour le vertex program Calcul d'un cout X eectué une fois pour chaque sommet Coût total : X * nombre_de_sommets Pour un modèle 3D utilisé en JV [10 100000]
Création de shader Calculs dans le vertex program Coût pour le vertex program Calcul d'un cout X eectué une fois pour chaque sommet Coût total : X * nombre_de_sommets Pour un modèle 3D utilisé en JV [10 100000] Impact visuel Informations pour chaque sommet Interpolation linéaire (étape 3) Dépend de la géométrie Dépend du calcul eectué (peut-il s'interpoler linéairement?)
Création de shader Calculs dans le fragment program Coût pour le fragment program Calcul d'un cout Y eectué une fois pour chaque fragment Coût total : Y * nombre_de_fragments Dépend de la couverture de l'écran par l'objet Dépend des recouvrements (Z-buer)... et donc de l'objet aussi Par exemple (pour un plan face à la caméra) : 1024 1024 1M
Création de shader Calculs dans le fragment program Coût pour le fragment program Calcul d'un cout Y eectué une fois pour chaque fragment Coût total : Y * nombre_de_fragments Dépend de la couverture de l'écran par l'objet Dépend des recouvrements (Z-buer)... et donc de l'objet aussi Par exemple (pour un plan face à la caméra) : 1024 1024 1M Impact visuel Informations pour chaque fragment pas besoin d'interpolation
Création de shader Exemple : par sommet Illumination diuse - interpolation linéaire 13K évaluations
Création de shader Exemple : par fragment Illumination diuse - interpolation linéaire 1M évaluations
Création de shader Exemple : par sommet Réexions - interpolation linéaire 13K évaluations
Création de shader Exemple : par fragment Réexions - interpolation linéaire 1M évaluations
Création de shader Conclusion Ou eectuer les calculs? Interpolation linéaire susante? Ressources limitées? Dans le vertex program Sinon Dans le fragment program
Des Questions?