Synthèse d'images – Rendu temps réel - team.inria.fr · – Le pipeline de rendu (OpenGL) ......
-
Upload
duongkhuong -
Category
Documents
-
view
215 -
download
0
Transcript of Synthèse d'images – Rendu temps réel - team.inria.fr · – Le pipeline de rendu (OpenGL) ......
Introduction … mathématiques – informatique – physique – biologie ...
… réseau – informatique graphique – logique ...
… simulation – synthèse d'images – modélisation géométrique …
… rendu expressif – rendu temps réel – rendu hors ligne ...
2
Copie dépôt pour le TP • Soit vous avez un moteur opengl un peu
fonctionnel (par exemple de l’UE moteur de jeu) • Soit vous pouvez récupérer le dépôt de
LearnOpenGL – git clone --recursive https://github.com/JoeyDeVries/
LearnOpenGL.git – git clone --recursive https://github.com/dlyr/
LearnOpenGL.git – git clone --recursive https://github.com/Zouch/
HelloGL.git • Télécharger tout et on voit ce qui compile à la
pause
8
Warm up … • Est-ce que vous pouvez définir, rapidement
– Un ordinateur – L’informatique graphique – Le rendu temps réel – Le pipeline de rendu (OpenGL) – Un shader – L’équation du rendu
9
Equation du rendu
12
L
i
(x,!o
) = L
o
(vis(x,wo
),�!
o
)
L
o
(x,!
o
) = E(x,!
o
) +
R⌦ L
i
(x,!
i
)⇢(x,!
o
,!
i
)cos dn,!i
d!
i
cosx = max(cosx, 0)
Rendu temps réel • Deux grandes famille en informatique graphique • Rendu hors ligne → pour les films • Rendu temps réel → pour l'interaction
• Objectif commun : calculer des images • Pas le même budget temps • Approches qui peuvent être très différentes
13
Simplification de l’équation du rendu • Intégrale vers somme • Prendre en compte uniquement l’éclairage direct
– Echantillonner les directions de lumière et non pas tout l’environnement
– Supprime la récursivité dans l’équation – Ajout d’un terme d’ambiant A pour compenser
• Détermine surface visible par projection/rasterization
14
L
o
(x,w
o
) =
Pk
(E
Lk⇢(x,!o
, l
k
)cos
dn, l
k
) +A
GPU
Pipeline graphique • Découpage en partie logique • Application : CPU
– Gestion entrée sortie
• Géométrie : transformation 3D • Rasterization : dessin par pixel
15
Partie Application • C'est la partie la plus contrôlable
– Donne la scène a afficher – Lecture sur stockage de masse, préparation des
données, images, textures ... – Traite les entrées utilisateurs – Généralement sur CPU
16
Pipeline graphique 3D 1/2 • Objectif : calculer une image
• Entrée, une scène 3D – Donnée 3D : définitions d'objets avec leur matériau – Lumières, caméras, environnement – Animations – Graphe de scène : lien entre les différents éléments de la
scène • Traitement de ces données pour l'affichage
– Calcul de la couleur de chaque pixel • Sortie
– Une image ou une suite d'images (film, animation)
17
Pipeline graphique 3D 2/2 • Entrée : Un triangle
– Vertex shader : effectue la projection – Rasterisation : forme 2d vers ensemble de fragment – Fragment shader : calcul la couleur d’un fragment
• Sortie : écriture dans le Framebuffer (écran)
18
Vertex shader • Travail au niveau des vertex
– Transformations géométriques – Éventuellement éclairage – Calcul de données au vertex
• Sortie en Normalized device coordinates • Les vertex sont ensuite assemblés en primitives
(triangles/quads) • Pour un pixel d'un triangle, les données
calculées pour chacun des trois vertex seront interpolées
20
Tesselation shader • Sur les cartes de dernière génération
– Permets de fabriquer (pleins) de nouveau triangles avec la carte graphique
– Prend un patch (un triangle, ou autre ensemble de points)
– Fabrique un ensemble de triangles ou de quads
21
Geometry shader • Permet la transformation et la création de
géométrie – Calcul des normales par face – Rendu fil de fer – Construction de volume d'ombre
• Moins adapté à la création massive de géométrie que le tesselation shader
22
Clipping et rasterisation • Processus hardware et non contrôlable • En entrée une primitive à afficher • En sortie une liste de fragment
23
Fragment shader • Calcule la couleur d'un fragment
– Entrée : coordonnée écran + données interpolées + données spécifiques
– Sortie : « couleur » du fragment
24
Les dernières étapes : écriture dans le framebuffer
• Plusieurs fragment calculer pour un pixel
• Comment combiner ces fragments
25
Exercice
• Soit un triangle en 2D – écrire le pseudo code de la fonction qui rempli les
pixels compris dans ce triangle avec une couleur constante (rasterisation)
• 1: déterminer les entrées/sorties • 2: spécifier la fonction • 3: proposer un model de solution • 4: écrire le pseudo-code
26
Architecture GPU • Processeur massivement parallèle • SIMD • Pleins de core (ou cœurs) qui effectue le même
programme sur des données différentes
• Adaptée aux calcul d'image – Un même calcul par point 3D – Un même calcul par pixel
27
Triangle setup • Calcul de différences (dfdx) utilisée pour
l'interpolation • Pour chaque valeur à interpoler • Le calcul devient simplement une addition • A voir pour la correction de perspective
29
Triangle traversal • Chaque pixel avec son centre couvert par le
triangle génère un fragment (a.k.a scan conversion)
• Génère aussi les valeurs interpolées • C'est un processus fixe, seule l'interpolation peut
être plus ou moins contrôlée avec certaines options.
30
Pixel shading • Calcul par pixel • Programmable par un shader • Le calcul pour un pixel se fait sur un core • Accède aux textures ...
31
Merge • Création d'un tableau de couleur (color buffer) • Un tableau rectangulaire de couleur • Une couleur : triplet ou quadruplet de float, int,
char ou autre • Cette étape n'est pas programmable • Mais configurable • Résout la visibilité
– Z-buffer (a.k.a depth-buffer)
• Fait aussi – alpha tests, blending, raster op, stencil, CROP ...
32
Framebuffer object • On peut aussi écrire dans un tableau qui n'est
pas directement affiché • Soit pour les problème de scintillement (v-sync) • Soit pour utiliser un rendu comme une texture
(reflexions …) • Soit pour faire du calcul qui n'a rien a voir avec
les images (GPGPU)
33
Exercice • Soit une valeur définie en trois points d'un
triangle, et uv les coordonnées barycentrique d'un point sur ce triangle – Comment calculer la valeur interpolée pour le point uv
sur le triangle
34
Communication avec le GPU • API dédiée • OpenGL
– Version 1.1 en 1997 – Version 4.0 en 2010 – Version 4.5 actuelle
• DirectX – Version 1 en 1995 – Version 5 (avec Direct 3D) en 1997 – Version 11 en 2009 – Version 12 actuelle
36
API OpenGL • Appel de commande driver (en C)
– glGenVertexArrays(1,&vertexArrayObject);
• préfixé par GL, postfixé par le type d’argument – void%glUniform4f(GLint%location,%%GLfloat%v0,%%GLfloat%v1,%%GLfloat%v2,%%GLfloat%v3);%
• Va provoquer l'exécution d'une commande sur le GPU
• Documentation à prendre en main – www.opengl.org – Dans la spécifications, les gl GL GL_ sont omis (mais pas
dans votre code)
37
OpenGL et machine à état • OpenGL fonctionne comme une machine à état
– Ce qui est activé reste actif – Activer un shader – Activer un objet 3D
• Un objet GL est un identifiant côté CPU
• Toujours vérifier les erreurs GL – Elles restent dans la piles d’erreurs sinon ;)
38
Hello world openGL • Initialisation
– Donnée 3D • Création de vertex array object (VAO) et de buffer
object VBOs – Programme d’affichage
• Création d’un shader program • A chaque dessin
– Activation du shader – Drawcall pour le VAO
40
Communication avec le GPU : les shaders • Un shader est un programme par exemple en
glsl • Il est compiler par le « GPU »
– Il peut aussi avoir des erreurs de compilation – À la volée (au lancement de votre programme) – Rechargement possible en cours d'execution
41
Exemple de shader • Vertex Shader
42
#version 150 in vec3 position; void main() { gl_Position = vec4(position, 1.0); }
Exemple de shader • Fragment Shader
43
#version 150 //in vec2 gl_FragCoord; out vec4 colorOut; void main() { colorOut = vec4(1,0,0,1); }
Compilation d'un shader • Pour le GPU il y a deux entités
– Les shaders objects : un main par partie programmable du pipeline
– Le shader program : il lie plusieurs shaders objects en un état du pipeline dans son ensemble
• Une fois les shaders objects compilés, puis liés en un shader program, le shader peut être activé (bind)
• C'est lui qui sera exécuté lors du dessin d'un objet 3D par le GPU
44
Langage glsl • Plus de détail dans la specs ;) • Type de bases :
– !int!float!…!– !vec2!vec3!vec4,!mat2!mat3!mat4!
• Fonctions prédéfinies – min,!max,!smoothstep,!dot,!cross,!normalize!…
• Un void!main() par étape du pipeline • Des variables uniform, obtenue de l’application,
constante pour un drawcall • Des variables in interpolées à partir de l’étage
précédent (ou directement de l’application) • Des variables out envoyé à l’étage suivant
45
Représentation d’objet 3D • Pour le rendu, ce qui est important c'est ce qu'on
voit • La surface des objets et leur apparence • En informatique, soit définition fonctionnelle/
paramétrique, soit définition discrétisée • Discrétisation : approximé une surface « lisse »
par un ensemble de morceaux de plan → triangles
47
Un objet 3D • Ensemble de triangles
– Un triangle : trois points dans l'espace
• Une apparence – Couleur – Variation de couleurs sur l'objet – Texture (image) plaquée sur l'objet
• Paramétrisation, uv par triangle
48
Liste de sommets partagés • Une liste de vertex : vertices_!
– Un vertex : vec3!position_!;!vec3!normal_!;!vec3!texcoord_!
• Une liste d'indice triangles_ (triplet) – Pour trois indice de triangles_ correspond trois
vertex de vertices_!– Cela donne un triangle de l'objet
• Le triangle i d'un objet est donc – vertices_[triangles_[i][0]]!– vertices_[triangles_[i][1]]!– vertices_[triangles_[i][2]]!
49
Donnée 3D sur le GPU • Envoie des données 3D vers le GPU • Un objet GPU (Vertex Array Object) • Des données (Buffer Object)
– Non structurées lors de l’envoie (un void *) – Structure donnée par glVertexAttribPointeur
• Un tableau d’indice (Element Buffer Object)
50
Donnée 3D sur le GPU
51
glGenVertexArrays(1,%&vertexArrayObject_);%%%glGenBuffers(2,%vertexBufferObjects_);%%%glBindBuffer(GL_ARRAY_BUFFER,%vertexBufferObjects_[VBO_VERTICES]);%glBufferData(GL_ARRAY_BUFFER,%%
% % %nbVertices_%*%sizeof(Vertex),%% % %&(vertices_[0]),%GL_STATIC_DRAW);%%
//%…%glVertexAttribPointer(index,%size,%type,%normalized,%stride,%pointer);%glEnableVertexAttribArray(index);%%//%…%glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,%vertexBufferObjects_[VBO_INDICES]);%glBufferData(GL_ELEMENT_ARRAY_BUFFER,%%
% % %3*nbTriangles_*sizeof(int),%&(triangles_[0]),%GL_STATIC_DRAW);%%%
Amélioration possibles • Pour le calcul géométrique
– Structure en demi-arrêtes
• Pour utiliser moins de mémoire – Triangles strips, triangles fans
52
Exercice • Soit un objet 3D
– Discrétisé par 1M de triangles – En moyenne les vertex ont une valence de 6
• Calculer l'occupation mémoire si on stocke les triangles indépendamment
• Même question avec une liste sommets partagés
• En utilisant un super algorithme de strippification automatique, supposons que l'on arrive à décomposer le modèle en 1000 strips – Quel est le gain (approximatif) que l'on obtient
53
Exercice • Soit un objet 3D
– Discrétisé par 1M de triangles – En moyenne les vertex ont une valence de 6
• Calculer l'occupation mémoire si on stocke les triangles indépendamment – 1M x 3 x sizeof(vertex) = 1M x 3 x 36 = 108 000 000 octets = 103 Mo
• Même question avec une liste de faces indexés – 1M/6x3 x sizeof(vertex) + 1M x 3 x sizeof(int) – = 1M/6x3 x 36 + 1M x 3 x 4 = 30 000 000 octets = 28,6 Mo
• On utilisant un super algorithme de strippification automatique, supposons que l'on arrive à décomposer le modèle en 1000 strips – Quel est le gain (approximatif) que l'on obtient – 1M/1000 = 1000 triangles par strips – 1 strip de 1000 triangles : 2 x sizeof(int) + 1000 x sizeof(int) = 4008 octets – 1000 strips : 4008 000 octets – En tout 4 008 000 + 1M/6x3 x 36 = 22 008 000 octets – Gain 8Mo soit 26%
54
Espace d'existence d'un objet 3D • Espace objet (model space) • Espace monde (world space) • Espace vue (view space)
– Caméra à l'origine – Regarde en -z (par convention) – Haut en y – Droite en x
• Passage d'un espace à l'autre : changement d'espace vectoriel.
55
Chaîne de transformations 3D → 2D • Espace monde vers l'espace de vue
• Projection • Vers l'espace fenêtre le cube unitaire
– Clipping • Coupe ce qui dépasse de l'écran
– Screen mapping • Donne les coordonnées écran (fenêtre)
56
Rappel espace vectoriel • Transformations linéaires représenté par une
matrice – – a scalaire –
• Les transformations linéaires de – Mise à l’échelle – Rotation – Cisaillement
57
f(ax) = af(x)Mv
f(x+ y) = f(x) + f(y)
Et l’origine ? • Espace vectoriel -> représente des vecteurs • Pour des points il faut aussi une origine
– Espace affine
• Les vecteurs sont définis indépendamment de l’origine
• Les points sont définis relativement à l’origine – P = (O + v)
• Un vecteur est la différence entre deux points.
59
Changement de repère • repère défini par trois vecteurs
• Si exprimé dans P :
• Alors passage de Q vers P
• La translation n’est pas une transformation linéaire
60
BQ!P
=⇥Q
x
Qy
Qz
⇤
Mv +Qo
Po
= (0, 0, 0)
P : Po
, Px
, Py
, Pz
! Q : Qo
, Qx
, Qy
, Qz
Pz = (0, 0, 1)Px
= (1, 0, 0) Py = (0, 1, 0)
R3
Rotation centré autour de l’origine • Autour de l’axe x • Autour de l’axe y • Autour de l’axe z • Centré autour d’un autre point ? • Autour d’un axe quelconque ?
61
M =
2
41 0 0
0 cos � sin
0 sin cos
3
5
Coordonnées homogènes • Représenter aussi les translations par des
transformations linéaires • Utilisation d’un espace homogène : ajout d’une
4eme coordonnées • V = x y z w • position 3D = x/w y/w z/w, w!=0
– x y z 1 et 2x 2y 2z 2 représente le même point – On divise par w pour avoir la position 3D
• vecteur 3D w = 0 – Différence entre deux points -> un vecteur – Marche avec w = 1 – 1 = 0
63
Projection • Transformation qui diminue la dimension
– 3D -> 2D – Homogène 3D -> homogène 2D (permet de conserver
l’information en z, tout en projetant) • Volume de vue vers cube unitaire, dans le
normalized device coordinates (NDC)
• Projection orthogonale : x y z -> x’ y’ z’ – x dans volume de vue : entre p et q par exemple – x’ dans cube unitaire -1 1 – Appliquer la transformation (x-p)/(q-p) * (1 - -1) – 1; – Pas d’effet de perspective
65
Projection perspective • Modèle de caméra pinhole • Volume de vue pyramidale (frustum) • Transformation en cube produit les effet de
perspective
66
Exercices • Exercice :
– Appliquer la matrice M à un point et un vecteur
• Ecrire la forme générale des matrices de projections orthographique et perspective.
67
2
664R t
0 0 0 1
3
775
Clipping • Une primitive peut soit
– Être incluse dans le cube unitaire (pass) – Sortir entièrement du cube unitaire (discard) – Couper le cube unitaire (clip)
• Pour être efficace lors de la rasterization, on recoupe les primitive clipper en amont (enfin c'est le GPU qui le fait)
• Le clipping est facile car les coordonnées sont dans le cube unitaire
68
Coordonnées fenêtre (encore 3D) • X, y, z dans l'espace de la fenêtre • Le z va servir lors de la rasterization pour savoir
quel fragment est le plus proche
69
Coordonnées entières et flottantes • Plusieurs convention • Mais aujourd'hui, classiquement, les pixels sont
centrés en .5 • Un pixel (0,0) à pour coordonnée flottant (0.5,
0.5) • Un intervalle [0,9] de pixel couvre les
coordonnée flottantes [0.0, 10.0[
70