Quick viewing(Text Mode)

Développement D'une Plate-Forme De Simulation De Scènes 3D Liées Au

Développement D'une Plate-Forme De Simulation De Scènes 3D Liées Au

N° d’ORDRE : 01/2010-D/IN

République Algérienne Démocratique et Populaire Ministère de l’Enseignement Supérieur et de la Recherche Scientifique Université des Sciences et de la Technologie « Houari Boumediene » Faculté d’Electronique et d’Informatique

THESE

Présentée pour l’obtention du diplôme de DOCTORAT

En : INFORMATIQUE

Spécialité : Informatique

Par : AMARA Yacine

Sujet

DEVELOPPEMENT D’UNE PLATE-FORME DE

SIMULATION DE SCENES 3D LIEES AU SOL ET SON

OCCUPATION

Soutenu le 16/02/2010, devant le jury composé de :

Mme-. H. DRIAS, Professeur, USTHB. Président Mr-. S. LARABI, Professeur, USTHB. Directeur de Thèse Mme-. A. BELHADJ-AISSA, Professeur, USTHB. Examinateur Mr-. S. AIT-AOUDIA, Maître de conférences A, ESI. Examinateur Mr- M. BELHOCINE, Maître de recherche, CRDTA. Examinateur Mr-. T. CHETTIBI, Maître de conférences A, EMP. Examinateur

A mes parents A ma femme A mes enfants Remerciements

Mes plus sincères remerciements vont pour Mme. Amina SERIR et M. Slimane LARABI pour m’avoir encadré dans mon travail de thèse. Je les remercie également pour la confiance et la liberté qu'ils mon accordées durant ces années de thèse. Soyez assurés, Madame et Monsieur, de toute mon estime et mon profond respect.

Que les membres de jury trouvent toute ma gratitude pour avoir accepté de juger mon travail, qu’ils trouvent ici l’expression de ma profonde reconnaissance.

J’adresse toute ma gratitude à M. Xavier MARSAULT pour sa disponibilité et pour ses précieux conseils qui m’ont guidé au cours de ces années de thèse. Veuillez trouver ici l’expression de mes remerciements les plus sincères ainsi que la marque de mon profond respect. Je tiens à vous remercier pour tout ce que vous avez fait pour moi pendant mes deux séjours au sein de l’équipe MAP-ARIA. Vous m’avez tout d’abord enseigné les techniques de rendu sur GPU, puis grâce au longues discussions que nous avons eues pendant presque six mois, nous avons pu dégager une démarche qui nous a permis d’aboutir à des résultats satisfaisants. Je tiens à vous témoigner toute ma reconnaissance pour le travail que nous avons réalisé en commun. Je vous remercie aussi de m’avoir permis de travailler sur les données de la zone de la Haute Savoie. J’avoue que sans ces données, je n’aurais jamais pu avancer dans mon travail de thèse. Je n’oublierai pas les encouragements de tous les membres de l’équipe ARIA et à leur tête le chef du laboratoire M. Hervé LEQUAY.

Je remercie aussi M. Sylvain LEFEBVRE pour m’avoir fait profiter de ces précieuses explications, orientations et conseils en matière de techniques de programmation sur GPU. Que les membres de l’équipe Evasion de l’INRIA de Grenoble, particulièrement M. Eric BRUNETON et Mme. Marie-Paule CANI, trouvent ici mes sincères remerciements pour m’avoir accordé le privilège de travailler sur leur moteur de rendu PROLAND.

J’exprime ma reconnaissance à M. LEHTIHET et Mme. SADEG pour le temps passé à corriger mes chapitres et à améliorer la qualité de rédaction de ma thèse.

Que le commandement de l’Ecole Militaire Polytechnique trouve ici toute ma reconnaissance de m’avoir permis d’effectuer des séjours à l’étranger. Tous mes remerciements vont aussi à mes collègues de l’UERI et du centre de calcul.

Je n’oublierais pas le soutient moral de ma famille et particulièrement mes parents, mon épouse Malika et mes deux enfants Sarah Lyna et Mohamed Ramine. Je les remercie d’avoir supporté mes sauts d’humeur pendant toute cette longue période. Qu’ils trouvent ici toute ma gratitude et reconnaissance. Table des Matières

Table des Matières

Introduction générale …………………………………………………………………………...………….. 1

Chapitre 1 : Techniques de simplification des terrains

1.1 Triangulation à adaptivité limitée……………………………………………………………...………... 4 1.1.1 Multiples niveaux de détail statiques………………………………………………..……… 4 1.1.2 Grilles imbriquée régulières ( Nested regular grids )……………………………..……..…. 6 1.1.3 Discussions……………………………………………………………….…………………... 7 1.2 Triangulation à résolution dynamique………………………………………………..………………… 7 1.2.1 Triangulation en arbre quaternaire………………………………………..………………... 7 1.2.1.1 Méthode « Restricted quadtrees »……………………………………………… 8 1.2.1.2 Méthode « Quadtree surface maps »…………………………………………... 9 1.2.1.3 Méthode « Continuous LOD quadtree »…………………………………...... 12 1.2.1.4 Méthode « Restricted quadtree triangulation »………………………………... 14 1.2.1.5 Méthode « 4-8 meshes »…………………………………….…………………... 16 1.2.1.6 Méthode « Irregular quadtree hierarchy »...... 16 1.2.2 Triangulation en arbre binaire………………………………………….……………………. 18 1.2.2.1 Méthode « Real-time optimally adapting meshes »…………………………… 18 1.2.2.2 Méthode « Right-triangulated irregular networks »……………………………. 20 1.2.2.3 Méthode « Right-triangular bin-tree »………………………….……………….. 22 1.2.3 Discussions……………………………………………………………….…………………… 23 1.3 Triangulations par cluster……………………………………………………………………………….. 23 1.3.1 Blocs de carreaux « Tiled blocks »………………………………..………………………... 24 1.3.2 Arbres binaires mis en cache « Cached Triangle bin-trees »………….………………… 25 1.3.3 Combinaison des triangulations régulières et irrégulières……………..………………… 25 1.4 Métriques d’erreurs…………………………………………………………………...…………………. 25 1.4.1 Erreur d’approximation dans l’espace objet………………………..……………………… 25 1.4.2 Erreur d’approximation dans l’espace image……………………..……………………….. 28 1.4.3 Discussions…………………………………………………………….……………………… 30 1.5 Conclusion………………………………………………………………………………………………… 30

Chapitre 2 : Modèles d’habillage

2.1 Placage de texture standard……………………………………………………………………………. 32 Table des Matières

2.1.1 Principe……………………………………………………………….……………………….. 32 2.1.2 Paramétrisation planaire………………………………………………..…………………… 33 2.1.2.1 Cas triviaux……………………………………………….……………………….. 33 2.1.2.2 Paramétrisation de surfaces quelconques…………….……………………….. 34 2.1.2.3 Mise à plat de surface à bordure unique…………………….……………...... 35 2.1.2.4 Atlas de texture………………………………………………….………………… 35 2.1.2.5 Paramétrisations contraintes………………………………….……………...... 36 2.1.3 Stockage des données de texture………………………………………..………………… 36 2.1.4 Accès aux données de texture…………………………………………..………………….. 37 2.1.5 Interpolation………………………………………………………………..………………….. 37 2.1.6 Limitations du placage de texture………………………………………..……………...... 38 2.1.6.1 Gaspillage de mémoire…………………………………………………………... 38 2.1.6.2 Interpolation et discontinuités……………………………………………………. 39 2.1.7 Extensions du placage de texture……………………………………..……………………. 39 2.1.7.1 Compression de texture…………………………………….………………...... 39 2.1.7.2 Textures Adaptatives……………………………………….…………………….. 40 2.2 Filtrage……………………………………………………………………………...……………………... 41 2.2.1 Origine du problème………………………………………………….………………………. 41 2.2.2 Sur-échantillonnage…………………………………………………..……………………… 42 2.2.3 Filtrage pour le placage de texture…………………………………..……………………... 43 2.2.3.1 Principe…………………………………………………….…………………...... 43 2.2.3.2 Algorithme de MIP-mapping…………………………….……………………….. 43 2.2.4 Note sur la qualité de filtrage………………………………………..…………………...... 45 2.3 Modèles d’habillage pour les applications interactives………………………...…………………….. 45 2.3.1 Cartes accélératrices………………………………………………..……………………….. 45 2.3.2 Géométrie et applications interactive……………………………..………………………... 47 2.4 Chargement progressif de textures…………………………………………...……………………….. 48 2.4.1 Organisation des données de texture…………………………..………………………….. 49 2.4.2 Vue d’ensemble…………………………………………………………………………...... 50 2.4.3 Carte de chargement de texture………………………………….……………….………... 51 2.4.3.1 Calcul d'un niveau de la carte de chargement……………………….………... 52 2.4.3.2 Elimination des faces cachées………………………………………….………. 53 2.4.3.3 Calcul du niveau de détail……………………………………………….………. 53 2.4.3.4 Prise en compte de l’occlusion………………………………………………….. 54 2.4.3.5 Calcul de tous les niveaux d’une carte de chargement………………..……... 55 2.4.4 Génération des requêtes de chargement…………………………………………..……… 56 2.4.5 Cache de texture…………………………………………………………………….……….. 56 2.4.6 Producteur de texture…………………………………………………………….………….. 57 2.5 Conclusion………………………………………………………………………………………………… 57

Table des Matières

Chapitre 3 : Amplification à la volée de très grands terrains par des objets naturels

3.1 Vue d’ensemble…………………………………………………………………………………………... 60 3.2 Adaptation de la carte de chargement………………………………………...………………………. 61 3.2.1 Estimation du niveau de détail……………………………………….……………………… 63 3.2.2 Elimination de la géométrie en dehors du volume de vision…………..………………… 64 3.2.3 Prise en compte de l’occlusion………………………………………..…………………….. 64 3.2.4 Calcul pseudo aléatoire des motifs génériques………………………..………………….. 65 3.2.5 Rapatriement de la texture TLM………………………….………………….. 65 3.2.6 Calcul sous GPU de la liste des textures utiles………………………..………………….. 65 3.2.6.1 Exemple d’une texture TLM………………………………….………………….. 65 3.2.6.2 Algorithme d’analyse de la TLM………………………………………………… 67 3.2.6.3 Compactage des valeurs non NULL……………………….…………………… 68 3.2.7 Organisation des textures sur disque…………………………………..………………….. 69 3.2.8 Cache GPU………………………………………………………….………………………… 70 3.3 Rendu du terrain………………………………………………………………………………………….. 70 3.4 Sélection, instanciation & regroupement des objets du sursol…………………...………………… 72 3.4.1 Modèles de graines…………………………………………………………..…………...... 72 3.4.2 Motifs génériques…………………………………………………………..………………… 73 3.4.3 Pré-calcul de la couverture du sol……………………………………………………...... 74 3.4.4 Sélection, instanciation & regroupement sous GPU………………………………...... 74 3.4.4.1 Sélections et instanciation des graines………………………………………… 75 3.4.4.2 Regroupement par type de graine………………………………………………. 77 3.5 Rendu des objets du sursol………………………………………………………………..……………. 77 3.5.1 Rendu des arbres en temps réel………………………………………………..………….. 78 3.5.2 Gestion de la transition (texture du sol / plantes)……………………………..…………... 79 3.6 Conclusion………………………………………………………………………………………………… 80

Chapitre 4 : Résultats et discussion

4.1 Prétraitement des données du terrain…………………………………………………………………. 81 4.1.1 Découpage des dalles……………………………………………………..………………… 82 4.1.2 Construction de la pyramide des tiles……………………………………..……………….. 83 4.1.3 Ajout des bordures………………………………………………………………..………….. 83 4.1.4 Compression des textures…………………………………………………….…………….. 84 4.1.5 Codage des textures LCC………………………………………………………..………….. 85 4.2 Modules « rendu et amplification du terrain »……………………………………………...……...... 86 4.2.1 Module « Carte de chargement »……………………………………………….………….. 87 4.2.2 Module « Habillage du terrain »…………………………………………………..………… 89 4.2.3 Module « Sélection des graines »………………………………………………..…………. 92 4.2.4 Module « Rendu des arbres »……………………………………………………..………... 96 Table des Matières

4.3 Evaluation des performances…………………………………………………………………………… 98 4.3.1 Evaluation qualitative………………………………………………………………..……….. 98 4.3.2 Evaluation quantitative………………………………………………………….……………. 100 4.4 Modèle de graines : cas de la planète entière………………………………………………………… 101 4.4.1 ORK (Opengl Rendering Kernel)…………………………………………………..……….. 101 4.4.2 PROLAND (PROcedural LANDscape)…………………………………………………….. 101 4.4.2.1 Représentation du terrain………………………………………………………... 102 4.4.2.2 Producteurs de données…………………………………………………………. 102 4.4.3 Sélection/Instanciation sous Proland………………………………………………………. 103 4.4.3.1 Sélection, groupement et rendu par motif……………………………………… 104 4.4.3.2 Sélection et rendu par terrain……………………………………………………. 104 4.4.3.3 Sélection et rendu par tile………………………………………………………... 104 4.4.3.4 Sélection statique…………………………………………………………………. 105 4.4.4 Quelques résultats……………………………………………………………………………. 105 4.5 Conclusion………………………………………………………………………………………………… 107

Conclusions et perspectives ……………………………………………………………………………... 108 Annexe I Annexe II Bibliographie

Table des Figures

Table des Figures

1.1 Rendu en multi-résolution dans le système NPSNET [ FZP+93 ]…………………………………… 5 1.2 Geometry clipmap……………………………………………………………………………………….. 6 1.3 Triangulation adaptative basée sur les arbres quaternaires………………………………………... 8 1.4 (a) Subdivision en arbre quaternaire sans restriction. (b) subdivision avec restriction………….. 8 1.5 Fissures (ombrées en gris) résultant de la représentation polygonale quadrilatérale d’une surface subdivisée en arbre quaternaire avec restriction……………………………………………….. 9 1.6 Triangulation conforme d’une subdivision en arbre quaternaire avec restriction, tel que présentée par [VB87] ………………………………………………………………………………………... 10 1.7 Triangulation conforme améliorée issue d’une subdivision en arbre quaternaire avec restriction, tel que présentée par [ SS92 ]………………………………………………………………….. 10 1.8 Approche ascendante : Nœuds-feuilles atomiques utilisés pour la construction, avec restriction, de l’arbre quaternaire…………………………………………………………………………… 10 1.9 (a) Les sommets du noeud racine (niveau 0), (b) les sommets non-persistants du niveau 1, (c) et ceux du niveau 2………………………………………………………………………………………….. 11 1.10 (a) Début de la triangulation d’un nœud dans le niveau i. Pas de sommets initialement sélectionnés dans le niveau i+1. (b) La sél ection d’un sommet dans le niveau i+2 force la subdivision et l’insertion de d’autres sommets dans les niveaux précédents…………………………. 12 1.11 (a) Triangulation initiale. Fusion des pairs de triangles le long des arêtes du bord (b) et le long de la diagonale (c)……………………………………………………………………………………… 13 1.12 (a-d) Relations de dépendances……………………………………………………………………... 13 1.13 (a-c) Traversée récursive de l’arbre pour générer un triangle strip ………………………………. 14 1.14 Hiérarchie implicite de l’arbre quaternaire et in dexation des points définis sur la grille régulière……………………………………………………………………………………………………….. 15 1.15 (a) RQT triangle strip. (b) le chemin hamiltonien du graphe dual………………………………… 15 1.16 Subdivision récursive en 4-8 triangle mesh …………………………………………………………. 16

1.17 (a) Un sommet v (en rouge) et son domaine de fusion M v (en blanc). (b) maillage triangulaire adaptatif obtenu après suppression du sommet et v et les sommets du domaine Mv……………….. 16 1.18 Subdivision récursive QuadTIN irrégulière………………………………………………………….. 17

1.19 (a) Le sommet le plus proche au point médian de l’arête diagonale e t,t’ est sélectionné pour faire une subdivision récursive. (b) seuls les sommets d’un domaine restreint sont considérés…… 17 1.20 Triangulation adaptative QuadTIN d’une distribution irrégulière de points d’élévation………… 18 1.21 Hiérarchie binaire construite par bissection de la plus longue arête des triangles isocèles…… 18 1.22 Opérations de subdivision et de fusion utilisées dans un algorithme de triangulation basé sur un arbre binaire de triangles………………………………………………………………………………... 19 1.23 Propagation des subdivisions forcées des triangles……………………………………………….. 19 1.24 Etiquetage binaire de la technique RTIN utilisant 0 pour les fis gauches et 1 pour les fils droits…………………………………………………………………………………………………………… 21 Table des Figures

1.25 Numérotation des triangles (les sommets de base constituent le repère de subdivision et de numérotation)………………………………………………………………………………………………… 22 1.26 (a) Quatre nœuds feuilles initiaux à fusionner. (b) les nœud s fusionnés avec les points supprimés (petits cercles creux)…………………………………………………………………………… 26 1.27 Le fusionnement des nœuds satisfaisant localement l’erreur d’approximation tolérée peut avoir comme conséquence intolérable un cumul d’erreurs à l’égard du résultat final [PG07]………. 26 1.28 (a) Métrique d’erreur calculée pour les sommets sélectionnés…………………………………... 27 1.29 L’épaisseur du volume englobant détermine l’erreur d’approximation géométrique dans l’espace objet…………………………………………………………………………………………………. 28

1.30 Distance verticale εv entre le sommet de base v candidat à être supprimé et son interpolation linéaire v ………………………………………………………………………………………………………. 29

2.1 Placage de texture………………………………………………………………………………………. 33 2.2 Représentation d’un terrain par une carte de hauteur………………………………………………. 34 2.3 Mise à plat de maillage triangulaire avec une bordure unique……………………………………... 35 2.4 Atlas de texture………………………………………………………………………………………….. 36 2.5 Exemple d'interpolation linéaire……………………………………………………………………….. 38 2.6 Compression des vides………………………………………………………………………………… 40 2.7 Effets d' aliasing …………………………………………………………………………………………. 41 2.8 Les sont influencés par un morceau de la surface…………………………………………... 42 2.9 Pyramide de MIP-mapping…………………………………………………………………………….. 44 2.10 Chaînes des traitements ( pipeline ) d’un processeur graphique (version simplifiée)…………… 46 2.11 (a) Structure pyramidale de la texture. (b) L’architecture gère uniquement les derniers niveaux [LDN04] …………………………………………………………………………………………….. 49 2.12 Organisation de l’architecture [Lef05] ……………………………………………………………….. 50 2.13 Carte de chargement………………………………………………………………………………….. 51 2.14 Carte de chargement pour un triangle………………………………………………………………. 52 2.15 Elimination des faces situées en dehors du rectangle de l'écran………………………………... 53 2.16 Exemple de texture LOD pour k = 3 niveaux gérés par l’architecture…………………………… 54

3.1 Vue d’ensemble sur notre architecture……………………………………………………………….. 60 3.2 Module 1 : Calcul de la liste des textures utiles à l’habillage du terrain au frame courant………. 61 3.3 Texture TLM mappée sur l’espace du terrain………………………………………………………... 62 3.4 Calcul du niveau de détail……………………………………………………………………………… 63 3.5 Calcul de la liste des indices de textures utiles au point de vue courant…………………………. 66 3.6 Exécution parallèle de l’algorithme d’analyse de la TLM …………………………………………… 68 3.7 Exemple illustratif des différentes étapes utilisées pour compacter, sur GPU, les éléments non NULL d’une liste………………………………………………………………………………………...... 68 3.8 Module2 : phase de rendu du terrain………………………………………………………………….. 71 3.9 Génération de graines à partir des motifs de points et de la couverture du sol………………….. 73 3.10 Motifs de points ( patterns ) géo-spécifiquement distribués sur le terrain………………………… 74

Table des Figures

3.11 Module 3 : sélection/instanciation des graines sous GPU (PASS 3). Module 4 : rendu final des plantes (PASS 4)……………………………………………………………………………………….. 75 3.12 Texture(s) de sélection contenant les graines générées………………………………………….. 76 3.13 Regroupement par type de plante des données de la sélection dans une texture d'indirection codant les positions réelles dans la texture de sélection……………………………………………….. 77 3.14 Prise en compte de la transition……………………………………………………………………... 79

4.1 Exemple d’une grille de découpage 4x4 tiles ………………………………………………………... 82 4.2 Pyramide des textures du sol indexées d’une manière séquentielle……………………………… 83 4.3 Une texture du sol avec 4 bordures de chaque coté mip-mappée sur deux niveaux…………… 84 4.4 Schéma de codage du quadtree LCC (A, R, N sont des indices de matières)…………………... 85 4.5 Plusieurs représentations du terrain pour un même point de vue…………………………………. 86 4.6 Transfert de la texture TLM depuis l’espace de rendu vers l’espace CUDA ……………………... 89 4.7 Habillage du terrain par les textures utiles…………………………………………………………… 91 4.8 Etapes d’exécution de l’algorithme de David Roger [RAH07]……………………………………… 95 4.9 Regroupement des propriétés par type d’essences………………………………………………… 96 4.10 Atlas de textures des trois modèles d’arbres utilisés pour amplifier la zone de Megève (Haute Savoie)………………………………………………………………………………………………………… 97 4.11 Terrain texturé par notre plate-forme (avec la permission de la RGD73-74)……………………. 98 4.12 Terrain t exturé et amplifié par 3 types d’arbres à différentes résolutions (avec la permission de la RGD73-74)……………………………………………………………………………………………... 99 4.13 Terrains texturés avec prise en compte des effets atmosphériques……………………………... 102 4.14 Architecture et fonctionnement des producteurs de données…………………………………….. 103 4.15 Temps d'exécutions (ms) de chaque phase en fonction de la densité des points par motif…… 105 4.16 Quelques prises de vue sur de différents endroits de la terre amplifiés par des arbres……….. 106

A1.1 Architecture d’une carte graphique 3D…………………………………………………………….... ii A1.2 Structure des GPU des cartes graphiques de la première génération…………………………... iii A1.3 Structure des GPU des cartes graphiques de la deuxième génération…………………………. iv A1.4 Aperçu de la puissance calculatoire des GPU et CPU……………………………………………. v A1.5 Architecture du pipeline fixe………………………………………………………………………….. vi A1.6 Architecture du pipeline programmable……………………………………………………………... vi A1.7 Fonctionnement du pipeline programmable………………………………………………………… viii A1.8 Bump-Mapping…………………………………………………………………………………………. ix A1.9 Cube-Mapping…………………………………………………………………………………………. ix A2.1 La pile logicielle de CUDA……………………………………………………………………………. x A2.2 Les opérations mémoire Gather et Scatter…………………………………………………………. xi A2.3 La mémoire partagée rapproche les données des UALs…………………………………………. xi A2.4 Groupage des threads………………………………………………………………………………… xii

Table des Abréviations

Table des Abréviations

MNT : Modèle Numérique de Terrain LCC : Land Cover Classification LOD : Level Of Detail API : Application Programming Interface GPU : CPU : Central Processing Unit OpenGL : Open GLSL : OpenGL Language CUDA : Compute Unified Device Architecture VS : Vertex GS : Geometry Shader FS : Fragment Shader

Introduction Générale

Introduction générale

Introduction générale

L’homme s’est toujours intéressé à la schématisation de son environnement. Les explorateurs et les voyageurs ont souvent utilisé ou dessiné des cartes leur permettant de se repérer. Cela a donné lieu à de multiples échanges d’ordre commercial, culturel et autres, contribuant ainsi à accélérer le rythme de l’évolution de l’humanité. Avec l’avènement des moyens technologiques, l’intérêt de dessiner la terre demeure toujours le même mais les moyens d’y parvenir sont en perpétuelle évolution. Désormais, il est possible de mesurer et d’observer la terre depuis l’espace.

Les moyens actuels d’acquisition embarqués sur les avions et les satellites fournissent des données numériques permettant de représenter la terre, avec précision, sur divers supports informatiques. Ces données comprennent, essentiellement, des mesures altimétriques et des orthophotographies numériques. Les données altimétriques sont relatives au relief de la terre représenté généralement par une grille d’altitudes, à partir de laquelle on extrait des modèles numériques de terrain ou MNT. Les orthophotographies numériques sont des images, prises d’une manière orthogonale, qui reflètent l’occupation du sol. Le couplage de ces deux types de données par des algorithmes adéquats a permis la visualisation de la terre en multi-résolutions. Donc, loin des cartes des navigateurs, l’homme actuel s’est libéré de la terre pour la représenter sur un écran d’ordinateur, élargissant ainsi, sa capacité d’exploration et son confort quotidien. Dès lors, le nombre d’applications ayant comme théâtre un terrain a fortement augmenté. Ces applications couvrent un spectre très large allant de simples jeux jusqu’aux systèmes d’aides à la décision très sophistiqués.

De plus, le besoin en terme de résolution, de réalisme et d’interactivité se fait sentir, de jours en jours, par des utilisateurs disposant d’ordinateurs usuels. Face à cette demande croissante, des algorithmes performants de modélisation et de visualisation de terrains ont été élaborés. Ils tentent de simplifier les données acquises afin de les visualiser en 3D tout en préservant un taux de rafraîchissement élevé permettant de greffer d’autres fonctionnalités aux programmes. C’est dans cette perspective que notre sujet de thèse a été proposé. Il s’agit d’élaborer une plate-forme de visualisation interactive de larges terrains tout en faisant surgir, dès que nécessaire, les éléments naturels codés implicitement dans les orthophotographies. Ainsi, les utilisateurs peuvent bénéficier de scènes encore plus riches en détails, et par conséquent plus réalistes.

Les scènes naturelles sont caractérisées par leur variété topographique, leurs vastes étendues et la diversité des éléments qui les composent. Leur modélisation requiert le

- 1 - Introduction générale traitement d’une masse importante de données avec des ressources ayant souvent des capacités limitées. Ainsi, cela nécessitera l’élaboration d’un ensemble de structures de données efficaces rendant l’exécution des algorithmes proposés optimale. Il serait totalement inconcevable de faire attendre l’utilisateur plusieurs minutes, ni même quelques secondes entre deux images successives. Sachant que le nombre d’images produites doit être suffisamment élevé (au moins 25 images par seconde, et c'est un minimum actuellement) pour qu’il n’y ait pas de saccades. Toutefois, le réalisme des scènes affichées doit être aussi suffisant pour immerger l’utilisateur dans ce nouvel environnement virtuel.

Lorsque nous travaillons sur des données réelles, nous ne disposons pas généralement d’informations suffisamment précises pour afficher des scènes détaillées. Il est donc nécessaire d’y ajouter du détail, crédible si possible, de façon à augmenter leur réalisme tout en limitant l’impact sur la consommation de mémoire. Nous parlerons alors d’amplification. Les détails ajoutés peuvent être de diverses natures: il peut s’agir d’objets, de textures, etc. Inversement, il nous arrive de manipuler des objets complexes (modélisés par un nombre important de polygones, i.e. les arbres). L’utilisation sans simplification de ces objets réduirait toute tentative visant à rendre notre plate-forme interactive. Donc, il est important de simplifier ces objets avant de les afficher, tout en limitant l’impact visuel de la simplification.

Par conséquent, il est indispensable d’adapter dynamiquement la résolution géométrique et texturale des objets de la scène (terrain + objets naturels du sursol) en fonction de la distance à l’observateur. Ainsi, nous pouvons aboutir à un compromis entre: capacité mémoire, réalisme et interactivité. Notons qu’avec l’arrivée des cartes graphiques programmables (dès 2003), les chercheurs ont tenté de personnaliser leurs traitements (effectués par le pipeline graphique) afin d’obtenir de meilleures performances et plus de réalisme. De la même manière, la plate-forme que nous avons proposée tente de déporter le maximum de traitements graphiques là où ils devraient être (sur le processeur graphique, GPU) et par conséquent, libérer le processeur central (CPU) pour qu’il ne s’occupe que des tâches non graphiques (gestion du réseau, des bases de données, des systèmes d’intelligence artificielle, etc.).

Cette thèse est organisée en quatre chapitres:

 Le premier chapitre, présente les différents algorithmes utilisés pour la simplification et la visualisation des terrains, dans lequel, nous nous limitons aux techniques de représentation dites en multi-résolutions. Une étude des différentes métriques d’erreurs utilisées par ces algorithmes est également présentée.

 Le second chapitre, expose les modèles d’habillages et plus spécifiquement celui du placage de textures. Les problèmes liés à ce modèle y sont présentés ainsi que les solutions proposées pour les résoudre. Ce chapitre comporte également les travaux

- 2 - Introduction générale

effectués dans le contexte de chargement progressif de textures et particulièrement ceux de Lefebvre et al . [LDN04]. Ces travaux constituent le point de départ de notre démarche de rendu et d’amplification.

 Le troisième chapitre, présente notre démarche. Elle est composée de quatre modules développés sous processeur graphique. Les deux premiers modules s’occupent du calcul de la liste des textures utiles au point de vue courant, et de l’affichage de la géométrie habillée de notre terrain. Les deux autres implémentent des mécanismes d’amplification et d’instanciation des objets naturels occupant le sol en s’appuyant sur une carte de couverture.

 Le dernier chapitre, récapitule quelques détails d’implémentation et des illustrations par des exemples issus des données numériques relatives à la zone montagneuse de la Haute-Savoie en France. Les résultats d’intégration de nos derniers modules (amplification et instanciation) dans un moteur de rendu de la planète (développé par l’équipe Evasion de l’INRIA Rhône Alpes) y sont également présentés.

- 3 -

Chapitre 1 Techniques de Simplification des Terrains

Chapitre 1 : Techniques de simplification des terrains

Chapitre 1 Techniques de simplification des terrains

Le domaine de la simplification et de la visualisation de gros maillages de données a connu un essor conséquent lors de la dernière décennie. De nombreux algorithmes résultent de ces années de recherche permettent de réaliser des simplifications de maillages puis ensuite de les visualiser ou de les stocker de manière efficace. Tout en nous appuyant sur l’étude réalisée par Pajarola et al. [PG07], nous allons essayer de faire le tour d’horizon des différents algorithmes utilisés pour la simplification et la visualisation des terrains. Nous commencerons en premier lieu par les méthodes de simplification, dites, à adaptivité limitée, qui tentent de représenter un terrain en un nombre fixe de niveaux de détail (Level-of-Details ou LOD). Ensuite, nous détaillerons les techniques de simplification exploitant des structures de données hiérarchiques permettant d’obtenir une représentation continue et en multi-résolution. Plus loin dans le chapitre, nous verrons les méthodes de triangulations par cluster et les différentes métriques d’erreurs utilisées pour quantifier la qualité de la simplification.

1.1 Triangulation à adaptivité limitée

Plusieurs systèmes de visualisation de terrains utilisent des techniques de simplification dont les résultats ne s’adaptent pas complètement à la surface initiale. Cependant, ces techniques sont simples à implémenter et facilitent les échanges avec les médias de stockages externes.

1.1.1 Multiples niveaux de détail statiques

Les premiers travaux réalisés dans ce domaine utilisent des approches basées sur des représentations fixes et en multi-résolutions des différentes parties composant la surface d’un terrain. Ces parties, typiquement des blocs carrés, sont calculées et stockées sur disque dans une phase de pré-traitement. Au moment de l’exécution, les approximations appropriées du maillage sont sélectionnées et assemblées en fonction des paramètres du point de vue courant. Le résultat de ces opérations est une surface composée de plusieurs blocs de différentes résolutions. Cela engendre, d’une part, des fissures entre ces blocs et d’autre part, l’apparition d’un effet de surgissement ( popping ) lorsque l’on effectue une transition entre les différents modèles d’un même bloc.

- 4 - Chapitre 1 : Techniques de simplification des terrains

Le système de visualisation militaire NPSNET [ FZP+93 ] décompose le terrain en un ensemble de blocs adjacents. Chacun de ces blocs est représenté en quatre niveaux de détail pré-calculés et stockés sur disque. Une grille de 16x16 est allouée en mémoire pour contenir l’ensemble des blocs nécessaires pour le rendu 1 du terrain à un instant donné. Une métrique d’erreur basée sur un simple calcul de distance est utilisée pour déterminer la résolution avec laquelle un bloc doit être affiché (figure 1.1). Au déplacement de l’observateur, une ligne ou une colonne complète de blocs est chargée et celle qui lui est opposée dans la grille est supprimée afin de maintenir une cohérence spatiale. Etant donné que le nombre de niveaux de détail est fixe, cette technique offre une adaptation limitée à la surface initiale. Néanmoins, elle est utilisée dans certains types d’applications où l’horizon du champ de vision est assez proche.

Figure. 1.1 – Rendu en multi-résolution dans le système NPSNET [FZP+93 ].

D’autres auteurs [ LKH+95 , RLI+99 ] ont utilisé un arbre quaternaire au lieu d’une grille pour partitionner le terrain. Chaque niveau stocke des blocs (des grilles uniformes) de même résolution. La racine de l’arbre stocke un maillage, avec une faible résolution, décrivant le terrain en entier ; tandis qu’une feuille comporte un bloc, à forte résolution, décrivant une toute petite partie du terrain. Au moment de l’exécution, l’arbre est parcouru et les blocs participant à l’affichage du frame courant sont sélectionnés en fonction du niveau de détail avec lequel ils doivent apparaître. Comme dans le cas de la technique précédente, des fissures apparaissent aux frontières des blocs voisins de résolutions différentes provoquant des artifices visuels. Ce problème est résolu par l’utilisation des polygones en mur verticaux (figure 1.5, section 1.2.1.1). Ces techniques semblent faciles à implémenter, mais elles sont soumises aux difficultés liées aux traitements des artifices visuels. En effet, elles n’assurent pas une continuité entre les niveaux de détails des blocs adjacents de différentes résolutions. Malgré cela, elles sont

1 Le rendu désigne l’opération qui, à partir du modèle géométrique d’une scène et d’informations sur l’environnement lumineux, produit une image pour un point de vue donné.

- 5 - Chapitre 1 : Techniques de simplification des terrains très populaires en raison de leur scalabilité notamment lorsqu’il s’agit de les utiliser dans des applications réseaux.

1.1.2 Grilles imbriquées régulières ( Nested regular grids )

Récemment Lassasso et Hoppe [LH04] ont proposé une méthode simple et efficace appelée geometry clipmap . Dans cette technique, le terrain est représenté par une pyramide de grilles carrées imbriquées centrées autour de la position de l’observateur et dont les tailles évoluent en puissance de deux. Lors d’un déplacement de l’observateur, la nouvelle approximation du terrain est obtenue par une simple permutation entre les niveaux successifs de la pyramide. Ainsi, l’approximation est dite dépendante du point de vue.

(a) pyramide de grilles (b) vue de dessus

(c) vue en perspective du terrain

Figure. 1.2 – Geometry clipmap.

Cette permutation est rendue possible du fait que les grilles (stockées dans la mémoire vidéo) sont dépourvues de leurs altitudes et que ces dernières ne sont considérées qu’au moment de la navigation. Afin de permettre une mise à jour efficace et incrémentale de ces

- 6 - Chapitre 1 : Techniques de simplification des terrains données, le tableau des altitudes est accédé d’une manière toroïdale, c’est à dire, en utilisant un adressage périodique dans les directions x et y [LH04]. Une transition douce entre deux niveaux est assurée à travers le chevauchement entre ces niveaux. De plus, les polygones en murs verticaux sont utilisés pour coudre les fissures à la frontière des niveaux de résolutions différentes.

1.1.3 Discussions

Les techniques citées précédemment tentent de résoudre le problème de visualisation interactive de terrains de manière simple et efficace au détriment de la qualité de simplification. En effet, l’objectif de ces techniques est de construire, à chaque frame , une approximation de la surface initiale sans prendre en considération des critères de subdivision permettant d’obtenir un nombre minimal de triangles nécessaires à la représentation de cette dernière. Dans ce qui suit, nous allons présenter des méthodes plus complexes qui s’appuient sur des structures de données efficaces (arbres binaires et quaternaires) afin de produire des surfaces à adaptation complète avec une continuité entre les différents niveaux de détails. Ces objectifs sont atteints grâce aux règles locales de subdivisions imposées lors de la construction du maillage approché.

1.2 Triangulation à résolution dynamique

Plusieurs techniques permettant d’obtenir une construction adaptative et une visualisation rapide des terrains ont été proposées. Comme nous le verrons par la suite, ces techniques exploitent les arbres quaternaires ( quadtree based triangulations) et les arbres binaires (triangle bin-tees) pour construire une triangulation adaptative et continue du terrain. Ainsi, le problème d’artifices visuels induit par l’agencement de grilles (voir section 1.1.1) est évité par construction. L’idée phare partagée par toutes ces approches est de construire par affinement ou bien par simplification hiérarchique un maillage régulier en multi-résolution. L’affinement consiste à subdiviser un triangle rectangle isocèle en deux triangles identiques de même nature à l’aide de la médiane issue de l’angle droit. Ce processus est réitéré de manière récursive jusqu’à satisfaction d’un critère d’arrêt. Tandis que, la simplification est le processus inverse de l’affinement : étant donné une triangulation régulière d’une grille représentant le terrain, les triangles rectangles sont fusionnés, selon une métrique d’erreur, dans un nouveau triangle de même nature. La régularité de ces deux processus permet le codage implicite et simple de toutes les dépendances entre les opérations (affinement / simplification) dans des structures de données compactes.

1.2.1 Triangulation en arbre quaternaire

Dans cette section, nous discutons plusieurs algorithmes de triangulation adaptative d’un champ de hauteurs ( height-fields ), basés sur l’utilisation des arbres quaternaires. Un exemple typique d’une surface simplifiée par triangulation en multi-résolution qui peut être construite par cette classe de méthodes est donné sur la figure 1.3.

- 7 - Chapitre 1 : Techniques de simplification des terrains

Figure. 1.3 – Triangulation adaptative basée sur les arbres quaternaires.

1.2.1.1 Méthode « Restricted quadtrees »

La triangulation adaptative hiérarchique basée sur la subdivision en arbre quaternaire des surfaces variété 2 dans l’espace de dimension deux, a été présentée pour la première fois dans [VB87] et appliquée sur les surfaces paramétriques courbées. Dans l’espace de ces paramètres, cette subdivision est effectuée récursivement, jusqu'à satisfaction de la condition de Lipschitz [BO06] pour l’ensemble des sous régions constituant la surface. De plus, elle est soumise à la restriction suivante : la différence en matière de niveaux de détails entre les régions voisines est au plus égale à un (voir figure 1.4). Les différentes étapes utilisées par cette approche pour trianguler et visualiser ce type de surfaces sont : 1. Initialisation : évaluation de la surface paramétrique dans une grille régulière en faisant varier les deux paramètres suivant un pas constant. 2. Evaluation de la métrique d’erreur d’approximation pour chaque région. 3. Subdivision en quatre régions égales des régions dont l’approximation est supérieure à l’erreur tolérée. 4. Répétition des étapes 2 et 3 jusqu’à l’obtention d’une erreur inférieure au seuil fixé préalablement pour l’ensemble des régions. 5. Triangulation et rendu de toutes les régions (les feuilles de l’arbre).

(a) (b) Figure. 1.4 – (a) Subdivision en arbre quaternaire sans restriction. (b) subdivision avec restriction.

2 Une variété est un espace topologique abstrait, construit par recollement d'autres espaces simples.

- 8 - Chapitre 1 : Techniques de simplification des terrains

Afin d’éviter l’apparition des fissures possibles dans la représentation polygonale (figure 1.5), chaque région est triangulée en fonction du niveau de détail de ses voisines. La restriction imposée par la technique fait que le niveau de détail entre ces régions diffère au plus de un niveau. La règle de triangulation est expliquée dans [VB87] comme suit : Chaque carré est subdivisé en huit triangles : deux triangles par bord, à moins que le bord encadre un plus grand carré ; auquel cas, un triangle simple est formé le long de ce bord (figure 1.6).

Figure. 1.5 – Fissures (ombrées en gris) résultant de la représentation polygonale quadrilatérale d’une surface subdivisée en arbre quaternaire avec restriction.

Aucun détail de l’algorithme ni d’ailleurs de la structure de données utilisée n’a été donné dans l’article [VB87]. Néanmoins, il constitue la base sur laquelle plusieurs travaux se sont appuyés pour proposer des approches de triangulation hiérarchiques basées sur l’utilisation des arbres quaternaires.

1.2.1.2 Méthode « Quadtree surface maps »

Dans [ Siv96 , SS92 ], la technique restricted quadtree a été améliorée et appliquée aux surfaces dites de dimensions 2.5. Cette représentation commune aux modèles numériques de terrains (MNT), est définie par une grille régulière stockant les altitudes des points de la surface. Deux algorithmes efficaces ont été fournis pour la construction de l’arbre et la génération de la triangulation [ SS92 ]. Le premier repose sur une approche ascendante tandis que le second utilise une technique descendante pour générer une représentation hiérarchique en arbre quaternaire avec restriction. L’auteur de l’article a observé que les nœuds de l’arbre de même niveau dans la hiérarchie et partageant des arêtes, ne devraient pas être subdivisés, afin de garantir une triangulation conforme (triangulation sans fissures - voir figures 1.6 et 1.7). Dans l’approche ascendante, la grille (carré) en entrée est partitionnée en nœuds atomiques de 3x3 points d’élévations (figure 1.8). Ces nœuds forment les feuilles d’un arbre complet et équilibré couvrant la grille. Ensuite, les nœuds sont fusionnés pour construire de bas en haut les autres nœuds de l’arbre quaternaire. Ce processus de fusion est conditionné par les deux critères suivants :

1. Métrique d’erreur : l’erreur d’approximation calculée, en enlevant les arêtes des points médians des nœuds à fusionner, devrait être inférieure à l’erreur tolérée.

- 9 - Chapitre 1 : Techniques de simplification des terrains

2. Contraintes sur l’arbre quaternaire : la taille du nœud devrait être égale à la taille de chacun de ses trois frères dans la hiérarchie de l’arbre, et ni le noeud ni ses frères ne devraient avoir des voisins de taille inférieure.

L’algorithme s’arrête si aucune des opérations de fusion n’est possible. Il est d’une complexité linéaire O(n) en espace mémoire et en temps d’exécution, où n représente le nombre des points d’élévations.

Figure. 1.6 – Triangulation conforme d’une subdivision en arbre quaternaire avec restriction, tel que présentée par [VB87].

Figure. 1.7 – Triangulation conforme améliorée issue d’une subdivision en arbre quaternaire avec restriction, tel que présentée par [ SS92 ].

Figure. 1.8 – Approche ascendante : Nœuds-feuilles atomiques utilisés pour la construction, avec restriction, de l’arbre quaternaire.

- 10 - Chapitre 1 : Techniques de simplification des terrains

Le second algorithme s’appuie sur une approche descendante pour construire l’arbre quaternaire avec restriction. Tout d’abord, la racine de l’arbre est construite à partir d’une approximation grossière des données en entrée. Puis, la subdivision est effectuée d’une manière récursive jusqu'à l’obtention d’une surface approchant au mieux ces données. La restriction sur la différence entre le niveau de détail des nœuds-feuilles adjacents (qui doit être au plus égale à 1) est maintenue durant ce processus.

Figure. 1.9 – (a) Les sommets du noeud racine (niveau 0), (b) les sommets non-persistants du niveau 1, (c) et ceux du niveau 2.

Les sommets qui peuvent être enlevés pour fusionner les nœuds frères sont appelés les sommets non-persistants. En commençant par le nœud racine (figure 1.9 (a)), pour chaque nœud de l’arbre partiellement construit, les sommets non-persistants sont identifiés parmi les données d’entrée et leurs erreurs d’approximation sont calculées et comparées avec l’erreur tolérée. Le sommet dont l’erreur n’est pas inférieure au seuil est inséré dans l’arbre. Cependant, l’insertion de ces sommets peut mener à une série de mises à jours complexes comme décrit ci-dessous. Afin de maintenir d’une manière permanente la restriction sur la construction de l’arbre, l’insertion des sommets non-persistants peut mener à une propagation de la subdivision jusqu’au nœud parent, mais aussi aux nœuds adjacents. Comme l’illustre la figure 1.10, il se peut qu’un nœud du niveau i ne soit pas subdivisé puisque aucun sommet du niveau i+1 n’est à insérer. Cependant un sommet v 2 du niveau i+2 doit être ajouté. Cette insertion ne peut pas être effectuée directement car il n’y a pas encore de parent créé et couvrant v2 dans niveau i+1. D’abord, il faut que le nœud parent de v2 et ses frères soient créés dans le niveau i+1 en subdivisant le plus petit nœud du niveau i enfermant v2 dans quatre nœuds. De telles subdivisions peuvent être propagées sur plusieurs niveaux de l’arbre quaternaire. Pour plus de détails, en particulier sur l’approche descendante, l’article [Siv96] présente une description plus approfondie. L’algorithme descendant proposé pour créer des maillages surfaciques adaptatifs traite en entier les données d’entrée avec un coût linéaire O(n) . Cependant, contrairement à l'algorithme ascendant, de même complexité, cette méthode calcule correctement l'erreur d'approximation à chaque insertion de sommet (voir section 1.4). Les deux méthodes présentées dans [ Siv96 , SS92 ] opèrent sur des structures de données hiérarchiques, de type arbres quaternaires. Elles fournissent les fonctionnalités nécessaires d’insertion des sommets, de calcul de la distance entre un point et une

- 11 - Chapitre 1 : Techniques de simplification des terrains approximation de la surface par morceaux linéaire, de recherche des voisins et de fusionnement ou de subdivision des nœuds. De plus, les nœuds qui ne vérifient pas la restriction imposée durant la construction de l’arbre sont post-traités afin de produire une triangulation conforme.

Sommets sélectionnés dans le niveau i Sommets non sélectionnés dans le niveau i+1 Sommets non sélectionnés dans le niveau i+2 Le sommet v2 sélectionné dans le niveau i+2 Sommets insérés dans le niveau i+1 Sommets insérés dans le niveau i a b Figure. 1.10 – (a) Début de la triangulation d’un nœud dans le niveau i. Pas de sommets initialement sélectionnés dans le niveau i+1. (b) La sélection d’un sommet dans le niveau i+2 force la subdivision et l’insertion de d’autres sommets dans les niveaux précédents.

Ces deux algorithmes sont capables, dans la limite de la métrique d’erreur, de créer une triangulation adaptative avec un niveau de détail continu. Cependant, leurs complexités ne sont pas optimisées pour le rendu temps réel de très grands terrains à cause de leur dépendance des algorithmes de triangulations basiques.

1.2.1.3 Méthode « Continuous LOD quadtree »

Une approche différente de triangulation et de génération d’un arbre quaternaire avec restriction est présentée dans [ LKR+96 ]. Elle est basée sur la notion de fusion de triangles (triangle fusion ). S’appuyant sur une triangulation entière de la grille régulière, cette approche ascendante procède par fusionnement consécutif de pairs de triangles symétriques afin de simplifier la représentation initiale. La triangulation de départ (comme l’illustre la figure 1.11 (a)) est équivalente aux nœud-feuilles atomiques de la technique ascendante présentée précédemment. Le fusionnement des triangles est réalisé en deux phases :

• Premièrement, dans un nœud atomique les pairs de triangles isocèles (a l et a r sur la figure 1.11 (b)) partageant la plus petite arête sont fusionnés, et le point médian sur l’arête du bord est supprimé. • Deuxièmement, le sommet central du nœud atomique est supprimé suite à la fusion

des pairs de triangles isocèles le long de la diagonale (e r et e l sur la figure 1.11 (c)).

Cependant, pour éviter l’apparition de fissures durant l’opération de fusion, deux pairs de triangles isocèles qui partagent le même sommet à supprimer, vont subir simultanément l’opération de fusion (voir les pairs el, er et fl et f r sur la figure 1.11 (c)). La contribution majeure qu’apportent les auteurs de l’article [ LKR+96 ] est l’introduction de la notion de

- 12 - Chapitre 1 : Techniques de simplification des terrains dépendance entre sommets qui permet d’éviter l’apparition des fissures et la création d’une triangulation conforme en multi-résolutions.

Figure. 1.11 – (a) Triangulation initial e. Fusion des pairs de triangles le long des arêtes du bord (b) et le long de la diagonale (c).

Par exemple, sur la figure 1.11 (b) et (c), il est clair que le point médian du bord (le point de base des triangles a l et a r) ne pourrait pas appartenir à la triangulation conforme si le sommet du centre est écarté (le point de base des triangles e l et e r). Cependant, du point de vue opposé, le sommet de base des triangles e l, e r et f l, f r ne peut pas être supprimé si l’un des sommets de base des pairs de triangles a l, ar, b l, br, cl, cr ou dl, dr est maintenu. Cette contrainte sur la construction de l’arbre quaternaire avec restriction, produisant une triangulation conforme, définie une relation de dépendance hiérarchique binaire entres les sommets comme illustré sur la figure 1.12.

niveau l niveau l niveau l+1 niveau l+1

Figure. 1.12 – (a-d) Relations de dépendances. Le sommet du centre dans (a) dépend de l’inclusion des deux coins du nœud. Les points médians des arêtes des bords dans (b) dépendent du sommet central du nœud. Les dépendances intra et inter sommets dans le niveau suivant sont illustrées dans (c) et (d).

Chaque sommet à insérer dépend de l’insertion de deux autres sommets de même niveau ou bien de ceux d’un niveau inférieur immédiat. Par conséquent, une triangulation d’un arbre quaternaire avec restriction est dite conforme seulement si aucune des relations de dépendances n’est violée lors de la construction de cet arbre. Le processus de triangulation définit dans [ LKR+96 ] résout d’une manière récursive le problème des relations de dépendances d’un ensemble S de sommets choisis (par exemple tous les sommets excédant une erreur tolérée) comme suit : pour chaque sommet v∈ S , tous les parents qui en dépendent (selon l’une des règles de dépendances figure 1.12) sont aussi récursivement activés et insérés dans la triangulation.

- 13 - Chapitre 1 : Techniques de simplification des terrains

Un autre aspect important présenté dans [ LKR+96 ] est celui de la construction, au moment de la création de la triangulation, d’un flux de triangles (triangle strip ) similaire à celui proposé plus tard dans [ HK95 ],. Ce concept est implémenté par le matériel graphique sous la forme d’une primitive de dessin. Par conséquent, cette technique est très efficace en matière de performances de rendu. La méthode de génération d’un triangle stip décrite dans [ LKR+96 ] repose sur une traversée récursive, dans le sens contraire des aiguilles d’une montre, et pré-ordonnée des triangles composant les triangles quadrants des blocs de l’arbre (figure 1.13). En commençant par le nœud racine, les triangles sont récursivement parcourus suivant une stratégie left-first : par exemple le triangle q0 (figure 1.13(c)). De cette façon, les sommets peuvent être ordonnés d’une manière cohérente pour former un triangle strip . Pour plus de détail, un code source est disponible dans l’article [ LKR+96 ].

Figure. 1.13 – (a-c) Traversée récursive de l’arbre pour générer un triangle strip .

1.2.1.4 Méthode « Restricted quadtree triangulation »

La technique dite Restricted Quadtree Triangulation (RQT ) présentée dans [ Paj98a , Paj98b], permet la visualisation en temps réel de grands terrains. Elle s’appuie sur une représentation hiérarchique en arbre quaternaire comme celle présentée dans [Siv96 , SS92 ] et exploite les relations de dépendances présentées dans [ LKR+96 ] pour générer une triangulation conforme minimale. Pour cette technique, deux algorithmes de triangulation ascendant et descendant ont été présentés. Ils opèrent sur deux grilles régulières : l’une stocke les altitudes des points d’un terrain ( terrain height-field ) et l’autre maintient les erreurs d’approximation leurs correspondant. L’auteur de l’article a observé que la structure hiérarchique en arbre quaternaire peut être définie implicitement dans la grille, par le biais d’une indexation appropriée et un ensemble de fonctions récursives, sans stockage explicite de cette dernière. Ce qui permet un gain important en terme d’espace mémoire. Comme expliqué dans [ Paj98b ], pour chaque point k+1 k+1 Pi,j des 2 x2 sommets de la grille, le niveau l dans l’arbre quaternaire implicite peut être efficacement calculé par des opérations arithmétiques et logiques sur les indices i et j (figure 1.14). Il a également constaté que les relations de dépendances de la figure 1.12 peuvent être exprimées à l’aide d’expressions arithmétiques fonction des indices ( i, j) des points.

- 14 - Chapitre 1 : Techniques de simplification des terrains

De ce fait, les deux algorithmes évoqués précédemment, s’exécutent très rapidement et agissent directement sur les données d’entrée, au lieu de manipuler une structure de données hiérarchique basée sur les pointeurs. Un algorithme de triangulation optimal exploitant la notion d’erreur strictement monotone (strict error monotonicity ) obtenue par saturation d’erreur (voir section 1.4) est présenté dans [Paj98a ]. Cela permet à un algorithme descendant de sélection de sommets, de ne pas résoudre les contraintes de dépendances ni d’ailleurs de propager la subdivision des triangles au moment de l’exécution. La métrique d’erreur proposée garantie que pour un seuil d’erreur fixé à l’avance, l’ensemble des sommets initialement sélectionnés satisfera automatiquement les contraintes imposées sur la construction de l’arbre quaternaire, qui par conséquent permettra d’obtenir une triangulation conforme.

niveau 0 niveau 1 niveau 2 Figure. 1.14 – Hiérarchie implicite de l’arbre quaternaire et indexation des points définis sur la grille régulière.

D’autre part, dans [ Paj98a ] un algorithme de construction d’un triangle strip a été proposé afin d’augmenter les performances de rendu. La hiérarchie implicite de l’arbre quaternaire est traversée pour construire ce flux au lieu de pré-ordonner les triangles des blocs comme proposé dans [LKR+96 ]. Comme illustré sur la figure 1.15, l’algorithme qui traverse récursivement les sommets centres des triangles des blocs, dans le sens contraire des aiguilles d’une montre, forme une courbe de remplissage de l’espace ( space filling curve ) où chaque triangle est visité une seule fois. Cette courbe présente aussi un chemin hamiltonien dans le graphe dual de la triangulation. Ainsi, le triangle strip peut être généré par un parcours en profondeur d’abord (depth-first ) de l’arbre quaternaire implicite dans un temps linéaire proportionnel à la taille de ce flux en terme de nombre de triangles.

Figure. 1.15 – (a) RQT triangle strip. (b) le chemin hamiltonien du graphe dual.

- 15 - Chapitre 1 : Techniques de simplification des terrains

1.2.1.5 Méthode « 4-8 meshes »

La classe des méthodes dites 4-8 meshes [BAV98 , BLV01 ], est basée sur une approche de subdivision en arbre quaternaire et une autre de triangulation comme l’illustre la figure 1.16. Du point de vue efficacité, cette triangulation est équivalente aux techniques vues précédemment. Cependant, au lieu de se baser sur un graphe de dépendances des sommets comme dans [ LKR+96 ], un domaine de fusion Mv (merging domain ) est définie pour chaque sommet v afin de satisfaire les contraintes de la triangulation et par conséquent, éviter l’apparition des fissures dans le maillage final. Comme schématisé sur la figure 1.17, le domaine de fusion Mv correspond fondamentalement à l’enveloppe transitive de tous les sommets dépendant de v dans le graphe de dépendances [ LKR+96 ]. En conséquence, Mv est utilisé pour définir l’ensemble des sommets qui seront enlevés de la triangulation. Un concept similaire, appelé domaine de subdivision ( splitting domain ), est utilisé pour insérer une liste de sommets dans une triangulation.

Figure. 1.16 – Subdivision récursive en 4-8 triangle mesh .

sommet v à supprimer, domaine M v à fusionner

Figure. 1.17 – (a) Un sommet v (en rouge) et son domaine de fusion M v (en blanc). (b) maillage triangulaire adaptatif obtenu après suppression du sommet et v et les sommets du domaine M v.

Pour affiner ou fusionner n nœuds, les algorithmes de triangulation de cette classe de méthodes sont d’une complexité de O(n log n) , alors que les deux algorithmes présentés dans [ LKR+96 , Paj98a ] peuvent générer d’une manière optimale un maillage adaptatif de n triangles dans un temps linéaire O(n) .

1.2.1.6 Méthode « Irregular quadtree hierarchy »

Il a été montré, dans [ Vel01 , VG00 ], que toutes surface 3D peut être adaptativement triangulée en utilisant une approche hiérarchique de triangulation 4-8, pourvu qu’une

- 16 - Chapitre 1 : Techniques de simplification des terrains paramétrisation de cette surface variété soit donnée. L’approche QuadTIN présentée dans [PAL02 ] construit une hiérarchie en arbre quaternaire avec restriction à partir de n’importe quel ensemble de points distribués irrégulièrement dans l’espace 2D ; par exemple, un réseau de triangles irréguliers (Triangulated Irregular Network ). Comme dans [ Vel01 , VG00 ], l’idée de l’approche QuadTIN [ PAL02 ] est basée sur le fait que les points ne doivent pas nécessairement être sur une grille régulière pour permettre une subdivision hiérarchique régulière (figure 1.18). À chaque étape de la subdivision, l’arête diagonale d’un quadrilatère n’est pas nécessairement subdivisée au niveau de son point médian. Si ce dernier n’existe pas, parmi l’ensemble des points d’entrée, il est remplacé par le sommet qui lui est le plus proche (figure 1.19 (a)). niveau l-1 niveau l niveau l niveau l+1

Figure. 1.18 – Subdivision récursive QuadTIN irrégulière.

Figure. 1.19 – (a) Le sommet le plus proche au point médian de l’arête diagonale e t,t’ est sélectionné pour faire une subdivision récursive. (b) seuls les sommets d’un domaine restreint sont considérés.

Afin d’éviter, d’une part, l’apparition des triangles étirés et, d’autre part, le problème d’inversion d’orientation, une restriction est imposée sur le domaine de recherche des points candidats parmi l’ensemble des sommets du TIN (figure 1.19 (b)). Dans le cas où il n’y pas de candidat dans le domaine de recherche, des points artificiels (Steiner points ) sont insérés dans la triangulation pour garantir une cohérence dans la construction de la hiérarchie. Un exemple qui montre la flexibilité de la triangulation adaptative QuadTIN et son adaptabilité à un ensemble de points d’entrée distribués irrégulièrement est donné sur la figure 1.20.

- 17 - Chapitre 1 : Techniques de simplification des terrains

Figure. 1.20 – Triangulation adaptative QuadTIN d’une distribution irrégulière de points d’élévation.

1.2.2 Triangulation en arbre binaire

Dans cette section, nous discutons des algorithmes basés sur la bissection de triangles qui permettent de produire une triangulation adaptative à partir d’une grille régulière décrivant la surface d’un terrain.

1.2.2.1 Méthode « Real-time optimally adapting meshes »

Connue sous le nom de ROAM , cette méthode présentée dans [ DWS+97 ] est conceptuellement très proche de celle décrite dans [ LKR+96 ]. Cependant, elle est strictement basée sur la notion d’arbre binaire de triangles ( triangle bin-tree ) comme le schématise la figure 1.21. Elle est également considérée comme étant un cas particulier de la technique d’affinement basée sur la bissection des triangles allongés ( longest side bisection ) présentée dans [ Riv93 , Riv95 ]. Cette méthode affine récursivement les triangles par subdivision de la plus longue arête au niveau du sommet de base (voir aussi la figure 1.11).

niveau l niveau l+1 niveau l+2 niveau l+3

Figure. 1.21 – Hiérarchie binaire construite par bissection de la plus longue arête des triangles isocèles ( sommet de base, le point médian de la plus longue arête)

Comme l’illustre la figure 1.22, une opération d’affinement engendre la subdivision d’une paire de triangles au niveau du sommet de base de la plus longue arête partagée, tandis qu’une opération de simplification consiste à fusionner deux paires de triangles au niveau du sommet de base.

- 18 - Chapitre 1 : Techniques de simplification des terrains

Figure. 1.22 – Opérations de subdivision et de fusion utilisées dans un algorithme de triangulation basé sur un arbre binaire de triangles.

Une observation importante (en liaison avec l’obtention d’une triangulation conforme) est que tous les voisins d’un triangle t dans le niveau l de la hiérarchie devraient être dans le même niveau que t ou dans les niveaux l+1 ou l-1de l’arbre binaire. Par conséquent, deux paires de triangles ( ta,t b) et ( tc,t d) partageant le même sommet de base ne peuvent être fusionnés que s’ils sont dans le même niveau hiérarchique (figure 1.22). En outre, un triangle t ne peut pas être subdivisé immédiatement si son voisin tlong à travers sa plus longue arête est d’un niveau plus élevé dans la hiérarchie (figure 1.23). Dans ce cas, la subdivision du triangle t est précédée par la subdivision du voisin en question. Cette subdivision forcée est conceptuellement semblable à la notion de propagation de la subdivision [ SS92 ] (figure 1.10). D’ailleurs, la relation de dépendance [ LKR+96 ] (figure 1.10) dénote exactement la même propagation de subdivision forcée d’un arbre binaire ou d’un arbre quaternaire avec restriction durant la triangulation. Tous ces concepts, qui permettent d’obtenir une triangulation conforme, sont équivalents dans ce contexte.

Subdivision en cours au niveau du point de base Subdivisions forcées Figure. 1.23 – Propagation des subdivisions forcées des triangles.

La technique de triangulation temps réel ROAM est basée sur un algorithme de type glouton qui utilise deux files d’attente de triangles ( t ∈ T : le maillage triangulaire courant) avec priorités :

• Une file d’attente de subdivision ( split ) avec priorité Qs stocke les triangles t∈T en fonction de leurs priorités a être subdivisés,

• Une file d’attente de fusion ( merge ) Qm maintient les paires de triangles de T candidats a être fusionnés. A chaque frame , les deux files d’attentes sont consultées et le maillage courant est adaptativement affiné ou simplifié en fonction de l’erreur tolérée « τ ». Le calcul de ces priorités est basé sur une métrique d’erreur définie sur les triangles.

- 19 - Chapitre 1 : Techniques de simplification des terrains

L’algorithme proposé exige que la métrique d’erreur d’approximation et celle utilisée pour le calcul des priorités des files d’attentes Q s et Q m, soient strictement monotones. Cela signifie que l’erreur ou la priorité de n’importe quel triangle dans la hiérarchie de l’arbre binaire ne doit pas être supérieure à celles de ses parents. Cette condition de monotonie limite l’utilisation directe de plusieurs métriques d’erreur standard. Par exemple, ni la métrique d’erreur dépendante du point de vue [ LKR+96 ], ni celle utilisant la mesure de distance verticale [ SS92 ], ni même celle définie hiérarchiquement par la distance de Hausdorff 3 ne répondent pas à cette condition de monotonie (voir section 1.4). Pour remédier à ce problème et forcer la monotonie de n’importe quelle métrique d’erreur, un traitement particulier doit être pris en considération. Il consiste à traverser les triangles de l’arbre binaire de bas en haut tout en calculant dans une phase de prétraitement les bornes des priorités de chaque nœud. De plus des deux contributions majeures qu’apporte l’algorithme ROAM, à savoir, l’utilisation des files d’attentes de priorités sur les triangles pour construire une triangulation adaptative, et la proposition d’une métrique d’erreur basée sur le calcul d’une distorsion dans l’espace écran, le travail présenté dans [ DWS+97 ] énumère d’autres contributions intéressantes. Une liste de douze critères, qui s’appliquent généralement dans le contexte de la simplification et de la visualisation des grands terrains, est donnée. En outre, quelques techniques d’implémentations pour améliorer les performances de ROAM y sont décrites, à savoir, l’élimination des faces extra volume de vision ( view frustum culling ), la génération incrémentale d’un flux de triangles ( incremental triangle strip generation ), le re-calcul différé des priorités ( deferred priority re-computation ), et l’optimisation progressive ( progressive optimization ).

1.2.2.2 Méthode « Right-triangulated irregular networks »

Le réseau de triangles droits irréguliers (RTIN) présenté dans [ EKT01 ], est une plate- forme de triangulation en multi-résolution appartenant à la même classe des méthodes dite triangle bin-trees . Cette approche s’est particulièrement focalisée sur une représentation efficace de la hiérarchie en arbre binaire et le parcours rapide du maillage pour trouver les voisins. L’approche commence par un carré, englobant les points d’entrée, divisé en deux triangles à partir d’un de ses deux diagonales. Les triangles sont ensuite subdivisés récursivement au niveau du point de base (le point médian de la plus longue arête), de la même manière que la technique décrite précédemment. Afin de garantir une triangulation conforme, la même propagation de subdivision forcée (figure 1.23) est imposée à la technique de triangulation RTIN. L’auteur de l’article [ EKT01 ] a observé que la propagation causée par la subdivision d’un triangle t se trouvant dans le niveau hiérarchique lt ne peut pas entraîner la subdivision d’un triangle de surface inférieure à t (dans les niveaux l > lt), et

3 La distance de Hausdorff est un outil topologique qui mesure l’éloignement de deux sous ensembles d’un espace métrique sous-jacent.

- 20 - Chapitre 1 : Techniques de simplification des terrains

qu’au plus deux triangles de chaque niveau l ≤ l t sont subdivisés. Cette propagation de subdivision nécessite au pire des cas O(log n) étapes, où n représente le nombre de triangles constituant les nœuds feuilles de l’arbre binaire. Une des principales contributions de l’article [ EKT01 ], est la proposition d’une structure de données efficace pour représenter la hiérarchie en arbre binaire. Comme le schématise la figure 1.11, les triangles fils sont marqués en tant que fils gauche et fis droit en cohérence avec la subdivision au niveau du sommet de base de leur triangle parent. De la même manière, un étiquetage binaire est utilisé (figure 1.24) dans la technique RTIN pour identifier les régions triangulaire de l’approximation. En effet, une triangulation RTIN est représentée par un arbre binaire dénotant les subdivisions d’un triangle et les élévations (les coordonnées d’altitudes z) des sommets de ce triangle. Les coordonnées (x, y) n’ont pas besoin d’être stockées pour chaque sommet puisqu’elles sont calculées à partir des étiquettes des triangles.

Figure. 1.24 – Etiquetage binaire de la technique RTIN utilisant 0 pour les fis gauches et 1 pour les fils droits.

La seconde contribution de l’article [ EKT01 ] est la proposition d’un schéma de recherche rapide des voisins en s’appuyant sur cet étiquetage binaire. Etant donné une numérotation, dans le sens contraire des aiguilles d’une montre, de v1 à v3 des sommets d’un triangle t avec v3 le sommet de l’angle droit, le i-voisin du triangle t est défini comme étant le triangle adjacent ti qui ne partage pas le sommet i. En outre, les i-voisin de même-taille (the same- size i-neighbors ) de n’importe quel triangle sont les triangles adjacents à travers les arêtes se trouvant dans le même niveau de la hiérarchie de l’arbre binaire. Par exemple, le triangle 10 (figure 1.24) est le 1-voisin de même-taille du triangle 11, et le triangle 001 est le 3-voisin du triangle 0000. Par contre, ce n’est pas un voisin de même-taille. La fonction de recherche des voisins NI (t) présentée dans [ EKT01 ] recherche, en premier lieu, les i-voisin de même-taille d’un triangle puis détermine le i-voisin actuel d’une triangulation particulière. Cette fonction récursive qui renvoie l’étiquette du i-voisin de même-taille d’un triangle t, est conceptuellement identique au parcours récursif d’un arbre pour trouver les régions adjacentes dans n’importe quel arbre de partitionnement binaire d’un espace ( BSP-tree

[Sam89a , Sam89b]). Une implémentation efficace non récursive de NI (t) basée sur des opérations logiques et arithmétiques est aussi donnée dans [ EKT01 ].

- 21 - Chapitre 1 : Techniques de simplification des terrains

1.2.2.3 Méthode « Right-triangular bin-tree »

Dans l’article [ Ger99 ], la classe de méthodes utilisant les arbres quaternaires avec restriction ou les arbres binaires de triangles droits est étudiée en tenant compte de l’efficacité de : stockage, traitement, accès, recherche et compression des données. La plate forme de triangulation en multi-résolution proposée dans [ Ger99 ] suit la même approche de construction de la hiérarchie binaire de triangles que celle présentée dans [DWS+97 , EKT01 ]. Afin d’éviter l’apparition des fissures dues à la bissection récursive des triangles, la mesure de saturation d’erreur [Paj98a ] est utilisée. La contribution majeure de l’article [Ger99 ] est la représentation compressée de la hiérarchie en arbre binaire basée sur un parcours efficace du maillage et un schéma de numérotation des triangles. Comme l’illustre la figure 1.25, le parcours ordonné des triangles dans la hiérarchie est équivalent à celui utilisé dans un flux de triangles ( triangle strip ). En outre, chaque triangle est numéroté suivant la parité du niveau hiérarchique de son parent comme suit : si le parent de numéro n se trouve dans un niveau impair, ses fils gauche et droit porteront les numéros 2n et 2n+1 respectivement et inversement si le niveau du parent est pair (figure 1.25). Pour un triangle donné, des opérations logiques au niveau bits peuvent être utilisées pour calculer le triangle adjacent qui partage le même sommet de base.

Figure. 1.25 – Numérotation des triangles (les sommets de base constituent le repère de subdivision et de numérotation).

La numérotation des triangles ainsi faite, impose une classification binaire des triangles (triangle haut ou triangle bas) dans la triangulation conforme. Un triangle haut ne peut avoir qu’un voisin de même niveau ou d’un niveau plus élevé (résolution grossière) lors d’un parcours en profondeur d’abord de l’arbre binaire. De la même manière, un triangle bas ne peut être suivi que par un triangle de même niveau ou de niveau plus faible dans la hiérarchie. Par conséquent, il suffit d’avoir le triangle de départ et un bit par triangle pour coder la triangulation. En outre, les sommets ont besoin d’être spécifiés seulement à la première occurrence durant le parcours de l’arbre binaire. En se basant sur ce parcours et sur la technique de numérotation, une représentation compressée de la hiérarchie en arbre binaire est proposée. D’ailleurs, il a été montré qu’une triangulation adaptative arbitraire peut être efficacement extraite depuis un flux de code représentant toute la hiérarchie et par conséquent, elle peut être lue et traitée efficacement depuis un média de stockage. Le codage proposé de l’arbre binaire des triangles est très intéressant dans la mesure où il peut être utilisé pour accéder efficacement à une triangulation adaptative surtout lorsqu’il s’agit d’un arbre binaire stocké d’une manière séquentielle sur disque.

- 22 - Chapitre 1 : Techniques de simplification des terrains

1.2.3 Discussions

Au cours des années 90, les cartes graphiques présentaient des limites en terme de capacité d’affichage. C’est pour cette raison que les travaux effectués à cette époque, notamment les algorithmes à résolution dynamique, avaient pour objectif principal de calculer, au niveau du CPU, une triangulation conforme de taille minimale, capable d’être affichée par le matériel graphique à chaque frame . Plus récemment, des améliorations significatives en terme de vitesses de calcul et de communication ont été apportées aux GPU, provoquant la migration du goulot d’étranglement du GPU vers le CPU. Ce qui a conduit à l’apparition d’une autre classe d’algorithmes visant, cette fois-ci, à alléger le CPU en se basant principalement sur des approches de traitement par cluster. Ces dernières seront détaillées dans la section ci- dessous.

1.3 Triangulations par cluster

Les améliorations apportées au GPU en terme de vitesse de calcul et de rapidité de communication avec le CPU ont fortement influencé les techniques de rendu temps réel. Désormais, plusieurs aspects architecturaux du GPU guident la modélisation elle-même de ces techniques. Actuellement, les processeurs graphiques sont capables de traiter des milliards de triangles par seconde, ce qui engendre deux conséquences importantes. D’une part, le chargement depuis le CPU des données constituant la triangulation adaptative doit se limiter à un nombre minimale de cycles d’exécution par triangle afin de pouvoir soutenir la vitesse du GPU. D’autre part, le rendu interactif de scènes de haute qualité composées de millions de triangles par frame est devenu possible. Les structures de données classiques (basées sur les sommets ou sur les triangles) qui gèrent et stockent en temps réel des graphes de dépendances de taille importante provoquent un goulot d’étranglement. Cela est dû principalement aux accès aléatoires durant le parcours des structures hiérarchiques et au manque de cohérence au niveau du cache. D’ailleurs, les GPU actuels sont optimisés pour le rendu en mode graphique maintenu et leurs performances maximales sont atteintes particulièrement en adoptant certains formats et chemins de données. Ceci implique l’utilisation des primitives de dessin empaquetées et alignées ( packed and aligned primitives ) et des primitives à base de flux ou d’index pour bien exploiter d’une part, les caches associés à chaque sommet et d’autre part, les chemins de rendu les plus rapides. En outre, le nombre d’appels de primitives par frame doit être maintenu à un niveau bas afin de permettre au pilote graphique de contrôler le temps de rendu [ Wlo04 ]. En conclusion, les performances maximales ne sont obtenues qu’en faisant un rendu de données se trouvant dans la mémoire GPU. Cependant, la mise à jour de cette mémoire entraîne des enjeux de synchronisation entre le CPU et le GPU ; ce qui est problématique pour les techniques de simplification à résolution dynamique. De ce fait, les approches qui sélectionnent, à chaque frame , l’ensemble minimal de triangles à rendre depuis le CPU typiquement non pas assez de flux de sortie pour alimenter le GPU au

- 23 - Chapitre 1 : Techniques de simplification des terrains maximum de sa capacité. Puisque la fréquence de traitement du GPU augmente plus rapidement que celle du CPU, la marge entre ce que le GPU pourrait rendre et ce que le CPU est capable de calculer à la volée, afin de générer des triangulations adaptatives, est continuellement appelée à s’agrandir. Pour toutes ces raisons, plusieurs techniques ont été récemment proposées pour réduire le travail de chargement par primitive en composant en temps réel des blocs pré-assemblés de surfaces optimisées. Ainsi, l’utilisation d’un modèle de rendu en mode maintenu est devenue possible à l’encontre d’un modèle de rendu direct moins efficace pour toutes les tâches de communication CPU/GPU.

1.3.1 Blocs de carreaux « Tiled blocks »

Un exemple classique d’approches de triangulation par cluster est celui des techniques de blocs de carreaux [ HM93, WMD+04 ], qui partitionnent le terrains en un ensemble de patches carrés représentés en différentes résolutions. L’une de ces techniques est celle proposée dans [ SW06 ], qui combine l’approche en blocs de carreaux avec celle de la triangulation en arbre quaternaire avec restriction. Cette technique s’efforce d’améliorer efficacement la communication entre CPU et GPU par le biais de mises à jours incrémentales regroupées en lots. Dans cette approche, le terrain est partitionné en carreaux égaux de taille 257x257, avec un chevauchement d’une ligne ou d’une colonne dans chaque direction. Pour chaque carreau, un arbre quaternaire avec restriction composé d’un ensemble fixe de maillages est généré. Il en résulte une hiérarchie de maillages imbriqués par carreau. Au moment de l’exécution, un LOD spécifique est indépendamment sélectionné pour chaque carreau et les mises à jours appropriées sont envoyées au GPU. Chaque niveau détaillé est représenté par tous les sommets des niveaux grossiers plus ceux additionnels. En cachant le maillage courant au niveau de la mémoire GPU, seuls les sommets additionnels ont besoin d’être envoyés, réduisant de 50% la bande passante requise au transfert CPU/GPU. Puisque les sommets sont transférés par groupes, des techniques efficaces de tableaux de sommets ( vertex array ) peuvent être utilisées pour augmenter l’efficacité du transfert. Dans [SW06 ], tous les sommets d’un carreau donné sont stockés dans un tableau, dont sa taille s’accroît pour chaque LOD, alors que les connectivités entre ces sommets sont stockées séparément pour chaque niveau dans des tableaux d’indexes. Afin d’assurer une transition douce lors du changement de la surface, cette méthode utilise le concept de géo-morphing [Hop98 ], qui permet d’interpoler les attributs des sommets entre LODs. Le défi principal de cette méthode ainsi que pour toutes les techniques de blocs de carreaux est de pouvoir traiter les points de suture dans les frontières des blocs, qui nécessite un temps d’exécution supplémentaire. Dans [ SW06 ], les frontières des blocs adjacents sont détectées et connectées en utilisant des triangles générés au moment de l’exécution. Comme nous allons le voir plus tard, ce traitement sera évité dans les techniques basées sur les arbres quaternaires. D’ailleurs, cette technique n’est pas

- 24 - Chapitre 1 : Techniques de simplification des terrains entièrement adaptative et limite la simplification à des sous échantillons de données afin de soutenir la transmission progressive des sommets.

1.3.2 Arbres binaires mis en cache « Cached Triangle bin-trees » Les techniques RUSTIC [ Pom00 ] et CABTT [ Lev02 ] sont deux extensions de l’algorithme ROAM [ DWS+97 ]. Ces deux techniques améliorent les performances de rendu par l’ajout d’un cache à grain grossier (coarse-grained on-board caching ). RUSTIC est une extension de l’algorithme ROAM de base dans laquelle des sous-arbres statiques pré-calculés de l’arbre binaire de triangles de ROAM sont utilisés. L’approche CABTT est très similaire à RUSTIC mais des clusters de triangles sont dynamiquement créés, mis en cache et réutilisés durant le rendu. Les clusters forment les éléments unitaires des opérations d’affinement ou de simplification et peuvent être cachés dans des tableaux de sommets.

1.3.3 Combinaison des triangulations régulières et irrégulières

BDAM [ CGG+03a ], P-BDAM [ CGG+03b ] et HyperBlock-QuadTIN [ LPT03 ] ont généralisé l'approche de l’utilisation d’un cache en combinant des triangulations régulières et irrégulières dans la même plate-forme sous GPU. Dans ces techniques, le rôle des structures multi-résolution est de générer des partitions régulières adaptatives du terrain indépendamment des données, alors que le rôle de la géométrie est d’approcher les données à l’intérieur de la partition avec un maillage, provenant d’une triangulation irrégulière, qui tient compte des contraintes appropriées sur les frontières et comporte un nombre fixe de triangles.

1.4 Métriques d’erreurs

Dans cette section, nous passons en revue la majorité des métriques d’erreurs qui ont été proposées ou utilisées par les algorithmes de triangulations vus précédemment.

1.4.1 Erreur d’approximation dans l’espace objet

Pour pouvoir afficher des surfaces paramétriques déformées, plusieurs critères de subdivision récursive qui tiennent compte de la courbure locale, de l’intersection des surfaces et de la silhouette des frontières, ont été présentés dans la référence [VB87]. Cependant, ces critères ne sont pas directement applicables sur les données d’élévation modélisant un terrain. L’erreur d’approximation proposée dans [ SS92 ] se réfère à la distance verticale d’un sommet supprimé à l’égard de son interpolation linéaire prévue par son nœud parent. Sur la figure 1.26, l’erreur du sommet B est définie par la différence entre sa distance verticale et l’élévation moyenne des sommets A et C. Un exemple de nœuds fusionnés, tel que décrit dans la section 1.3.1 est donné sur la figure 1.26b. Supposons que l’erreur d’approximation de tous les sommets supprimés (les points esquissés de la figure 1.26) est en dessous de

- 25 - Chapitre 1 : Techniques de simplification des terrains l’erreur tolérée et qu’il n y a pas de nœuds voisins qui viole la restriction imposée sur la construction de l’arbre quaternaire, alors les nœuds et les triangles (figure 1.26a) peuvent être fusionnés dans des nœuds plus larges (figure 1.26b). Le problème principal de l’algorithme ascendant proposé dans [ SS92 ] est l’évaluation de la métrique d’erreur d’approximation. Du fait que la distance verticale d’un sommet supprimé (B sur la figure 1.26) à l’égard de son interpolation linéaire (la ligne entre A et C) prévue par le nœud parent immédiat peut être inférieure à un seuil d’erreur « τ ». Il n’est pas clair que la distance de ce sommet reste inférieure à ce seuil jusqu’à achèvement du processus itératif de simplification ascendante par fusionnement. Comme l’illustre la figure 1.27, cette métrique d’erreur n’est pas monotone. En fait, la surface simplifiée résultante n’interpole pas les sommets supprimés dans une distance bornée.

Figure. 1.26 – (a) Quatre nœuds feuilles initiaux à fusionner. (b) les nœuds fusionnés avec les points supprimés (petits cercles creux).

Figure. 1.27 – Le fusionnement des nœuds satisfaisant localement l’erreur d’approximation tolérée peut avoir comme conséquence intolérable un cumul d’erreurs à l’égard du résultat final [PG07].

Cependant, l’approche descendante présentée dans [ SS92 ] calcule la distance à la surface originale pour chaque sommet. Par conséquent, aucune accumulation des erreurs au-delà de l’erreur tolérée τ ne peut se produire. La surface re-construite est dite correcte à une approximation τ. Une mesure de distance verticale similaire a été utilisée dans [ EKT01 , Paj98a ], et modifiée pour vérifier la propriété de monotonie décrite dans [ DWS+97 ]. Cependant, contrairement aux techniques présentées dans [ EKT01 ] et [ DWS+97 ], qui définissent la métrique d'erreur sur les triangles, l'approche RQT [ Paj98a ] définit l'erreur métrique sur les

- 26 - Chapitre 1 : Techniques de simplification des terrains sommets. Si cette dernière est pré-calculée par triangle, ceci assure directement la propriété de monotonie de la métrique d’erreur, en prenant la distance maximale des sommets appartenant au domaine que couvre le triangle. Cependant un attribut d’erreur d’approximation géométrique doit être stocké pour chaque triangle issu de la triangulation adaptative. Ceci peut être très coûteux en termes d’utilisation mémoire car ce nombre est plusieurs fois plus grand que le nombre des données en entrée (les données d’élévations). La métrique d’erreur par sommet proposée dans [ Paj98a ] élimine ce surcoût. Il a été observé dans [ Paj98a , Paj98b] et [ OR99 ] que dans le cas des métriques d’erreurs calculées dans l’espace objet, le graphe de dépendances de la figure 1.12 peut être encodé dans la métrique d’erreur elle-même par le biais d’une technique dite de saturation d’erreur. Comme l’illustre la figure 1.28a, la sélection d’un sommet particulier P (carré noir) due à son erreur ε=9, dépassant l’erreur tolérée τ=5, provoque plusieurs subdivisions forcées des triangles (lignes discontinues). Pour éviter de telles situations, les valeurs d’erreurs sont propagées et maximisées le long du graphe de dépendances (figure 1.28b).

Figure. 1.28 – (a) Métrique d’erreur calculée pour les sommets sélectionnés. Les sommets en blanc (noir) ont une erreur inférieure (supérieure) à la tolérance τ = 5. les subdivisions forcées sont indiquées par des lignes discontinues. La propagation de la saturation d’erreur est montrée pour le sommet qui a provoqué ces subdivisions.

Cette saturation d’erreur est effectuée en prétraitement : Chaque sommet stocke la valeur maximale de toutes les erreurs propagées et de sa propre erreur calculée, et propage ce maximum le long du graphe de dépendances. Ce prétraitement peut être effectué par un simple parcours de la grille des élévations. Par conséquent, une sélection rapide descendante des sommets selon leurs erreurs saturées donne directement une triangulation adaptative conforme d’un arbre quaternaire avec restriction. Ceci sans avoir recours à des contraintes sur la construction de l’arbre, aux subdivisions forcées ou de résoudre les relations de dépendances. Cette technique de saturation des erreurs a été observée aussi dans [BAV98] et peut être appliquée de plusieurs façons pour faire respecter les contraintes de construction des hiérarchies en multi-résolution telle que la préservation de la topologie dans l'extraction d'iso-surface [ GP00 ]. Une autre métrique d’erreur d’approximation dans l’espace objet est définie dans [DWS+97 ], en calculant pour chaque triangle t dans la hiérarchie de l’arbre binaire l’épaisseur εt du volume englobant qui enferme tous les enfants de ses sous-arbres (figure 1.29). Cette mesure limite la déviation maximale d’un maillage simplifié vis-à-vis des

- 27 - Chapitre 1 : Techniques de simplification des terrains données brutes en entrée. Cependant, elle doit être calculée et stockée pour chaque triangle qui peut être définit par la hiérarchie multi-résolution. Comme nous allons le voir dans la section suivante, cette limite d’approximation basique dans l’espace objet représente une entrée pour la métrique d’erreur (dépendante du point de vue) définie dans l’espace image.

Figure. 1.29 – L’épaisseur du volume englobant détermine l’erreur d’approximation géométrique dans l’espace objet.

1.4.2 Erreur d’approximation dans l’espace image

Une métrique d’erreur statique définie dans l’espace objet est insuffisante pour simplifier d’une manière adaptative un terrain qui va être rendu en perspective. Cela est dû au fait que les régions lointaines doivent être simplifiées plus que les zones proches. En effet, la simplification doit dépendre de la position de l’observateur qui change continuellement durant la navigation. Par conséquent, la métrique d’erreur doit être définie dynamiquement en fonction du point de vue. Une métrique d’erreur efficace dans l’espace image a été proposée dans [ LKR+96 ] qui consiste à déterminer, pour un point de vue donné, la liste des sommets qui doivent être inclus ou enlevés de la triangulation. Comme l’illustre la figure 1.30, l’idée fondamentale de cette métrique est que les pairs de triangles peuvent être fusionnées si l’écart εv projeté dans τ ρ l’espace écran est inférieur à une erreur tolérée « ». Soit v la projection en perspective ε = − du segment de droite v v v entre le sommet de base et son interpolation = + ρ τ linéaire v (vl vr 2/) . Si v est inférieure à la tolérance , le sommet v peut être supprimé et les pairs de triangles lui correspondant peuvent être fusionnées. Notons que la projection ρ v n’est pas définie en fonction de la résolution la plus élevée du maillage, ni du LOD courant mais plutôt en correspondance avec les deux sommets adjacents vl et vr du niveau de résolution inférieure dans l’arbre quaternaire. Par conséquent, bien qu’il soit difficile à apercevoir dans la pratique, cette métrique d’erreur telle qu’elle est définie dans [ LKR+96 ] souffre des mêmes inconvénients que celle de l’approche ascendante [SS92 ]. Elle ne garantie pas une limitation de l’erreur dans la triangulation finale. Pour cela, la métrique d’erreur nécessite d’être saturée correctement ou définie et maximisée pour chaque triangle en cohérence avec la résolution initiale du maillage.

- 28 - Chapitre 1 : Techniques de simplification des terrains

Figure. 1.30 – Distance verticale εv entre le sommet de base v candidat à être supprimé et son interpolation linéaire v .

Dans [ LKR+96 ], la métrique d’erreur, dépendante du point de vue, calculée dans l’espace image a été étendue à tous les blocs de l’arbre quaternaire. En particulier, si pour une région R de l’arbre, la projection maximale des sommets de haute résolution dans R est plus petite que τ, alors la région peut être ignorée durant le processus de simplification. Pour une boite englobante d’un bloc de R et sachant les paramètres de visualisation, on peut calculer ε ε la plus petite des élévations l et la plus grande h de cette boite, qui une fois projetée sur τ ε l’écran peut excéder . Par conséquent, si l’erreur verticale maximale max de tous les ∈ ε sommets v R est plus petite que l alors la région R peut être remplacée par un bloc de ε ε résolution inférieure. Si max est plus grande que h alors R doit être affinée en plus petits blocs. Autrement dit, les erreurs projetées dans l’espace écran doivent être calculées pour tous les sommets v ∈ R et comparées individuellement à τ. De la même manière que l’approche présentée dans [ LKR+96 ], l’épaisseur du volume de ε vision t tel qu’il a été introduit dans [ DWS+97 ] (voir figure 1.29), peut être utilisé pour ρ estimer la distorsion maximale t d’un triangle t dans l’espace image durant le processus de simplification dépendante du point de vue. Par conséquent, pour une triangulation donnée ρ T, sa distorsion dans l’espace image peut être limitée par la longueur maximale projetée t de tous les triangles t ∈T . De plus, pour cette métrique de distorsion, les auteurs de l’article [DWS+97 ] proposent plusieurs autres critères d’affinement et de simplification à savoir : réduction des détails des faces arrières, distorsion normale des surfaces, distorsion des coordonnées de textures, préservation des silhouettes, élimination des faces extra volume de vision, atténuation atmosphérique ou de profondeur. Dans [ LP01 , LP02 ] et [ Ger03 ] il a été observé que les métriques d’erreurs dépendantes du point de vue peuvent aussi, dans un sens, être saturées de la même façon que dans l’article [ Paj98a ] pour les mesures exprimées dans l’espace objet. Cela fonctionne ρ seulement si la métrique d’erreur v d’un sommet v est basée sur une erreur ε d’approximation géométrique statique v , qui est projetée en perspective dans l’espace image (divisée par d v , où d v est la distance entre le sommet v et la position de ε l’observateur). Pour que cela fonctionne correctement, en plus de v , une sphère englobante de rayon invariant rv est nécessaire pour chaque sommet. Cet attribut rv permet de définir une hiérarchie imbriquée de sphères englobantes sur le graphe de dépendances des sommets d’un arbre quaternaire avec restriction. Un sommet v est

- 29 - Chapitre 1 : Techniques de simplification des terrains sélectionné dans le LOD courant d’une triangulation seulement si l’erreur invariante dans ρ = ε − τ l’espace image v /( d v rv ) est supérieure à l’erreur tolérée .

1.4.3 Discussions

La métrique d’erreur utilisée par les techniques en arbres binaires est définie sur les triangles de la hiérarchie. En raison des propriétés de ces arbres ayant approximativement 2n nœuds pour n feuilles et un maillage triangulaire de 2n triangles pour n sommets, le stockage des erreurs nécessite l’allocation d’un espace mémoire de 4n valeurs d’erreurs. En revanche, les approches en arbres quaternaires définissent la métrique d’erreur sur les sommets et nécessite seulement le stockage de n valeurs d’erreurs. Les métriques d’erreurs basées sur l’utilisation d’une distance verticale (approximation géométrique simple) ont été citées dans les articles [ EKT01 , Paj98a , SS92 ] et [ Ger99 ]. D’autres plus appropriées, dépendantes du point de vue telle que la métrique d’erreur calculée en fonction de la distorsion dans l’espace écran, sont discutées dans [ LKR+96 , DWS+97 ]. Par ailleurs, les métriques basées sur la saturation d’erreur sont présentées dans [LP01 ] et [ BPS+04 ]. En pratique, pour la visualisation de vastes terrains, la projection dans l’espace image d’une erreur géométrique d’approximation est plus efficace, que celle exprimée dans l’espace objet. Dans [ DWS+97 ], il a été observé que la métrique d’erreur doit être hiérarchiquement monotone pour garantir des approximations délimitées. Les techniques RTIN [ EKT01 ] et RQT [ Paj98a ] (dans l’espace objet), aussi bien que SOAR [LP01 , LP02 ] (dans l’espace image) fournissent de telle métrique d’erreur géométrique monotone.

1.5 Conclusion

Nous avons vu, tout au long de ce chapitre, que l’évolution du matériel a engendré la succession de plusieurs classes d’algorithmes de simplification, en multi-résolution, d’un maillage représentant un terrain. Cette simplification a été dictée par la limitation de l’espace mémoire, l’incapacité du matériel graphique à afficher une triangulation dense, ainsi que le besoin de produire un rendu interactif. La première classe d’algorithmes a tenté de contourner ces contraintes en pré-calculant les différents blocs constituant le terrain sur plusieurs niveaux de détails statiques. Ainsi, au moment du rendu, les blocs sont assemblés et affichés en fonction du point de vue. Cependant, l’assemblage induit un coût de calcul supplémentaire et le maillage produit ne s’adapte pas complètement à la surface initiale. La seconde classe d’algorithmes est apparue suite à l’évolution du matériel en terme d’espace mémoire et capacité de calcul. Ce qui a permis à ces algorithmes de produire, au moment de l’exécution, une triangulation conforme adaptative. Toutefois, le matériel graphique présentait toujours des limitations en terme de capacité d’affichage, imposant ainsi à ces algorithmes la production d’une triangulation de taille minimale.

- 30 - Chapitre 1 : Techniques de simplification des terrains

La dernière classe a était engendrée par la révolution qu’a connue le matériel graphique, au début des années 2000. En effet, devant l’évolution de la rapidité de calcul et de communication du GPU, le CPU présente souvent un goulot d’étranglement. Ce qui a amené ces algorithmes a proposé de n’effectuer que des pré-calculs au niveau du CPU et de balancer le maximum de traitements au GPU du fait qu’il soit devenu programmable. Cependant, cette évolution n’exclue pas le besoin de simplification surtout lorsqu’il s’agit d’afficher des terrains de grandes étendues à forte résolution. Après avoir survoler les algorithmes qui traitent l’aspect géométrique du rendu de terrains, nous allons consacrer le chapitre suivant aux modèles d’habillage qui permettent d’améliorer le réalisme des scènes affichées.

- 31 -

Chapitre 2 Modèles d’Habillage Chapitre 2 : Modèles d’habillage

Chapitre 2 Modèles d’habillage

Les terrains sont très présents en synthèse d'images. Dès lors qu'une scène extérieure doit être représentée, un modèle de terrain est nécessaire. Cependant, la surface des terrains présente certaines caractéristiques particulières. En premier lieu, leur paramétrisation n'est pas aussi difficile que dans le cas général. En second lieu, les terrains nécessitent d'habiller des régions de très grande taille, lesquelles peuvent être vues de près comme de loin. En effet, ils représentent souvent des zones de plusieurs dizaines de kilomètres carrés (plus encore pour les simulateurs), mais la résolution de détails nécessaires peut être aussi précise que quelques centimètres si le point de vue est proche du sol (par exemple un marcheur ou un véhicule terrestre). Le terrain est le plus souvent vu à la fois de très près et de très loin (horizon). Notons cependant que seule une petite partie du terrain est visible à chaque instant dans le champ visuel. La principale difficulté réside donc dans la quantité de données, tant du point de vue du stockage que de celui de la création. A travers ce chapitre, nous allons présenter quelques définitions et concepts liés au placage des textures sur les surfaces géométriques standard. Ensuite, nous présenterons quelques travaux sur le chargement progressif de textures permettant de répondre au problème crucial de savoir quelles parties d’une texture sont utiles et à quelle résolution. Pour plus de détail sur les modèles d’habillage pour la synthèse d’image, la thèse de Lefebvre [Lef05] constitue une excellente référence.

2.1 Placage de texture standard

Le placage de texture est le modèle d'habillage le plus répandu. Il est utilisé dans les simulateurs, les jeux vidéo, mais également dans les logiciels de rendu réaliste. Il constitue, aujourd'hui, un composant de base de la synthèse d'image [ HS93 ]. Il est donc important d'en détailler et d'en analyser les mécanismes et les limitations : c'est précisément le but de cette section.

2.1.1 Principe

Le placage de texture a été introduit par Catmull [Cat74]. L'idée principale est d'associer une image à deux dimensions, appelée texture, à une surface géométrique. L'apparence de la texture est définie dans un espace de référence : l'espace texture. La correspondance

- 32 - Chapitre 2 : Modèles d’habillage entre l'objet et la texture est définie par la paramétrisation de la surface géométrique. On associe à chaque point de la surface un point de l'espace texture (voir section 2.1.2), appelé coordonnée de texture ( u,v). La paramétrisation permet de lire directement dans la texture la couleur correspondant à un point quelconque de la surface. La texture est ainsi appliquée à la surface de l'objet, comme illustré sur la figure 2.1.

Figure. 2.1 – Placage de texture. La géométrie ( à gauche) est associée à une texture (au milieu) via une paramétrisation qui définit une coordonnée dans la texture pour chaque sommet du maillage triangulaire. Il est dès lors possible de peindre la texture sur la géométrie (à droite).

2.1.2 Paramétrisation planaire

Cette section discute les différentes approches utilisées pour attacher un espace texture 2D à une surface. On se place ici dans le contexte des surfaces représentées par des maillages triangulaires. Le problème est donc d'associer une coordonnée dans le plan (coordonnée de texture) à chacun des sommets du maillage. Cette coordonnée sera linéairement interpolée sur les triangles lors du rendu, ce qui permettra d'obtenir une paramétrisation continue de leur intérieur. Au delà de quelques cas triviaux (voir section 2.1.2.1), la paramétrisation d'une surface est un problème difficile qui motive encore aujourd'hui de nombreuses recherches. Ce sujet trouve des applications dans d'autres domaines, tels que la simplification de maillages et la mise en correspondance de formes. Nous ne proposons pas ici une analyse détaillée, mais nous nous attachons plutôt à décrire les approches les plus courantes et leurs liens avec le problème de l'habillage de surface. Le lecteur intéressé par les techniques de paramétrisation en général est invité à consulter l'état de l'art de Floater et Hormann sur le sujet [ FH05 ].

2.1.2.1 Cas triviaux

La paramétrisation planaire est facile sur quelques types de surfaces. Par exemple, les surfaces planes (sols, murs), cylindres et cônes peuvent être paramétrés sans distorsions. En fait, toute surface développable peut être mise à plat sans distorsion. Il existe un autre cas largement répandu : les terrains, qui sont des surfaces quasi- planaires. La cartographie tire avantage de cette propriété en les représentant vus de dessus. Les coordonnées ( x, y) fournissent alors une paramétrisation efficace du terrain.

- 33 - Chapitre 2 : Modèles d’habillage

On considère généralement que la distorsion due à la pente est négligeable. Les terrains sont d'ailleurs souvent représentés par des cartes de hauteur: un maillage triangulaire régulier est construit à la surface du plan (chapitre 1). Les sommets du maillage prennent leur troisième coordonnée en échantillonnant la carte de hauteur (figure 2.2). Il s'agit certes d'un cas particulier, mais correspondant à une application très largement répandue (simulateurs, jeux).

Figure. 2.2 – Représentation d’un terrain par une carte de hauteur. Le terrain est représenté par un maillage triangulaire régulier. La carte de ha uteur est utilisée pour lire la coordonnée z des sommets. Les coordonnées des sommets dans le plan définissent une paramétrisation de la surface dont la distorsion est généralement ignorée, car faible.

2.1.2.2 Paramétrisation de surfaces quelconques

Afin d'associer une image 2D à une surface, il faut déplier la surface sur un plan, qui représente l'espace texture. Dans le cas général, ceci ne peut se faire sans introduire de distorsions ou de replis. Un repli ( foldover ) désigne le cas où deux parties distinctes de la surface sont associées à une même zone du plan et donc de l'espace texture. En conséquence, le même aspect se trouve répété sur les deux parties de la surface. Il est connu que l'on peut éviter les replis si une surface est homéomorphe à un disque : il est alors possible de la déformer pour la transformer en un disque. Pour obtenir cette propriété, il faut souvent introduire une ou plusieurs coupures dans le maillage. Par exemple, une sphère ne possède pas de bordure et ne peut donc pas être mise à plat sur un plan sans introduire de replis. L'introduction d'une coupure rend la surface homéomorphe à un disque et une mise à plat sans replis devient possible. Il reste néanmoins à trouver une transformation minimisant les distorsions. Deux types de distorsions peuvent être observées : les distorsions angulaires et les distorsions métriques. Les distorsions angulaires apparaissent lorsque les angles ne sont pas conservés par la paramétrisation : les angles entre les arêtes des triangles sur la surface ne seront plus les mêmes une fois le maillage mis à plat. Les distorsions métriques apparaissent lorsque les distances ne sont pas conservées : les longueurs des arêtes des triangles ne seront plus les mêmes une fois le maillage mis à plat. Un résultat connu [ AR60 ] démontre qu'une paramétrisation planaire conservant les distances n'existe que si la surface est développable (i.e. cylindre, cône), ce qui n'est pas le cas de la plupart des surfaces manipulées en synthèse d'images. Ces distorsions sont souvent indésirables dans le cas du placage de texture. La texture possède une résolution uniforme : la quantité d'information

- 34 - Chapitre 2 : Modèles d’habillage

(résolution par unité d'aire) est constante. En conséquence les distorsions d'aire ou d'angle produisent des défauts visuels à la surface de l'objet : certaines parties de la surface possèdent plus de détails que d'autres. Aplanir la surface de manière satisfaisante implique donc de pouvoir introduire des coupures et de minimiser les distorsions.

2.1.2.3 Mise à plat de surface à bordure unique

De nombreux travaux [HAT+00, DMA02] se sont intéressés à minimiser les distorsions lorsque le maillage est homéomorphe à un disque. Si ce n'est pas le cas, le maillage doit être prédécoupé, par exemple par l'utilisateur à l'aide d'un outil d'édition. Sheffer et Hart [SH02] ont proposé une méthode permettant d'automatiser la coupure du maillage. La paramétrisation est ensuite créée avec l'une des méthodes précédentes. La figure 2.3 présente un maillage coupé puis paramétré avec cette approche. Leur algorithme dissimule les coupures dans des zones peu visibles du maillage triangulaire. Notons cependant, que l'introduction des coupures nécessite de modifier la géométrie puisque les sommets le long de la bordure doivent être dédoublés.

Figure. 2.3 – Mise à plat de maillage triangulaire avec une bordure unique. Après avoir été découpé (coupure en bleu sur le modèle à gauche) le maillage est mis à plat en minimisant les distorsions.

2.1.2.4 Atlas de texture

La notion d'atlas de texture a été introduite par Maillot et al . [MYV93]. Le principe est de découper le maillage en différentes parties distinctes, à la manière des patrons utilisés pour la confection de vêtements, puis de paramétrer chaque partie indépendamment. Les différentes paramétrisations sont ensuite regroupées, en les disposant côte à côte dans le plan. Cette approche permet de réduire les distorsions en relâchant les contraintes imposées par une paramétrisation globale [BVI91]. Les distorsions sont échangées contre l'introduction de discontinuités dans la paramétrisation (figure 2.4). Des travaux plus récents ont permis d'améliorer et d'automatiser l'algorithme [SSG+01, CMR+98, LPR+02]. Notons que Carr et Hart [CH02] proposent de pousser la notion d'atlas à l'extrême en paramétrant chaque triangle indépendamment. Un des points difficiles, avec les atlas, concerne l'empaquetage des différentes parties paramétrées dans un rectangle de taille minimale

- 35 - Chapitre 2 : Modèles d’habillage

(problème équivalent à la minimisation des chutes de tissu dans la confection de vêtements). En effet, l'image utilisée pour le placage de texture est rectangulaire. Ce problème est NP- complet dans le cas général. Il est similaire au problème d’ordonnancement de tâches, connu sous le nom de strip packing .

Figure. 2.4 – Atlas de texture. Différentes parties du modèle sont paramétrées séparément. Les sous-parties sont ensuite regroupées dans une même texture.

2.1.2.5 Paramétrisations sous contraintes

Les travaux présentés précédemment s'attachent à paramétrer le maillage triangulaire en tenant compte uniquement de ses propriétés géométriques. Néanmoins, il est parfois souhaitable d'effectuer la paramétrisation en fonction des données contenues dans la texture. Par exemple, l'utilisateur dispose de la photographie d'un visage et souhaite la mettre en correspondance avec un maillage existant. Il faut alors faire correspondre les éléments géométriques (i.e. les yeux, la bouche, ...) avec le contenu de la texture (la photographie ou dessin). Des techniques de paramétrisation sous contraintes ont été développées dans ce sens [GGW+98, Lév01, DMA02, KSG03]. Elles permettent à l'utilisateur de guider le système, en introduisant des contraintes de positionnement. Ces contraintes ne peuvent être respectées qu'au prix de l'introduction de distorsions supplémentaires.

2.1.3 Stockage des données de texture

La texture appliquée à la surface par le placage de texture est représentée sous la forme d'une image rectangulaire à deux dimensions stockée en mémoire. Les éléments de la texture sont appelés texels (pour texture elements ). Lorsque la texture stocke des couleurs, chaque texel est un triplet (rouge, vert, bleu). Une quatrième valeur, nommée alpha, est souvent ajoutée ; elle permet de stocker un attribut supplémentaire, généralement un coefficient d'opacité. Il permet par exemple de mélanger plusieurs couches de textures appliquées sur une même surface. En outre, les textures servent aussi à stocker d'autres

- 36 - Chapitre 2 : Modèles d’habillage attributs : perturbations de normales ( bump maps ) [Bli78], repères locaux [Kaj85], éclairage (lightmaps ), etc.

2.1.4 Accès aux données de texture

Durant le dessin à l'écran, l'algorithme de rendu connaît les coordonnées de texture des points de la surface. L'algorithme de 1 interpole les coordonnées de texture définies en chaque sommet par le biais de la paramétrisation. L'interpolation n'est pas linéaire car il faut tenir compte de la projection perspective. Sans cela, des effets de glissement de la texture à la surface de l'objet apparaissent [HM91]. Les texels sont considérés au centre des cases de la grille formée par l'image dans l'espace texture. L'accès le plus simple aux données consiste à renvoyer la couleur du texel le plus proche du point d'échantillonnage. Lorsque l'algorithme de dessin souhaite connaître la couleur au point ( u, v), l'indice ( i, j) du texel dans le tableau stocké en mémoire est calculé par 2 (i, j) = (u, v) . Malheureusement, ceci produit un champ de couleur discontinu et, lorsque la surface est proche de l'écran, la grille due à l'utilisation du texel le plus proche devient visible. On parle alors de pixelisation . La section suivante décrit une méthode permettant de supprimer cet effet indésirable. Cependant, dans la situation inverse (point de vue éloigné), il existe un autre défaut visuel majeur connu sous le nom d’aliasing 3.

2.1.5 Interpolation

Afin de supprimer les effets de la pixelisation , on considère les texels comme les points de contrôle d'une fonction continue. L'idée est de reconstruire localement une fonction lisse lorsqu'un point est échantillonné à une position arbitraire dans la texture. Ceci permettra de supprimer la grille et les défauts visuels qui lui sont associés. La plupart des systèmes de rendu implémentent à cette fin un schéma d'interpolation, généralement l'interpolation bilinéaire (figure 2.5). L'idée est de considérer non pas un seul texel , mais les quatre texels encadrant le point d'échantillonnage. La couleur est déduite de la position du point dans le carré formé par ces quatre texels . Ce principe est illustré sur la figure 2.5. Cette figure montre également l'amélioration de la qualité obtenue en utilisant l'interpolation bilinéaire. D'autres schémas d'interpolation sont bien sûr possibles, comme l'interpolation bi-cubique , mais elles mettent en jeu plus de texels et sont donc plus lentes.

1 Une fois les triangles sur l'écran, un algorithme de remplissage donne une couleur à chacun des pixels situés en leur intérieur. Cette conversion entre représentation vectorielle et pixels est appelée rasterisation. 2 L'espace texture est souvent normalisé de manière à ce que les coordonnées de texture soient comprises dans l'intervalle [0,1[x[0,1[. Dans ce cas, pour une image de taille (l,h),(i,j ) = ( ul ,vh  ) .

3 Aliasing : Il s'agit d'un « grouillement » de couleurs qui se manifeste sur les faces obliques ou lorsque les objets s'éloignent (voir section 2.2.1).

- 37 - Chapitre 2 : Modèles d’habillage

Figure. 2.5 – Exemple d'interpolation linéaire. A gauche : Texture appliquée sans interpolation. Au milieu : Texture avec interpolation bilinéaire. A droite : Le centre du pix el se projette en F dans la texture. La couleur du point A est linéairement interpolée entre les texels T 00 et T 01 . La couleur du point B est linéairement interpolée entre les texels T10 et T 11 . La couleur au point F (point d'échantillonnage) est linéairem ent interpolée entre A et B. Sans interpolation, la couleur de F aurait été la couleur du texel le plus proche : T 11 .

2.1.6 Limitations du placage de texture

La plupart des limitations rencontrées avec le placage de texture proviennent à la fois de la difficulté à paramétrer les surfaces et de la structure de donnée très simple employée pour représenter le contenu (image rectangulaire de résolution uniforme). Comme nous l'avons vu en section 2.1.2, les méthodes de paramétrisation doivent en effet découper les surfaces en différentes sous parties afin de réduire les distorsions (atlas de texture). Malheureusement, distorsions et discontinuités introduisent toutes les deux différents types de problèmes que nous décrivons ci-après.

2.1.6.1 Gaspillage de mémoire

- Bordures. Un premier problème apparaît sur le contour des paramétrisations. Nous avons vu que le contour du maillage dans l'espace texture est souvent quelconque. Or, la texture est stockée sous la forme d'une image rectangle. Ceci implique que l'ensemble des texels entre la bordure de la paramétrisation et le rectangle de la texture sont gaspillés (voir figure 2.3). Lorsque la texture est de haute résolution, le gaspillage peut devenir conséquent.

- Distorsions. Quelle que soit la qualité de l'algorithme de paramétrisation, il existe une distorsion résiduelle. Ceci est d'autant plus vrai que l'algorithme tente de ne pas découper la surface ou que des contraintes de positionnement sont imposées. En conséquence, la densité de la texture à la surface n'est pas constante (par exemple, 1cm 2 de surface correspond à une aire variable dans la texture). Certaines zones affichent moins d'informations que d'autres. Or, si l'utilisateur souhaite une résolution minimale garantie, il deviendra obligatoire d'augmenter globalement la résolution de

- 38 - Chapitre 2 : Modèles d’habillage

la texture afin de compenser la perte due à la distorsion. Ceci afin d'atteindre la résolution souhaitée dans les zones de distorsion maximale.

- Discontinuités. Comme nous l'avons vu précédemment, les méthodes de paramétrisation minimisent les distorsions en découpant la surface, parfois en plusieurs parties (atlas de texture). Une fois la surface découpée, les différentes sous-parties doivent être regroupées dans le rectangle correspondant à la texture stockée en mémoire, de manière à minimiser l'espace vide. Malheureusement, il n'existe pas de regroupement éliminant totalement les espaces vides dans le cas général. De plus, ce type d'optimisation est connu pour être un problème NP-complet (problème de strip-packing). Il est donc résolu par des heuristiques [Rem96], qui permettent néanmoins de trouver de bonnes solutions. Ces espaces vides gaspillent eux aussi de la mémoire. Ce gaspillage peut devenir important, surtout lorsque la résolution globale de la texture augmente.

2.1.6.2 Interpolation et discontinuités

Lors de l'interpolation linéaire, l'algorithme suppose que les texels voisins à l'écran sont également voisins dans la texture. En conséquence, si une discontinuité est introduite par la paramétrisation (atlas ou bordure), un à trois des texels voisins peuvent être dans la zone non définie de la texture. La couleur des espaces vides va alors déborder dans la texture lors de l'affichage. Une solution partielle consiste à colorer une bande d'au moins un d'épaisseur dans la texture autour des bordures. Ceci permet d'ajouter le texel manquant lors des interpolations linéaires.

2.1.7 Extensions du placage de texture

Plusieurs travaux apportent des extensions à l'algorithme standard de placage de texture, notamment en ce qui concerne l'encodage des données. Ils ont été principalement menés dans le contexte des applications interactives, pour lesquelles les limitations d'espace mémoire sont plus fortes. Ils portent sur la réduction de la taille occupée en mémoire par les textures, via des algorithmes de compression du contenu, mais également en adaptant localement la résolution de stockage aux données. D'autres travaux proposent des schémas d'interpolation et de stockage permettant de représenter plus fidèlement certains aspects de surface.

2.1.7.1 Compression de texture

Les méthodes de compression de textures doivent permettre un accès aléatoire rapide. Ceci exclut les algorithmes séquentiels de compression tels que LZW ou RLE (Run Length Encoding). La compression est donc généralement effectuée sur les texels ou sur de petits blocs de texels . Beers et al . [BAC96] proposent une méthode basée sur la quantification des données. De petits blocs de pixels (typiquement 2x2) sont remplacés par un index dans un

- 39 - Chapitre 2 : Modèles d’habillage dictionnaire. Celui-ci contient des blocs représentant au mieux les blocs d'origine. Il s'agit d'une compression avec perte. Des méthodes de compression destructives sont également disponibles dans les cartes accélératrices (algorithme ST3C). Même si des taux de compression non négligeables peuvent être atteints, ils ne permettent pas toujours de réduire suffisamment la taille des textures tout en préservant une qualité acceptable.

2.1.7.2 Textures Adaptatives

Les textures adaptatives permettent de varier localement la résolution de stockage en fonction de l'utilisation de la texture. Heckbert [Hec90] propose un modèle de textures hiérarchiques pour stocker des informations lumineuses le long des surfaces. Les données sont stockées dans une grille hiérarchique 2D (arbre quaternaire). Fernando et al . [FFB+01] utilisent également une approche hiérarchique pour stocker, dans une texture, une carte d'ombres ( shadow map ) représentant la scène vue depuis une source de lumière. Kraus et Ertl [KE02] proposent une structure de données différente pour permettre de limiter le stockage d'espace vide dans une texture 2D ou 3D (méthode également décrite par Mc-Cool [Coo02]). Leur approche présente l'avantage d'être bien adaptée aux cartes accélératrices actuelles et est donc très efficace. L'idée est de recouvrir l'espace texture d'une grille régulière, appelée grille d'indirection. Chaque case de la grille peut être vide, ou contenir un pointeur vers une imagette stockée dans une seconde texture, appelée texture de référence (voir figure 2.6). Celle-ci stocke de manière compacte de petites images carrées. Lorsque l'on souhaite accéder aux données, il faut tout d'abord déterminer dans quelle case de la grille d'indirection le point d'échantillonnage se trouve. Si la case est vide, la couleur choisie pour le fond est retournée. Autrement (la case contient un pointeur), la position du point dans la texture de référence est calculée à partir du pointeur, puis un accès dans la texture permet de retrouver la bonne couleur.

Figure. 2.6 – Compression des vides. La texture initiale est découpée par une grille. La texture de référence contient uniquement les cases non vides. La grille d'indirection permet de recomposer la texture d'origine. Ses cases sont soit vides, soit contiennent un pointeur (pour des raisons de lisibilité, les pointeurs des cases marquées de trois points ne sont pas représentés).

Le problème de cette méthode est qu'elle complique l'interpolation linéaire puisque les indirections modifient les voisinages. Les indirections ont en fait le même effet que des

- 40 - Chapitre 2 : Modèles d’habillage discontinuités dans la paramétrisation, avec la différence notable qu'ici la géométrie n'est jamais modifiée. De plus, le filtrage de la texture devient également plus difficile (voir section 2.2). En conséquence, des défauts visuels apparaissent lors de l'affichage de l'objet. Ceci nous permet de constater que des structures de données à peine plus complexes qu'un stockage dans un tableau pose déjà de réels problèmes.

2.2 Filtrage

Le filtrage permet d'adapter les données générées le long de la surface par le modèle d'habillage à la résolution de l'image. En effet, l' aliasing se produit quand les éléments de couleur générés par le modèle d'habillage sont plus denses que les pixels de l'écran. Chaque pixel de l'écran ira alors sélectionner un seul de ces éléments de couleur : de l'information est perdue. L'habillage généré est sous échantillonné par les pixels de l'écran. Des effets de moiré et de grouillement de couleurs apparaissent. Ceci est illustré sur la figure 2.7. Comme l' aliasing introduit des basses fréquences parasites et est un phénomène instable, il est très visible et dégrade la qualité des images et des animations. Le filtrage consiste à pré-traiter le signal (la texture) pour qu'il puisse être correctement échantillonné par les pixels de l'écran.

Figure. 2.7 – Effets d' aliasing . A gauche, un modèle de personnage est recouvert d'un damier. Cette image possède suffisamment de résolution et aucun aliasing n'est visible. Au milieu : dans le cadre, on peut voir un rendu de faible résolution (reproduit en plus grand à côté). Les pixels de l'écran ne peuvent capturer correctement le motif du damier qui est de trop haute fréquence, et de l' aliasing apparaît. A droite : dans le cadre le même rendu de faible résolution, mais en utilisant un algorithme de filtrage. Dans cette image, le filtrage élimine les trop hautes fréquences. L'effet d' aliasing n'est plus visible ; on ne voit plus que la couleur moyenne.

2.2.1 Origine du problème

L' aliasing se produit car les pixels sont considérés comme des points sur l'écran. La scène n'est donc échantillonnée que sur ces points particuliers : on ignore ce qui se passe entre deux pixels. Dans le cas d'un appareil photographique (ou de l'oeil), plusieurs rayons lumineux participent à la couleur des éléments photosensibles de la pellicule. Ceci provient du fait que les éléments photosensibles ne sont pas des points : ils ont une surface non nulle. Tout rayon lumineux est pris en compte par l'un ou l'autre des éléments sensibles (on ne perd pas d'information). En somme, les éléments sensibles intègrent sur un petit

- 41 - Chapitre 2 : Modèles d’habillage domaine spatial plus qu'ils n'échantillonnent. C'est pour cette raison que les photographies ne souffrent pas d' aliasing , contrairement aux images de synthèse. Une des approches pour éliminer l' aliasing consiste donc à traiter les pixels non pas comme des points, mais comme de petits éléments à la surface de l'écran.

Figure. 2.8 – Les pixels sont influencés par un morceau de la surface. A gauche : La grille représente les pixels de l'écran. Chaque pixel contient un morceau de la surface dont la couleur est définie par le modèle d’habillage. En bas à droite : Gros plan sur le contenu de quelques pixels de l'écran.

Considérons maintenant une surface habillée (texturée), affichée à l'écran. Supposons que le modèle d'habillage forme une grille de couleur sur la surface (ce qui est le cas de la plupart des modèles générant des données à une résolution fixe). Lorsque la surface s'éloigne de l'observateur, plusieurs éléments de couleur sont inclus dans la zone couverte par un unique pixel de l'écran, comme illustré sur la figure 2.8. Pour filtrer le résultat, la couleur du pixel devrait tenir compte de l'ensemble des éléments de couleur du morceau de surface l'influençant (il faut en faire la moyenne).

2.2.2 Sur-échantillonnage

Une approche classique du filtrage, le sur-échantillonnage, consiste à générer des images de plus haute résolution que désirée, puis à réduire la résolution à l'aide d'un filtre. Ce filtre va permettre de simuler la contribution de plusieurs rayons lumineux : tout se passe comme si l'on avait considéré plusieurs échantillons par pixel au lieu d'un seul. Si ce type d'approche est générique, il n'élimine cependant pas complètement l' aliasing : il ne fait que repousser la limite à laquelle il se produit. Les surfaces obliques ou éloignées pouvant générer des fréquences arbitrairement élevées, de l' aliasing sera toujours visible. Dans le cas des modèles d’habillage, et en particulier du placage de texture, il est possible de traiter le problème à la source, en filtrant les trop hautes fréquences directement dans la texture ; opération qui de plus peut être accélérée par un pré-calcul comme nous allons le voir par la suite.

- 42 - Chapitre 2 : Modèles d’habillage

2.2.3 Filtrage pour le placage de texture 2.2.3.1 Principe

Plutôt que de considérer le problème sur l'écran, on cherche en général à résoudre le problème dual : Le pixel, considéré carré sur l'écran, est (anti-) projeté dans l'espace texture. L'empreinte du pixel dans l'espace texture permet de déterminer quels sont les texels contribuant à la couleur du pixel. La forme de cette empreinte dépend de la projection perspective, de la position de la surface, mais également de la paramétrisation. Déterminer l'empreinte du pixel et intégrer les contributions des différents texels étant très coûteux, on souhaite ne pas avoir à le faire au moment du rendu. Les chercheurs se sont donc attachés à trouver des approximations raisonnables, qui permettent autant que possible d'effectuer les traitements coûteux en pré-calcul. L'état de l'art de Heckbert [Hec86] sur le placage de texture détaille plusieurs de ces techniques. La plupart des algorithmes de filtrage font l'hypothèse que le contenu de la texture est continu (pas de discontinuité comme dans les atlas de texture). Ils ignorent également le fait que certaines parties de la texture peuvent devenir invisibles selon le point de vue et supposent généralement que l'empreinte du pixel à une forme prédéterminée (carré, rectangle, ellipse, etc.).

2.2.3.2 Algorithme de MIP-mapping

Différentes méthodes ont été proposées pour approcher l'empreinte du pixel et effectuer rapidement l'intégrale sur les texels concernés. Nous présentons ici l'algorithme le plus couramment utilisé : l'algorithme de MIP-mapping introduit par Williams [Wil83]. « MIP » signifie multum in parvo , c'est à dire « multiples dans un même espace ». Ceci fait référence aux multiples éléments de couleurs (ici des texels ) pouvant être contenus dans un même pixel de l'écran. Dans cette méthode, l'empreinte du pixel dans la texture est approchée dans l'espace texture par un carré aligné sur les axes. L'idée est de pré-calculer l'intégrale pour des empreintes carrées de différentes tailles alignées sur une grille. Lors du rendu, une empreinte carrée est estimée pour le pixel, et l'intégrale sur cette empreinte est reconstruite à partir des intégrales pré-calculées. Afin de permettre un filtrage rapide, la texture est supposée avoir une taille en puissance de deux et est stockée sous la forme d'une pyramide de Gauss (voir Figure 2.9). Chaque niveau de la pyramide est deux fois moins large que le précédent et correspond à une version filtrée de l'image précédente. Le filtre utilisé est souvent une simple moyenne, mais des filtres plus évolués peuvent être choisis. Le premier niveau de la pyramide est la texture originale, le dernier niveau a une résolution de 1x1 texel. Cette organisation demande environ 33 % d'espace mémoire supplémentaire, ce qui est généralement acceptable au vu du gain en qualité. Pour une empreinte de pixel d'une taille donnée, on reconstruit l'intégrale comme suit. La taille de l'empreinte est utilisée pour déterminer à quelle résolution, ou niveau de la pyramide, l'information doit être lue. La taille idéale se situe entre deux niveaux. Une interpolation linéaire est alors effectuée entre les contributions des deux niveaux.

- 43 - Chapitre 2 : Modèles d’habillage

Figure. 2.9 – Pyramide de MIP-mapping. La pyramide contient la texture à plusieurs résolutions. Chaque niveau est deux fois plus petit que le précédent. Un pixel d'un niveau contient la couleur moyenne des quatre pixels correspondant au niveau précédent.

Chaque niveau est traité comme une texture ordinaire (leur résolution est adaptée au pixel, puisqu'ils sont sélectionnés par l'empreinte). La couleur dans chaque niveau est donc donnée par l'interpolation bilinéaire du placage de texture. Il faut donc effectuer trois interpolations : une dans chaque niveau de la pyramide, puis une entre les deux niveaux (d'où parfois l'appellation, , d'interpolation tri-linéaire ). La taille de l'empreinte du pixel peut être déterminée en estimant les dérivées partielles de la paramétrisation (u(x, y),v(x, y)) en fonction du repère écran (x, y).  ∂u ∂v   ∂u ∂v  Les deux dérivées partielles recherchées sont :  ,  et  ,  .  ∂x ∂x   ∂y ∂y 

Cette estimation peut être calculée de différentes manières : - En examinant la coordonnée de texture utilisée par les pixels voisins dans l'écran, il est possible de déduire le nombre de texels utilisés entre deux pixels. Il s'agit en fait d'une estimation numérique des dérivées partielles. - Selon l'algorithme utilisé, cette information peut être directement disponible, analytiquement. Par exemple, un algorithme de rasterisation effectue l'interpolation des coordonnées de texture. Il calcule donc directement leur variation entre les pixels. Dans les deux cas, on obtient une information de longueur selon deux dimensions : l'axe des abscisses et l'axe des ordonnées de l'écran. 2 2  ∂u  2  ∂v  2  ∂u   ∂v  Les deux longueurs concurrentes sont :   +   et   +   .  ∂x   ∂x   ∂y   ∂y 

- 44 - Chapitre 2 : Modèles d’habillage

L'algorithme de MIP-mapping considérant l'empreinte du pixel comme étant carrée et alignée sur les axes, il faut utiliser ces deux informations pour estimer la taille du carré. Si l'on choisit la plus grande variation, la texture sera trop filtrée dans une direction. En conséquence on ne verra pas d' aliasing mais l'image perdra en netteté. Si, au contraire, on choisit la plus faible variation, l'image gagnera en netteté, mais il restera de l' aliasing . Ce réglage peut être laissé au programmeur via un paramètre de biais.

2.2.4 Note sur la qualité de filtrage

Il est important de souligner que le filtrage est effectué avant tout pour éliminer l' aliasing , en particulier lorsque celui-ci est instable et introduit des variations dans l'image lors des déplacements du point de vue. Cependant, aucun des algorithmes de filtrage utilisés dans les applications interactives ne produit un résultat strictement correct, car aucune des hypothèses faites n'est strictement applicable partout. Par exemple, considérons le cas d'une bosse sur un terrain ayant une face rouge et une face bleue, la face bleue étant du côté visible. L'algorithme de filtrage choisi est l'algorithme de MIP-mapping. Lorsque le point de vue s'éloigne de la bosse, tout en continuant à regarder la face bleue, la couleur des pixels va glisser vers le violet. Ceci résulte du fait que la visibilité n'est pas prise en compte lors du filtrage. Cependant, bien que la couleur soit fausse, aucun aliasing temporel n'est introduit : la couleur change continûment. Il est donc relativement difficile pour l'utilisateur de repérer ces erreurs.

2.3 Modèles d’habillage pour les applications interactives 2.3.1 Cartes accélératrices

Les processeurs graphiques (GPU) des cartes accélératrices récentes offrent une grande souplesse de programmation. Ils permettent d’implémenter directement sur la carte graphique des modèles d'habillage complexes et de les utiliser dans les applications interactives. La figure 2.10 présente une version simplifiée de la chaîne de traitement (pipeline ) d'une carte graphique programmable, ainsi que le flot de données et les parties programmables d'un processeur graphique. Le processeur graphique reçoit les données envoyées par l'application exécutée sur le CPU (processeur standard), à travers le driver (interface logicielle entre l'API graphique, OpenGL ou , et la carte graphique). Lorsque l'application envoie de la géométrie, celle-ci est tout d'abord traitée par le processeur de sommets. Ce processeur est programmable via un vertex program . Il permet d'effectuer des opérations sur les sommets de la géométrie et est notamment en charge de la projection des points à l'écran. La topologie de cette géométrie peut être dynamiquement modifiée par le processeur de géométries. Ce dernier est programmable via un geometry program . Ensuite, la géométrie vectorielle est envoyée à l'algorithme de rasterization (voir section 2.1.4) où elle est convertie en un ensemble de fragments. Les données disponibles en chaque sommet (couleur, normales, coordonnées de texture, ...) sont automatiquement interpolées. Les fragments

- 45 - Chapitre 2 : Modèles d’habillage sont ensuite traités par le processeur de fragments. Ce processeur est programmable via un fragment program . Il permet de calculer la couleur finale du fragment à partir des informations interpolées depuis les sommets et des informations stockées dans la mémoire texture. Si le fragment est accepté (test de profondeur Z-buffer ) il sera finalement affiché sur le pixel de l'écran correspondant.

Figure. 2.10 – Chaînes des traitements ( pipeline ) d’un processeur graphique (version simplifiée).

Si les processeurs graphiques sont programmables, il s'agit cependant d'un matériel spécifique, au comportement très différent des processeurs auxquels nous sommes habitués. Lors de la conception de modèles d'habillage il faut prendre soin de tenir compte de ce contexte. Ceci est d'autant plus vrai que des langages de programmation de plus en plus haut niveau apparaissent (langages de haut niveau Sh [MTP+04], Brooks [BFH+04], Cg [MGA+03], RTSL [PMT+01], Ashli (ATI), et langages d'API GLSL pour OpenGL et HLSL pour DirectX). Si ceci est vital pour permettre un niveau d'abstraction suffisant et donc de s'affranchir des spécificités de chaque constructeur et API (OpenGL / DirectX), il faut cependant tenir compte des particularités de l'architecture des processeurs graphiques si l'on veut les exploiter correctement :

- La précision des données stockées doit être minimale, et ce pour deux raisons. En premier lieu, augmenter la précision nécessite d'augmenter aussi le stockage. Les textures étant souvent de taille conséquente, il est vite possible de saturer la mémoire disponible. En second lieu, accéder aux données coûte cher. En fait, sur les dernières cartes disponibles l'accès est plus coûteux que les calculs [FSH04]. Minimiser la précision permet de réduire la bande passante et les défauts de cache, et donc les temps d'accès. Réduire la précision ne peut se faire trivialement sans introduire de nombreux défauts visuels. Il s'agit donc de concevoir les algorithmes afin qu'ils puissent produire des images de qualité malgré une faible précision de stockage (généralement 8 bits). La précision de calcul, quant à elle, est généralement de 32 bits (nombre à virgule flottante).

- 46 - Chapitre 2 : Modèles d’habillage

- L'accès aux données de texture entraîne un temps de latence. Il est cependant possible d'entrelacer calculs arithmétiques et accès texture afin que les calculs soient effectués en parallèle (à condition, bien entendu, que les calculs n'utilisent pas les données lues dans la texture). Ce type d'approche peut impliquer un gain de performance conséquent, mais ici aussi, il faut concevoir l'algorithme et les structures de données de manière à le rendre possible.

- L'architecture des processeurs graphiques est conçue pour traiter de larges flots unidirectionnels de données. Les informations de géométrie, texture et éclairage sont envoyées vers la carte qui doit alors produire une image sur l'écran. Récupérer l'image produite pour traitement par le CPU est malheureusement inefficace. Il ne s'agit pas uniquement d'une question de bande passante, mais véritablement d'un problème d'architecture : relire les données impose à la carte de finir les opérations en cours. Ceci a un peu le même effet qu'un saut de pointeur d'instruction sur un processeur : le pipeline de données est rompu. Il faut donc tenter de minimiser, ou mieux, d'éviter ce type d'opération. C'est pour cette raison que la plupart des travaux tentent de déporter l'ensemble d'un algorithme vers le GPU, d'autant que les transferts CPU vers GPU sont également assez lents.

- Les modèles d'habillage sont généralement implémentés avec les fragment program , exécutés en chaque pixel (voir figure 2.10). Si les programmes pouvant être écrits peuvent sembler génériques (sauts conditionnels et boucles sont disponibles), il est important de se rappeler que les cartes accélératrices traitent les pixels en parallèle. Ceci impose de fortes contraintes sur l'exécution et les performances des programmes écrits. Par exemple, un saut conditionnel ne sera efficace que si un large bloc de pixels (de l'ordre de 16x16) effectuent le même branchement. Dans le cas contraire, le traitement parallèle devra se synchroniser sur le pixel ayant effectué le plus long traitement.

Ne pas tenir compte de ces éléments résultera en de mauvaises performances. L'intérêt d'utiliser des cartes graphiques réside dans l'exploitation de leur architecture massivement parallèle et de leur capacité à traiter de grandes quantités de données. Par exemple, une carte graphique est très efficace pour effectuer un traitement simple sur l'ensemble des cases d'un tableau; opération généralement assez lente sur un processeur standard. L'accélération obtenue peut être conséquente; de plusieurs ordres de grandeur. Il s'agit donc de concevoir des algorithmes adaptés à cette architecture en tenant compte de ses spécificités.

2.3.2 Géométrie et applications interactive

La géométrie est généralement stockée sous une forme statique directement dans la mémoire accessible par le processeur graphique. Ceci permet de meilleures performances car la géométrie n'a plus besoin d'être transférée du CPU vers le GPU à chaque frame . Accéder ou modifier la géométrie stockée sur le GPU depuis le CPU est une opération lente.

- 47 - Chapitre 2 : Modèles d’habillage

De plus, la géométrie est généralement optimisée pour tirer profit des caches accélérant l'accès mémoire. Ceci permet des gains de performance considérables. Il reste néanmoins possible, d’une part, d'animer cette géométrie en utilisant des vertex program , qui sont exécutés par le GPU en chaque sommet et permettent de modifier leurs positions et leurs attributs à la volée. D’autre part, la géométrie peut être mise à jour en utilisant des geometry program , qui sont exécutés par le GPU en chaque primitive de dessin et permettent de supprimer, de modifier ou d’ajouter des primitives en fonction du besoin. Cependant la programmation des geometry program reste relativement rigide dans les GPU actuels. En effet, l’opération d’ajout de primitives est limitée par des schémas (processus) de modifications prédéfinis ainsi que par le nombre de ces primitives (voir la documentation sur les spécifications Nvidia, GPU série 8).

2.4 Chargement progressif de textures

Les textures utilisées par les applications modernes sont de plus en plus détaillées. Avec l'accroissement des capacités d'affichage et l'apparition de techniques de rendu mélangeant plusieurs couches de textures, les limites de capacité mémoire sont très vite atteintes. La plupart des systèmes de rendu imposent, en effet, de charger l'ensemble des données nécessaires à l'affichage d'une scène depuis tous les points de vue possibles. Néanmoins, le chargement progressif propose une alternative : dans cette approche, les données sont chargées uniquement au fur et à mesure des besoins, en fonction du point de vue courant et lorsque l'utilisateur se déplace. Un point de vue donné n'utilise pas l'ensemble des textures (certains objets sortent entièrement ou en partie de l'écran, se cachent les uns les autres). Quant aux textures utilisées, elles sont rarement entièrement visibles, et peuvent être nécessaires seulement à basse résolution si l'objet est loin. Afin que le chargement progressif ne pénalise pas les performances et n'introduise pas de ralentissements, il faut veiller à minimiser les transferts en chargeant uniquement les données utiles, en appliquant des stratégies de cache pour exploiter la cohérence temporelle et spatiale, et en ayant éventuellement recours à des algorithmes de compression. Dans le cas des terrains, plusieurs techniques de chargement progressif de textures, en rapport avec les algorithmes de simplification utilisés, ont été proposées. A savoir :

- L'architecture de Clipmaps introduite par Tanner et al . [TMJ98, LH04 ] utilise un centre d'intérêt dans l'espace texture et un rayon d'intérêt fournit par l'utilisateur pour déterminer les parties utiles de la texture. Les données sont chargées autour du centre d'intérêt avec une résolution plus faible au fur et à mesure que la distance au centre s'accroît. Au-delà du rayon d'intérêt, la texture n'est plus chargée. Malheureusement, déterminer le centre et le rayon d'intérêt de manière à englober le point de vue n'est pas toujours aisé. - Les MP-grids de Hüttner [Hut98] n'utilisent pas d'entrée utilisateur spécifique. La texture est découpée en une grille régulière dont les cases sont chargées progressivement.

- 48 - Chapitre 2 : Modèles d’habillage

Pour déterminer les parties utiles pour le point de vue courant, la géométrie associée à chaque case de texture est calculée. Un test géométrique (visibilité sur la boite englobante) est alors effectué pour déterminer si la case est utilisée et à quelle résolution. - Cline et al . [CE98] déterminent également les parties utiles de la texture à l'aide d'un calcul géométrique sur chaque polygone. Les polygones doivent être découpés en fonction des cases de texture pour le rendu. - Dollner et al . [DBH00] maintiennent une hiérarchie contenant à la fois le modèle géométrique du terrain et la texture.

Toutes ces techniques requièrent de nombreux calculs géométriques, sur CPU, avant de pouvoir réaliser l’opération de rendu, à chaque frame . Mais plus récemment, Lefebvre et al . [LDN04] ont proposé une architecture unifiée, sur GPU, permettant de déterminer la liste des textures nécessaires au rendu d’une géométrie arbitraire. Cette architecture, que nous avons adoptée et optimisée pour le cas des terrains (chapitre 3, section 3.2), sera présentée dans les sections suivantes.

2.4.1 Organisation des données de texture

Dans cette architecture, la texture est stockée comme une pyramide de Gauss, similaire à la pyramide utilisée par l'algorithme de MIP-mapping (voir section 2.2.3.2). Chaque niveau de la pyramide est découpé par une grille. Les cases des différents niveaux ont la même résolution (figure 2.11 (a)). Les cases filles d'une case de texture T sont les quatre cases correspondant à la même portion de texture au niveau suivant, plus détaillé, de la pyramide. T est la case parente. Le problème va donc être de déterminer les cases utiles au point de vue courant, de les charger progressivement, d'appliquer un cache sur les données et de pouvoir utiliser cette structure comme une texture standard. Bien que l’architecture proposée puisse gérer l'ensemble de la pyramide, le placage de texture standard est extrêmement efficace sur des textures de taille raisonnable. En pratique, l’architecture proposée s’active seulement sur les derniers niveaux de la pyramide, là où la résolution devient trop importante (typiquement supérieure à 2048x2048). Les premiers niveaux sont utilisés comme une texture habituelle (figure 2.11 (b)).

Point de vue courant Données de texture (a) (b) Figure. 2.11 – (a) Structure pyramidale de la texture. (b) L’architecture gère uniquement les derniers niveaux [LDN04] .

- 49 - Chapitre 2 : Modèles d’habillage

2.4.2 Vue d’ensemble

L’architecture fonctionne de la manière suivante : à chaque nouvelle image, les cases de texture utiles (devant être chargées) sont déterminées grâce au nouveau point de vue. Elles sont ensuite chargées de manière asynchrone. En effet, cette architecture peut être utilisée à tout moment comme une texture standard. Les cases de texture non encore chargées sont simplement remplacées par une version basse résolution de la texture. Elle est organisée en trois modules (figure 2.12) : Le premier module, la carte de chargement de texture détermine à partir du point de vue courant et de la géométrie quelles cases de la texture sont utiles (à tous les niveaux de la pyramide). Cette information est envoyée au second module, le cache de texture. Si la case est déjà présente dans la mémoire du cache (appelée mémoire de cases), elle est directement utilisée. Sinon, le cache lui réserve un emplacement et envoie une requête de chargement au dernier module, le producteur de texture. Celui-ci charge, ou produit, de manière asynchrone les données. Il peut simplement les charger depuis le disque, les décompresser directement en mémoire texture ou bien générer une texture procédurale.

Figure. 2.12 – Organisation de l’architecture [Lef05] . Le module carte de chargement calcule les cases de texture utiles à partir du point de vue courant et de la géométrie. Le cache de texture gère le stockage des cases de texture. Le producteur de texture produit les données de texture de manière asynchrone. Il lit ses données depuis un média de masse et les décode en mémoire texture. Les traitements effectués par le processeur graphique apparaissent en bleu.

Cette architecture présente plusieurs avantages. Tout d'abord, elle est transparente à l'utilisateur. Celui-ci envoie seulement le point de vue courant et la géométrie utilisée pour ce point de vue. Les calculs géométriques effectués pour la détermination des cases utiles sont tous faits par le processeur graphique, là où ils sont le plus efficaces. D'autre part, la notion de producteur de texture permet d'englober les textures standard, compressées et procédurales dans une même architecture. L'étape de production de texture peut être effectuée directement par le processeur graphique en mémoire texture : le transfert mémoire

- 50 - Chapitre 2 : Modèles d’habillage concerne alors uniquement des données compressées ou les paramètres d'une texture procédurale, minimisant ainsi les transferts coûteux entre mémoire centrale (CPU) et mémoire texture (GPU).

2.4.3 Carte de chargement de texture

La carte de chargement détermine quelles cases de la texture sont utiles pour un point de vue donné. C'est une pyramide de tableaux 2D. Chaque niveau correspondant à un niveau de la pyramide de texture. Une case d'un tableau correspond à une case de texture. Elle contient les informations sur l'utilisation de cette dernière par le point de vue courant. La figure 2.13 montre deux niveaux d'une carte de chargement dans un cas simple. Chaque case contient 3 valeurs : un marqueur d'utilisation, la valeur de niveau de détail vmin , la valeur de niveau de détail vmax . Si le marqueur est présent, la partie de la texture couverte par la case est utilisée par le point de vue courant. Ceci ne signifie par pour autant que cette case de texture doit être chargée. Cela va dépendre du niveau de détail auquel elle est utilisée. Les valeurs de niveau de détail (ou valeurs LOD) vmin et vmax correspondent aux niveaux de détail minimal et maximal, auxquels les pixels affichés à l'écran utilisent une case de texture. Une valeur LOD est comprise dans l'intervalle [0, k] où k est le nombre de niveaux gérés par la méthode (figure 2.11 (b)). Une case de texture représente elle-même un certain niveau de détail, déterminé par son niveau dans la pyramide. Si les valeurs v min et vmax encadrent le niveau n de la case dans la pyramide, (v min ≤ n ≤ v max ) alors la case est utile et doit être chargée.

Figure. 2.13 – Carte de chargement. L’ algorithme calcule l'ensemble des cases de texture utiles, marquées en vert (gris) dans les niveaux de la carte de chargement.

L’algorithme de calcul de la carte de chargement est conçu pour être implémenté sur les processeurs graphiques actuels. Il fonctionne sur des géométries arbitraires, possiblement animées et des paramétrisations quelconques. L'algorithme utilise une approche hiérarchique et produit une estimation conservative des cases de texture utiles. Il est facile à implémenter et suffisamment rapide pour des applications temps réel. Nous décrivons

- 51 - Chapitre 2 : Modèles d’habillage d'abord l'algorithme pour calculer un niveau donné de la carte de chargement, puis nous verrons comment calculer toute la pyramide à partir de quelques niveaux seulement.

2.4.3.1 Calcul d'un niveau de la carte de chargement

L'idée clé de l’algorithme est de dessiner la géométrie utilisée pour le point de vue courant dans l'espace texture, via la paramétrisation. Les coordonnées de texture des sommets sont utilisées pour le dessin, à la place de leurs coordonnées 3D. Le dessin est directement effectué dans le niveau de la carte de chargement, par le processeur graphique. Le niveau de la carte de chargement est représenté par une texture, et une opération de dessin dans une texture (render to texture ) est réalisée pour que le dessin soit fait dans la carte de chargement plutôt qu'à l'écran. La résolution d'affichage est choisie de manière à ce qu'un pixel affiché corresponde à une case du niveau de la carte de chargement. Les couleurs générées seront directement les valeurs stockées dans les cases d'un niveau de la carte de chargement (marqueur d'utilisation, v min , v max ). Les triangles sont donc dessinés dans le niveau de la carte de chargement en utilisant les coordonnées de texture des sommets. Lorsqu'un pixel est affiché aux coordonnées ( i, j), cela implique que le triangle en train d'être dessiné est texturé par une partie de la case de texture ( i, j) (figure 2.14). La case doit alors être marquée comme étant utilisée. La détermination des valeurs LOD (voir section 2.4.3.3) permettra de décider si la case est utile (si elle d oit être chargée ou non).

Figure. 2.14 – Carte de chargement pour un triangle. A gauche : Triangle texturé affiché à l'écran. A droite : Même triangle dessiné dans le niveau de la carte de chargement de résolution 4x4. Les coordonnées de texture sont utilisées pour le rendu. Les pixels dessinés correspondent chacun à une case de tex ture. Les cases utilisées sont marquées d'une lettre.

Pendant le dessin, on calcule également, en chaque sommet, les coordonnées écran ‘e’ auxquelles ils sont projetés à l'écran pour le point de vue courant. Ce calcul est effectué dans un vertex program , à l'aide de la matrice de projection du point de vue. Les coordonnées ‘e’ sont calculées en chaque sommet et interpolées en chaque pixel (voir section 2.1.5 ). Donc on a accès, en chaque case du niveau de la carte de chargement, aux coordonnées à l'écran d'un point du triangle utilisant la case de texture correspondante. Les

- 52 - Chapitre 2 : Modèles d’habillage coordonnées des sommets à l'écran seront utilisées pour éliminer les triangles non visibles depuis le point de vue courant, de calculer le niveau de détail auquel les cases de texture sont utilisées et de prendre en compte l'occlusion.

2.4.3.2 Elimination des faces cachées

Lors du calcul d'un niveau de la carte de chargement, tous les triangles de la géométrie sont potentiellement pris en compte. Or, les triangles non visibles dans le point de vue courant doivent être éliminés, soit parce qu'ils sont vus de dos, soit parce qu'ils sortent des bordures de l'écran. Pour éliminer les triangles en dehors du bord de l'écran, une opération de découpe (clipping ) est réalisée lors du dessin dans le niveau de la carte de chargement. La découpe des triangles est effectuée en fonction des coordonnées à l'écran des sommets , et non pas en fonction des coordonnées de texture utilisées pour le dessin. Cette opération peut paraître coûteuse, mais elle peut être effectuée directement par les processeurs graphiques, en sortie du vertex program . Par conséquent, seule la géométrie située dans le cadre de l'écran est effectivement dessinée dans la carte de chargement (figure 2.15). En ce qui concerne l’élimination des faces vues de dos, les cartes graphiques effectuent automatiquement cette opération, mais en considérant l'orientation des triangles dans l'affichage courant. Or, on devrait tenir compte de l'orientation des triangles depuis le point de vue courant (à l'écran), alors que le dessin se fait dans l'espace texture. Les normales définies en chaque triangle sont utilisées pour remédier à cette problématique.

Figure. 2.15 – Elimination des faces situées en dehors du rectangle de l'écran.

2.4.3.3 Calcul du niveau de détail

Nous avons vu que le niveau de détail, auquel les cases de texture sont utilisées, doit être calculé. Ce calcul est effectué dans un fragment program exécuté en chaque pixel lors du dessin du niveau de la carte de chargement. Rappelons que les valeurs provenant de plusieurs triangles sont ensuite combinées pour calculer les valeurs LOD minimales et maximales vmin et vmax . Le niveau de détail peut être déduit en examinant comment une case de texture est utilisée par les pixels de l'écran. Ce problème est très proche de celui que l'on tente de résoudre pour le filtrage, en cherchant l'empreinte des pixels de l'écran dans la texture (voir section 2.2.3.2). Ici, il s'agit non plus de déterminer l'empreinte du pixel de l'écran dans la texture, mais de résoudre le problème dual : il faut déterminer l'empreinte de

- 53 - Chapitre 2 : Modèles d’habillage la case de texture à l'écran. Une texture utilitaire 2D et sa pyramide de MIP-mapping est tout d'abord créée. Cette texture, appelée texture LOD, a une résolution de 2 k+1 x2 k+1 pixels où k est le nombre de niveaux de texture gérés par l’architecture proposée. La texture LOD a donc k niveaux de MIP-mapping. La couleur de tous les pixels d'un niveau est choisie de manière à correspondre au numéro d'un niveau du système proposé: les pixels du niveau i ont la couleur R = G = B = i. Un exemple de texture LOD est montré sur la figure 2.16.

Figure. 2.16 – Exemple de texture LOD pour k = 3 niveaux gérés par l’architecture.

Afin de calculer le niveau de détail d’une case, les coordonnées à l’écran des sommets sont utilisées pour accéder à la texture LOD. Comme cette dernière est filtrée par l’algorithme de MIP-mapping, les couleurs produites correspondront aux niveaux sélectionnés de la pyramide. Cette couleur est la valeur du niveau de détail à laquelle la case de texture est utilisée par le triangle : puisqu'on utilise les coordonnées écran pour accéder à la texture LOD et que l'on dessine dans l'espace texture, l'algorithme de MIP- mapping va estimer l'empreinte des cases du niveau de la carte de chargement sur l'écran (au lieu d'estimer l'empreinte des pixels de l'écran dans l'espace texture).

2.4.3.4 Prise en compte de l’occlusion

L’algorithme tel qu’il est présenté ci-dessus, surestime l'ensemble des cases de texture utiles. Cette estimation est bonne puisqu'une case est marquée comme utilisée uniquement si un triangle faisant face à la caméra et situé dans le rectangle de l'écran exploite cette case de texture. Cependant, l'occlusion n'est pas prise en compte : si un objet masque une partie de la texture, celle-ci sera tout de même déclarée visible. Gérer ce cas est important, notamment dans les scènes de type environnement urbain ou terrain. Pour éviter des calculs géométriques complexes et coûteux (le problème de visibilité est très difficile à résoudre de manière exacte et efficace), Lefebvre et al . [LDN04] proposent une solution certes approximative, mais simple à mettre en oeuvre. Il s'agit d'une approche similaire à l'algorithme de shadow buffer [Wil78]. Ils calculent, à chaque image, une carte de profondeur de la vue courante dans une texture de faible résolution. Rappelons que, lors du dessin dans le niveau de la carte de chargement, chaque case est associée à un point sur l'écran (voir section 2.4.3.1). On utilise cette coordonnée pour déterminer si les points sont

- 54 - Chapitre 2 : Modèles d’habillage visibles : leur profondeur à l'écran (coordonnée z) est alors égale à la profondeur lue dans la texture. Cependant le résultat n'est pas conservatif : il s'agit d'une approximation. En effet, tout comme l'algorithme de shadow buffer , cette méthode souffre d'erreurs numériques. D'autre part, seul un point est testé, alors que toute une partie du triangle peut être concernée : si le point est rejeté, toute la partie du triangle utilisant la case de texture est considérée comme non visible, ce qui peut être faux. Néanmoins, dans les applications interactives où la qualité peut être réduite au profit de la fluidité de rendu, ce choix est raisonnable. Dans le cas contraire, cette information de visibilité reste intéressante pour calculer une priorité de chargement.

2.4.3.5 Calcul de tous les niveaux d’une carte de chargement

Nous avons vu précédemment comment calculer un unique niveau d'une carte de chargement. Nous allons maintenant présenter comment calculer efficacement l'ensemble des niveaux. Une carte de chargement présente les propriétés suivantes : - Un niveau de la carte peut être déduit de tout autre niveau de plus haute résolution.

La valeur vmax (resp. vmin ) d'une case est alors calculée comme le maximum (resp.

minimum) des valeurs vmax (resp. vmin ) stockées dans les cases filles. Le résultat est conservatif par construction. - Dans les niveaux de haute résolution, seule une petite partie de la texture est utilisée par un point de vue donné : la résolution de l'écran limite la quantité de texture visible. Cependant, la zone visible n'est pas nécessairement continue. Cette zone, marquée comme utilisée, lors du dessin dans le niveau de la carte de chargement est appelée zone active . Les zones actives d'un niveau de haute résolution de la carte de chargement sont toujours incluses dans les zones actives des niveaux de plus faible résolution.

Ces deux propriétés nous permettent de définir l'algorithme de calcul suivant :

- Choisir la zone active de manière à couvrir toute la texture - Calculer le premier niveau (plus haute résolution) - Restreindre le dessin à la zone active - Pour (i = premier niveau + 1; i <= dernier niveau; i += N) Calculer le niveau (i + N) Restreindre le dessin à la zone active Pour (j=i + N-1; j >= i; j --) Calculer le niveau (j) à partir du niveau (j+1)

- 55 - Chapitre 2 : Modèles d’habillage

Cet algorithme calcule un niveau complet mais uniquement tous les N niveaux. Le rendu est restreint aux zones actives des niveaux précédents. Ceci requiert donc moins de calculs géométriques et de traitements par pixel que de dessiner l'ensemble des niveaux un par un. Le paramètre N permet de choisir la qualité de l'estimation. En pratique, le nombre de niveaux gérés par la méthode est souvent faible (chaque niveau étant deux fois plus grand que le précédent la résolution croît rapidement). Par conséquent, ils effectuent uniquement le calcul du dernier niveau (le plus grand) et déduisent les niveaux de plus faible résolution. Enfin, après que le calcul de tous les niveaux ait été effectué, la carte de chargement est stockée sous la forme de textures sur la carte graphique (une texture par niveau). Il faut récupérer cette information pour traitement sur le CPU, ce transfert peut être lent.

2.4.4 Génération des requêtes de chargement

Une fois la carte de chargement calculée et rapatriée, il faut générer les requêtes vers le cache de texture. Deux événements doivent être détectés : les cases devenant utiles et les cases qui ne sont plus utiles. Pour éviter un parcours complet de la carte de chargement (opération coûteuse) les propriétés hiérarchiques, une fois de plus, sont utilisées. Notons que, si une case à un niveau donné n'est pas utile, alors aucune de ses cases filles ne peut l'être. En effet, une case n'est pas utile si le vmax de cette case est en dessous du niveau de la case dans la pyramide. Autrement dit, une case parente aura été utilisée à sa place, ou bien la case n'est pas visible. Comme toutes les cases filles sont à des niveaux plus grands, elles ne peuvent être utiles. Pour générer les requêtes, le premier niveau de la carte de chargement (celui de plus faible résolution) est visité en premier. Une liste des cases utiles est alors créée. Seules les cases filles des cases présentes dans la liste sont visitées au second niveau. Une nouvelle liste est créée pour visiter le niveau suivant. Ceci continue jusqu'à ce que le dernier niveau soit atteint. Le résultat est la liste des cases utiles pour le point de vue courant. Les requêtes sont générées en comparant les cases utiles au point de vue précédent et les cases utiles au nouveau point de vue. Les cases qui ne sont plus utiles sont marquées comme libres dans le cache : elles pourront être effacées. Les cases nouvellement utiles sont soit déjà présentes dans le cache, soit seront générées par le producteur de texture. Notons que les cases de texture sont stockées dans le cache sous la forme de petites pyramides de MIP-mapping. Il n'est donc pas nécessaire de générer une requête de chargement pour une case parente utile si toutes ses cases filles sont également utiles, ce qui peut être facilement déterminé en vérifiant leurs valeurs LOD.

2.4.5 Cache de texture

Le rôle du cache de texture est de gérer le stockage des cases de texture utiles. Les cases sont effacées avec une approche LRU ( Least Recently Used ) : si le cache est plein et qu'une nouvelle case doit être chargée, la case qui n'a pas été utilisée depuis longtemps est remplacée. Si toutes les cases sont utiles au point de vue courant, la mémoire est saturée.

- 56 - Chapitre 2 : Modèles d’habillage

Dans ce cas, un mécanisme de priorité est défini pour déterminer les cases devant être éliminées en premier. Lorsque le cache reçoit une requête pour une case qui devient visible mais n'est pas présente dans la mémoire de cases, il effectue les opérations suivantes : - Un emplacement est réservé dans la mémoire de cases ; - Le pointeur correspondant à la case est marqué comme vide ; - Une requête est envoyée au producteur de texture. Dès que les données de la case sont générées par le producteur de texture dans la mémoire de cases, le pointeur est mis à jour.

2.4.6 Producteur de texture

L'objectif du producteur de texture est de générer la texture des cases déclarées nouvellement utiles. Il reçoit les requêtes de génération du cache de texture. Ces requêtes sont ajoutées à une file de priorité et gérées de manière asynchrone, selon un paramètre de bande passante fourni par l'utilisateur. Les données nécessaires sont lues depuis les médias de masse (réseau, disque dur, ...). Ces données sont ensuite envoyées vers la mémoire texture, dans une zone temporaire. A partir de ces données, le producteur de texture dessine directement la case de texture dans l'espace réservé en mémoire de cases. En pratique, ceci est effectué avec une opération de rendu dans une texture ( render to texture ). Un fragment program est utilisé pour calculer la texture à partir des données chargées. Ce programme prend en paramètre les coordonnées de la case dans la pyramide de texture et les données chargées. Le producteur de texture le plus simple copie simplement les données. Un producteur de texture plus complexe permet d'envoyer les données en mémoire texture sous forme compressée. Celles-ci sont alors décompressées par le fragment program exécuté par la carte graphique. L'intérêt est que les transferts de données coûteux (mémoire CPU vers mémoire texture) ne concernent plus que les données sous leur forme compressée.

2.5 Conclusion

Nous avons présenté dans ce chapitre quelques définitions, concepts et difficultés liés aux modèles d’habillage et plus précisément celui du placage de texture sur les surfaces géométriques. Nous avons vu également que la paramétrisation des surfaces décrivant un terrain est un problème facile à résoudre. Néanmoins, l’étendue de ces dernières nécessite des mécanismes performants de chargement progressif de textures. Cela est dû, d’une part, à la contrainte d’espace mémoire disponible sur les stations de travail, et d’autre part, à la nécessité de maintenir un taux de rafraîchissement élevé garantissant l’interactivité des scènes affichées. De ce fait, plusieurs techniques ont tenté de résoudre le problème de chargement progressif de textures mais toutes nécessitant des calculs sur CPU, à l’exception de celle proposée par Lefebvre et al . [LDN04] qui effectue ces calculs sur GPU. Ce qui permet de

- 57 - Chapitre 2 : Modèles d’habillage décharger le CPU, d’exploiter au mieux les capacités de calcul du GPU et d’éviter ainsi le goulot d’étranglement. Cependant, cette technique nécessite le rapatriement de l’ensemble des textures (cartes de chargement) du GPU vers le CPU pour analyse. Cette opération, s’effectue via un pipeline optimisé dans une seule direction (CPU → GPU), ce qui pénalise l’opération de rendu, particulièrement, lorsqu’il s’agit de cartes de chargement de grande taille (cas des terrains). La plate-forme, d’amplification de grands terrains par des objets naturels, que nous proposons et à laquelle nous consacrerons le chapitre suivant, s’appuie sur la technique de Lefebvre et al . [LDN04] en l’adaptant et l’optimisant pour le cas des terrains tout en résolvant, entre autre, le problème de rapatriement.

- 58 -

Chapitre 3 Amplification à la Volée de Très Grands Terrains par des Objets Naturels Chapitre 3 : Amplification à la volée de très grands terrains par des objets naturels

Chapitre 3 Amplification à la volée de très grands terrains par des objets naturels

Dans le domaine de la visualisation de terrain temps réel, la résolution des bases de données altimétriques et photographiques devient vite insuffisante lorsque le point de vue se rapproche du sol. Tout en limitant l'impact mémoire et le coût des calculs, on souhaite ajouter du détail géométrique et textural au sol, et faire surgir dès que nécessaire une géométrie verticale du sursol, végétale ou minérale, adaptée aux exigences du point de vue. L’obtention d’une réalité enrichie à partir d’ensembles de données restreintes est appelée amplification, terme mentionné pour la première fois dans [Smi84]. Les navigateurs terrestres actuels tels que Google Earth , World Wind ou GeoPortail sont conçus pour charger en streaming et afficher des modèles numériques de terrain texturés existants, sans aucune amplification. A l’inverse, un simulateur de vol comme Flight Simulator , sans fournir d’accès à de telles textures aériennes, implémente une forme d’amplification approximative par motifs de terrain génériques, judicieusement pavés et habillés. Une première tentative pour concilier les deux approches a été réalisée par la société française EMG qui publie Eingana en 2001. S’appuyant sur des bases de données de très faible résolution et divers outils d’analyse, leur algorithme Scaper (breveté) construit par amplification fractale un monde 3D habillé et habité assez réaliste. En effet, il serait illusoire de tenter de pré-calculer et de stocker des dizaines de millions d’objets végétaux ou minéraux pour enrichir un paysage de quelques kilomètres carrés seulement. C’est pourquoi les modèles de graines, apparus avec les premières simulations de végétation sur ordinateur, sont d’un grand intérêt pour la spécification et l’instanciation procédurales des scènes paysagères. Exploitant la forte redondance présente dans la nature, ils permettent de peupler un terrain à la volée sans stocker explicitement tous les objets du sursol et leurs propriétés. Ceci permet un gain considérable en mémoire, sans pour autant sacrifier la diversité ou la variété des résultats. Dans ce chapitre, nous détaillerons notre approche d’amplification [AMM07, AM09] basée sur la définition d’un modèle de graines, particulièrement adapté aux GPU. Ce modèle nous permet d'ajuster le niveau de détail de nombreux éléments du sursol, positionnés sur le terrain, en cohérence avec le contenu des images aériennes. Il tire profit du mécanisme d’instanciation présent sur les GPU actuels afin d’améliorer les performances de rendu. Ainsi le CPU se trouve complètement déchargé des tâches graphiques, ce qui lui

- 59 - Chapitre 3 : Amplification à la volée de très grands terrains par des objets naturels permet d’effectuer tous les calculs nécessaires dans un système global s’appuyant sur notre plate-forme, tels que ceux liés à l’intelligence artificielle, la communication, etc.

3.1 Vue d’ensemble

La plate-forme de rendu que nous avons développée permet de visualiser en interactif de grands terrains texturés et peuplés avec les objets constituant le sursol. Elle est organisée en quatre modules. Chaque module correspond à un passage d’une géométrie à travers le pipeline graphique (voir chapitre 2, figure 2.10). Le premier module TLM ( Tile Load Map ) ou carte de chargement est responsable du calcul, sur GPU, de la liste des textures nécessaires à l’habillage du terrain (voir section 3.2). Cette liste sera rapatriée sur CPU et comparée avec la précédente afin de tenir compte de la cohérence spatiale entre frames . Ainsi, le CPU peut charger, depuis un media de stockage, les textures utiles dans un cache GPU. Le second module effectue le rendu proprement dit du terrain texturé (voir section 3.3). Le module suivant permet de sélectionner et d’instancier les propriétés des objets du sursol peuplant la partie visible du terrain, en cohérence avec les textures couvrant le sol (voir section 3.4). Le dernier module effectue une opération de rendu, par instanciation, de tous les objets végétaux ou minéraux sélectionnés (voir section 3.5). Les deux premiers modules restent toujours actifs durant l’exécution de l’application. Ils permettent de visualiser, de près comme de loin, les parties visibles du terrain. Cependant, les deux autres modules s’activent seulement en s’approchant du sol, là où l’amplification devient nécessaire (figure 3.1). Par conséquent, une gestion efficace de la transition, au moment de l’apparition de la géométrie verticale, est indispensable pour éviter le popping (transition brutale entre les niveaux de détails).

Figure. 3.1 – Vue d’ensemble sur notre architecture. En fonction du niveau de détail de la géométrie décrivant le terrain à visualiser, celle-ci est habillée par des textures de différentes résolutions. De plus, en s’approchant du sol on fait surgir une géométrie verticale (amplification).

- 60 - Chapitre 3 : Amplification à la volée de très grands terrains par des objets naturels

En effet, indépendamment de l’algorithme utilisé pour générer, à chaque frame , la géométrie nécessaire au rendu du terrain, notre architecture est capable de lui associer la liste des textures utiles à des résolutions adéquates. Par conséquent, comme nous allons le voir dans le chapitre suivant, un algorithme de simplification est choisi parmi une panoplie d’algorithmes existants (voir chapitre 1) pour tester et valider notre architecture.

3.2 Adaptation de la carte de chargement

A chaque frame , l’algorithme de simplification envoie au GPU la géométrie nécessaire au rendu du terrain. Elle est stockée, dans un tableau de sommets ( Vertex Buffer Object ou VBO ) au niveau de la mémoire GPU. Comme l’illustre la figure 3.2, dans un premier temps, cette géométrie est rendue dans l’écran, à travers une opération de rendu off-screen . L’intérêt de cette opération est de récupérer, dans une texture, le contenu du depth-buffer . Le coût de calcul lié à ce passage est négligeable puisqu’il est effectué automatiquement par le GPU. La texture obtenue est exploitée, plus tard, dans le traitement de l’occlusion (voir section 3.2.3).

Figure. 3.2 – Module 1 : Calcul de la liste des textures utiles à l’habillage du terrain au frame courant. La géométrie du terrain est chargée dans un VBO au niveau de la mémoire GPU. Elle sera utilisée pour calculer la texture depth . Après, cette même géométrie est rendu dans une texture (appelée Tile load Map ou encore TLM) pour estimer le niveau de détail avec lequel chaque portion du terrain sera texturée. La TLM est ensuite analysée sous GPU pour en extraire la liste des textures utiles (GLM ou Ground load Map ) qui sera rapatriée sur CPU.

- 61 - Chapitre 3 : Amplification à la volée de très grands terrains par des objets naturels

Ensuite, cette même géométrie est projetée dans un espace image, représentée par une texture appelée TLM ( Tile Load Map ), afin qu’on puisse estimer le niveau de détail avec lequel chaque portion de la géométrie du terrain sera texturée. Concrètement, chaque pixel de la texture TLM correspond à une texture de taille carrée stockée sur disque, susceptible d’être chargée dans le cache GPU. En effet, habiller un terrain avec une texture unique n’est pas possible, surtout lorsqu’il s’agit de grands terrains. Par conséquent, la texture associée au terrain est souvent découpée, indépendamment de la géométrie, en une grille de petites textures de même taille couvrant la totalité de ce terrain ( figure 3.3 ).

Figure. 3.3 – Texture TLM mappée sur l’espace du terrain. A chaque portion du sol (sous texture), on lui fait correspondre un pix el de la texture TLM.

Chaque pixel de la texture TLM est représenté par quatre composantes (RGBA), où chacune est codée sur 8 bits. Chaque composante code l’une des variables suivantes : - lodMin : stocke le niveau de détail minimal des fragments projetés dans ce pixel. - lodMax : stocke le niveau de détail maximal de ces fragments. - pIndex : stocke l’indice de motif générique utilisé dans la phase d’amplification. - visible : indique la visibilité ou non de la portion de la géométrie projetée dans ce pixel.

Afin de cumuler ces informations (pour chaque fragment de la géométrie), le mode « max blending » est activé avant l’envoi de cette géométrie. Ce mode permet de retenir le maximum par composante entre la valeur déjà stockée et celle nouvellement calculée. Par conséquent, la variable « lodMin » doit être aussi considérée comme étant un maximum. Donc, au lieu de calculer « lodMin », nous calculons son complément « 1.0 – lodMin ». Notons que les valeurs numériques, quels que soient leurs types ( byte , integer , float ) sont normalisées (entre 0.0 et 1.0) en sortie du fragment program .

- 62 - Chapitre 3 : Amplification à la volée de très grands terrains par des objets naturels

3.2.1 Estimation du niveau de détail

A l’instar de la texture utilitaire 2D utilisée par Lefebvre et al . [LDN04] (Chapitre2, Section 2.4.3.3), pour estimer le niveau de détail de chaque fragment, nous utilisons une simple formule définie en fonction de la distance (D) entre ce fragment et la position de l’observateur. Pour déterminer le niveau n de détail d’un fragment, l’espace objet (le plan xz du terrain) est subdivisé en des cercles concentriques autour de l’observateur et dont l’évolution du rayon (d) est en puissance de deux (figure 3.4). Ainsi, le niveau n de détail est calculé de la manière suivante : 0 si D < d  n =    +  D  1 log 2   sinon    d 

Cela nous permet, d’une part, de préserver l’espace mémoire nécessaire au stockage de la texture utilitaire avec sa pyramide de Mip-Mapping , et d’autre part, de réduire le nombre de textures utiles à l’habillage du terrain. En effet, la première méthode est instable, peu adaptée au terrains et surestime le nombre de textures pour gérer la transition entre les niveaux de la pyramide (figure 3.1). Dans notre architecture, ce dernier problème est évité en calculant et en stockant, dans une phase de prétraitement, la pyramide de Mip-Mapping associée à chaque petite texture (voir section 3.2.7 ).

(a) (b)

(c) Figure. 3.4 – Calcul du niveau de détail. (a) Calcul radial du niveau de détail en utilisant la distance séparant chaque fragment de la position de l’observateur. (b) Représentation, en couleurs, des différents niveaux de détail. (c) Elargissement du cône de vision.

- 63 - Chapitre 3 : Amplification à la volée de très grands terrains par des objets naturels

3.2.2 Elimination de la géométrie en dehors du volume de vision

Pour éliminer la géométrie qui ne sera pas affichée, les six (06) plans (near , far , left , right , top , down ), délimitant le volume de vision, sont exploités pour écarter tous les fragments se projetant en dehors d e ce volume. Pour se faire, les coordo nnées écran sont calculées au niveau du vertex shader , puis rasterisées par le rasterizer et envoyées au fragment shader où le test s’effectuera. Il consiste à calculer pour chaque fragment le produit scalaire entre ces coordonnées écran (xe, y e, z e) et les coordonnées de chaque plan. Si l’une des six valeurs calculées est inférieure à 0, le fragment est écarté. Par conséquent, il ne sera pas dessiné dans la texture TLM . Cependant, un problème de bord surgira dès que l’observateur s’approche du sol. Auquel cas , les fragments qui sont projetés au voisinage de la position de l’observateur et aux limites du volume de vision (figure 3.4 (a), partie en rouge) ne sont pas toujours correctement dessinés au niveau de la TLM. Ce qui signifie, que la texture correspondant à l’un de ces fragments peut ne pas être chargée alors qu’elle est nécessaire à l’habillage d’une portion du terrain. Ceci se traduira, au moment du rendu, par des trous noirs sur les frontières de l’écran. Malheureusement, nous n’avons pas pu identifier l’origine précise de ce problème (même en le soumettant aux ingénieurs de Nvidia , concepteurs du processeur graphique), qui survient uniquement dans notre cas, c-a- d lors de la projection de la géométrie dans un espace texture. Car, jusqu’alors on n’effectuait que des projections dans l’espace écran. Après avoir étudier toutes les possibilités qui pourraient être à l’origine de ce problème, nous avons conclu que seul le rasterizer pouvait le provoquer. Malheureusement, l’algorithme implémenté au niveau de ce dernier est maintenu confidentiel par le constructeur. De ce fait, nous avons contourné le problème en élargissant légèrement le volume de vision d’une manière limitée en profondeur (figure 3.4 (c)).

3.2.3 Prise en compte de l’occlusion

Pour le cas des terrains, le traitement de l’occlusion présente un intérêt majeur car il nous permet d’éviter le chargement d’un nombre important de textures dont la géométrie sera occultée par une autre. En effet, en termes de temps de traitement, effectuer un passage pour calculer la texture depth est, de loin, moins coûteux que de charger ces textures depuis un média de stockage. De plus, étant donné que nous disposons d’un nombre limité de cases mémoires dans le cache GPU (voir section 3.2.8), le chargement des textures est restreint à celles qui sont utiles. Pour se faire, les c oordonnées ( xe, ye) sont utilisées pour accéder à la texture depth et récupérer la valeur de la profondeur. Si le fragment en cours de traitement est à une profondeur (ze) plus grande que cette valeur, il sera écarté. Nous allons voir plus loin dans ce chapitre que cette même texture depth sera utilisée pour éviter la visualisation des objets 3D du sursol cachés par la géométrie du terrain (voir section 3.4.4.1).

- 64 - Chapitre 3 : Amplification à la volée de très grands terrains par des objets naturels

3.2.4 Calcul pseudo-aléatoire des motifs génériques

En s’approchant du sol, là où l’amplification devient nécessaire (en fonction d’une distance empirique fixée par l’utilisateur), nous associons à chaque fragment retenu dans la texture TLM un numéro de motif générique « pIndex » calculé d’une manière pseudo aléatoire en fonction des coordonnées ( x, z) associées à chaque fragment. Il correspond à un numéro compris entre 1 et P (où P est le nombre de ces motifs). Ces motifs comportent des points définis par des coordonnées relatives ( xp, zp) pré-calculés et chargés, au lancement de l’application, au niveau de la mémoire GPU. Ils seront utilisés plus loin dans notre démarche pour sélectionner les objets 3D peuplant le sol (voir section 3.4.2). A ce niveau, seuls les fragments vérifiant les différents tests et se projetant correctement dans l’espace texture sont retenus ( visible = 1.0). Il reste à analyser la TLM pour en extraire la liste des textures utiles au point de vue courant.

3.2.5 Rapatriement de la texture TLM

Rapatrier la texture TLM, à chaque frame , depuis le GPU vers le CPU pour analyse est une opération très coûteuse. Cela est dû, d’une part, au fait que le pipeline graphique est optimisé dans la direction opposée (CPU →GPU), et d’autre part, la taille de cette texture risque d’être importante surtout lorsqu’il s’agit de grands terrains. Pour remédier à cette contrainte, nous proposons d’analyser cette texture sur GPU afin de ne rapatrier, au final, que la liste des indices correspondants aux textures utiles (où la taille de cette liste n’excède pas des dizaines d’octets). Néanmoins, comme nous allons le voir dans la section suivante, cela nécessitera un basculement depuis l’espace de rendu vers un espace de calcul parallèle (figure 3.2). Dans cet espace, le GPU est exploité comme une architecture fortement parallélisée à travers le langage CUDA ( Compute Unified Device Architecture ).

3.2.6 Calcul sous GPU de la liste des textures utiles 3.2.6.1 Exemple d’une texture TLM

Pour plus de lisibilité, nous allons considérer le cas d’une texture TLM de taille 8x8 afin d’illustrer le traitement effectué sur cette texture en phase d’analyse. La figure 3.5 illustre les différentes étapes nécessaires pour le calcul de la liste effective des textures à charger. Les valeurs numériques sur cette figure correspondent, respectivement, aux lodMin et lodMax calculés précédemment (voir section 3.2.1). Par ailleurs, les cases non visibles ( visible = 0) sont schématisées en croix. Les cases concernées par l’amplification ne sont pas prises en compte, pour ne pas encombrer l’exemple. Une case (qui correspond à une texture sur disque) est retenue seulement si le niveau L dans lequel on effectue le traitement (en commençant par celui de forte résolution, L=0) est compris entre lodMin et lodMax ( test du niveau de détail ). La construction du niveau L+1 de la texture TLM se fait de la manière suivante : le lodMin (resp. lodMax ) de la case parente est égale au minimum (resp. maximum) des lodMin (resp. lodMax ) des quatre cases filles.

- 65 - Chapitre 3 : Amplification à la volée de très grands terrains par des objets naturels

De plus, une case parente n’est pas retenue (même si la condition précédente est vérifiée) si leurs quatre cases files sont déjà retenues dans le niveau précédent.

Figure. 3.5 – Calcul de la liste des indices de textures utiles au point de vue courant.

Le résultat final de ce traitement est illustré sur la figure 3.5, où nous pouvons facilement imaginer que les différentes parties de la géométrie d’un terrain projetées dans la texture

- 66 - Chapitre 3 : Amplification à la volée de très grands terrains par des objets naturels

TLM , seront habillées par des textures de différentes résolutions (0 à 2 pour cet exemple). Concrètement, nous obtiendrons une liste ( cListGPU ) comportant, à la fois, les indices de textures utiles et beaucoup de valeurs NULL . L’apparition de ces valeurs est due à notre algorithme (voir section 3.2.6.2) qui procède, d’une manière parallèle, à l’analyse de la TLM.

3.2.6.2 Algorithme d’analyse de la TLM

Avant d’entamer la phase d’analyse de la texture TLM , cette dernière doit être transférée depuis l’espace de rendu vers l’espace CUDA au moyen d’un PBO ( Pixel Buffer Object )1. Ce transfert est indispensable du fait que les deux espaces ne sont pas visibles l’un par rapport à l’autre. Dans cet espace, le GPU est perçu comme une machine parallèle capable de lancer une grille de threads , effectuant le même traitement, sur des données différentes. Ce problème de programmation parallèle est connu dans la littérature sous le nom SIMD (Single Instruction Multiple Data ).

Chaque thread (Th i) opère sur quatre cases filles afin de calculer, dans un premier temps, les indices des textures à retenir. Ensuite, le thread prépare le niveau suivant en calculant les valeurs ( lodMin , lodMax , visible ) de la case parente qui seront stockées dans la case inférieure gauche qui lui correspond (figure 3.6). Ainsi, nous n’avons pas besoin d’allouer de l’espace mémoire pour stocker les différents niveaux de la pyramide (figure 3.5). En outre, le nombre de threads utilisés se réduit en puissance de deux (suivant les deux directions) à chaque passage d’un niveau à un autre. La figure 3.6, illustre les différentes étapes d’exécution de notre algorithme pour le cas d’une TLM de taille 8x8. Puisque l’exécution (dans l’espace CUDA ) se fait d’une manière parallèle, nous avons conçu notre algorithme d’analyse de telle sorte que les threads communiquent peu entre eux. Dans le cas contraire, nous serons obligés de synchroniser ces threads , chose déconseillée dans ce type de programmation afin de garantir une performance maximale. Néanmoins, la synchronisation est obligatoire lors du passage d’un niveau à un autre afin de s’assurer que les threads voisins ont bien mis à jour leurs cases parentes. Par ailleurs, en l’absence d’un mécanisme global de communication ( i.e . une variable globale partagée) entre les blocs de threads (voir Annexe II), nous définissons, sous GPU, une liste de taille égale au nombre de cases traitées. Cette liste est nécessaire au stockage des indices de cases retenues. Une case est dite retenue si elle vérifie le test du niveau de détail et/ou elle est concernée par l’amplification ( pIndex > 0). Les éléments de cette liste ( cListGPU , figure 3.5) sont mis à zéro à chaque frame , d’où l’apparition fréquente des valeurs NULL . En outre, le traitement des cases concernées par l’amplification s’effectue uniquement au niveau Niv0 (niveau de la plus forte résolution) de la pyramide (définie implicitement par notre algorithme). Désormais, cette liste doit être compactée pour ne rapatrier, sur CPU, que les valeurs non NULL .

1 Les PBO sont des structures de données disponibles au niveau du GPU utilisées pour accélérer le transfert (GPU →GPU, CPU →GPU, GPU →CPU)

- 67 - Chapitre 3 : Amplification à la volée de très grands terrains par des objets naturels

Figure. 3.6 – Exécution parallèle de l’algorithme d’analyse de la TLM .

3.2.6.3 Compactage des valeurs non NULL

Ce traitement consiste à regrouper les valeurs non NULL au début de la liste cListGPU . Comme l’illustre l’exemple de la figure 3.7, le traitement s’effectue d’une manière parallèle en trois étapes :

- Sélection des éléments non NULL : chaque thread effectue un test sur un élément de la liste cListGPU . Si la valeur de ce dernier est non NULL , l’élément qui lui correspond dans validList est mis à 1.

- Calcul des positions finales des valeurs non NULL : chaque thread calcule la valeur d’un élément de scanList (le premier est exclu) en additionnant son précédent à celui qui lui correspond dans validList .

- Regroupement des éléments non NULL : chaque thread teste un élément de cListGPU . S’il est non NULL , sa position finale est lue dans l’élément qui lui correspond dans scanList .

Figure. 3.7 – Exemple illustratif des différentes étapes utilisées pour compacter, sur GPU, les éléments non NULL d’une liste.

- 68 - Chapitre 3 : Amplification à la volée de très grands terrains par des objets naturels

A ce niveau, les éléments de cListGPU sont compactés et leur nombre est connu (la valeur de la dernière case de scanList + 1), il ne reste qu’à rapatrier ces valeurs au niveau du CPU. Ainsi, Ils seront décodés et comparés avec la liste précédente pour extraire, d’une part, la liste des indices de textures nécessaires à l’habillage du terrain, et d’autre part, la liste des textures concernées par l’amplification. Cette comparaison permet de tenir compte de la cohérence spatiale entre frames . Par conséquent, les textures déjà chargées au niveau du cache GPU ne seront pas re-chargées et la bande passante (CPU/GPU) est préservée.

3.2.7 Organisation des textures sur disque

La texture qui couvre la totalité du terrain est découpée, dans une phase de prétraitement, en plusieurs sous-textures pour faciliter son exploitation. Ce découpage est principalement adopté pour remédier à la contrainte de l’espace mémoire. Les stations de travail disposent souvent d’un espace mémoire limité face à une quantité colossale de données utilisées pour modéliser un grand terrain à une résolution satisfaisante. Malgré l’évolution fréquente du hardware en capacité de mémoire vive, cette contrainte persiste, du fait que le besoin en détails des scènes à visualiser ne cesse d’augmenter. Le découpage est soumis à plusieurs contraintes. Chaque sous-texture résultante, que nous appellerons plus tard tile (voir section 3.4), est représentée par une image de taille n x n (taille en puissance de 2). Choisir n grand se traduira par un gaspillage en espace mémoire du cache GPU. Il suffit qu’une partie d’un terrain soit visible pour que sa sous- texture soit complètement chargée, tandis que l’habillage ne nécessitera qu’une portion de cette dernière. En conséquence, l’espace du cache se trouve vite saturé. Par ailleurs, choisir n petit, signifie que le nombre des sous textures à charger augmente et par conséquent, le bus de transfert sera plus souvent sollicité, ce qui provoquera un goulot d’étranglement. D’où la nécessité de faire un compromis. En outre, pour pouvoir construire les autres niveaux de la pyramide (figure 3.1), le nombre des sous-textures doit être en puissance de 2 suivant les deux directions. Une sous-texture d’un niveau supérieur est construite à partir des quatre sous-textures filles. L’image obtenue couvre la même portion du terrain que ses quatre sous-textures mais à une résolution plus faible. Ainsi, à la tête de la pyramide on se retrouve avec une seule texture de taille n x n couvrant la totalité de notre terrain à une faible résolution. Ensuite, ces images seront indexées de la manière suivante : nous commençons par numéroter séquentiellement les sous-textures du niveau 0 (niveau de la plus forte résolution) de telle manière qu’à partir de la position d’une sous-texture dans la grille de découpage, on calcul facilement son indice. De la même manière, nous continuerons cette numérotation pour les autres niveaux de la pyramide. Finalement, pour chaque sous-textures de la pyramide, nous calculons sa propre pyramide de Mip-Mappping, augmentant ainsi sa taille initiale de ¾. En contrepartie, la gestion de la transition lors du passage (durant la navigation) d’un niveau à un autre est

- 69 - Chapitre 3 : Amplification à la volée de très grands terrains par des objets naturels gérée automatiquement (efficacement) par le GPU. Par conséquent, on perd légèrement en espace de stockage (bien évidemment après compression de ces textures) mais on gagne en qualité d’affichage et en temps de traitements.

3.2.8 Cache GPU

Le cache GPU est représenté, dans notre plate-forme, par une grande texture qui peut accueillir, d’une manière non contiguë, plusieurs tiles . D’ailleurs, sur les dernières générations de cartes graphiques ( G80 ou plus), nous pouvons aussi utiliser des tableaux de textures. Dans les deux cas de figures, il est impératif de définir un mécanisme qui nous permet de nous renseigner sur l’état du cache, des cases libres et de celles qui doivent être déchargées. Comme nous allons le voir plus tard (voir section 3.3), aucune correspondance directe n’est définie entre l’espace du cache et celui dans lequel on définit les coordonnées de textures associées à la géométrie du terrain. Ce mécanisme est défini sous CPU par une pile contenant, initialement, les indices des cases libres dans le cache. Au premier rapatriement de la liste des textures utiles, nous associons à chacune d’elles un indice dépilé. L’indice permet de calculer la position, dans le cache GPU, de chacune des textures à charger. Dans le frame suivant, la liste des textures rapatriée est comparée avec la précédente pour déterminer les cases qui doivent être déchargées (leurs indices sont empilés dans la pile) et à la même occasion, dépiler d’autres indices pour les textures à charger.

3.3 Rendu du terrain

Dans cette phase, les textures utiles à l’habillage du terrain sont chargées depuis un média de stockage vers leurs cases respectives dans le cache GPU (figure 3.8). Le transfert s’effectue au moyen d’un PBO , directement sur GPU, où les textures seront décompressées automatiquement. Rappelons que la géométrie du terrain réside toujours au niveau du GPU (voir section 3.2). Son affichage sur écran nécessite un simple appel d’une primitive de dessin. Désormais, il ne reste qu’à faire correspondre l’espace continu (où la géométrie du terrain est définie) avec celui du cache GPU (non contigu). Nous utilisons, à cet effet, une liste de taille égale au nombre de textures constituant la pyramide. Cette liste, qui sera mise à jour à chaque frame , stocke les indices des cases du cache où les textures ont été chargées. Au niveau du vertex shader , nous ré-estimons le niveau de détail (voir section 3.2.1), puis calculons les coordonnées de textures associées à chaque point géométrique. Ces deux informations seront utilisées pour déterminer, pour chaque fragment , sa position dans la pyramide des textures. Pour cela, une procédure de décodage d’un quadtree est définie sur GPU. Une fois le numéro de la case du cache (case stockant la texture utilisée par le fragment ) est déterminé, nous calculons pour ce fragment ses coordonnées relatives dans cette texture afin de lui attribuer une couleur.

- 70 - Chapitre 3 : Amplification à la volée de très grands terrains par des objets naturels

Figure. 3.8 – Module2 : phase de rendu du terrain.

Cependant, un problème survient avec les fragments se projetant aux bords des textures. En effet, pour attribuer une couleur à un fragment, le GPU échantillonne le texel en cours avec ses voisins pour calculer une couleur moyenne. Pour les fragments du bord, soit les texels voisins ne sont pas présents, soit ils appartiennent à une autre texture non voisine, du fait que l’espace cache est non contigu. Par conséquent, le résultat visuel qui sera obtenu retrace la grille de découpage effectué en prétraitement (voir section 3.2.7). Pour remédier à ce désagrément, la résolution du problème est anticipée en rajoutant aux différentes textures créées, les bordures nécessaires à un échantillonnage correct. Différemment, la résolution du problème sous GPU nécessitera une gymnastique complexe, dans l’espace cache, dont on peut se passer. Par ailleurs, pour augmenter le réalisme des scènes affichées par notre plate-forme, nous simulons de façon simpliste l’existence de nuages dynamiques. Nous utilisons pour cela une texture périodique transparente créée d’une manière procédurale et comportant quelques types de nuages. Cette texture est ensuite dupliquée en deux textures intercalées, l’une par rapport à l’autre, par une opération d’agrandissement. Les coordonnées utilisées pour accéder à la texture résultante ( multi-texturing ) sont calculées en faisant intervenir le temps et un facteur de vitesse. Ainsi, nous obtenons un rendu dynamique des nuages dont leurs apparences évoluent dans le temps. Au niveau du fragment shader , les coordonnées de textures sont utilisées pour accéder à la texture des nuages et récupérer la couleur se trouvant au dessus de la position où le fragment en cours est projeté. La couleur obtenue (comportant une couche de transparence) est mélangée avec celle du fragment (texture du sol) pour lui calculer sa couleur finale. De cette manière nous simulons l’ombre des nuages, qui se projette sur le

- 71 - Chapitre 3 : Amplification à la volée de très grands terrains par des objets naturels sol, au passage de ces dernièrs. Nous allons voir plus tard dans ce chapitre, que cette ombre sera de nouveau projetée sur les objets 3D du sursol.

3.4 Sélection, instanciation & regroupement des objets du sursol 3.4.1 Modèles de graines

Par définition, une graine représente un ensemble de propriétés utilisées pour l'instanciation d'un modèle géométrique de plante sur le terrain, telle qu'une position, une rotation, un facteur d'échelle, une couleur,...etc. On distingue trois niveaux de description: la graine simple, le groupe de graines et la méta-graine. Les objets visibles dans les textures aériennes (arbres, arbustes, roches) sont décrits par les deux premiers niveaux, tandis que les objets de petite taille (plantes, fleurs, tas de cailloux, feuilles mortes, brins d’herbe), non visibles et plus nombreux, peuvent bénéficier d’une description par méta-graine [DHL+98 , DCS+02 ].

- Une graine simple gère le placement d’un objet individuel du sursol (générique ou calculé). Elle est décrite par un vecteur de propriétés : espèce, position sur le terrain, et selon les besoins : taille, orientation, couleur, niveau de détail, etc.

- Un groupe de graines contient quelques objets très proches qui sont traités comme un seul objet à la sélection et au rendu.

- Une méta-graine est une graine de graines. Ses propriétés de base sont l’essence, la densité des objets qu’elle spécifie, et son rayon d’action propre, qui permet de l’activer localement de manière radiale. C’est un mode de description très économique : on peut la stocker efficacement au niveau des sommets géométriques du terrain de base, ou dans les textures associées, pour un accès direct en shader lors du rendu de la géométrie du sol. Un bénéfice commun aux groupes de graines et méta-graines est d’augmenter le degré d’instanciation et donc de diminuer le nombre de primitives graphiques.

Le positionnement à la volée des graines se fait d’abord dans le plan horizontal, puis par projection orthogonale sur le sol. Il est géo-spécifiquement déterminé : à chaque lancement de l'application, les mêmes graines apparaissent aux mêmes endroits. La distribution horizontale est traitée de deux manières : les graines filles des méta-graines sont localisées mathématiquement par des fonctions pseudo-aléatoires qui utilisent des variables spatiales, tandis que les graines simples et les groupes sont positionnés grâce à un pavage apériodique du plan utilisant des motifs de points pré-calculés (figure 3.9). D’autres fonctions pseudo-aléatoires servent à perturber les propriétés des graines (taille, orientation, couleur) pour obtenir des variations non redondantes et plus réalistes. Chaque espèce végétale obéit à des lois de distribution propres, mais aussi, à des lois régissant la symbiose avec d’autres essences, dont la complexité fait émerger des écosystèmes, qui dépasse le cadre de notre étude. Cependant, il est aisé dans un shader de prendre en compte certaines règles géographiques (altitude), climatiques (humidité),

- 72 - Chapitre 3 : Amplification à la volée de très grands terrains par des objets naturels saisonnières (neige en hiver, modification du feuillage,…), temporelles (croissance, vieillissement, disparition), car le modèle de graines accepte une paramétrisation adaptable au niveau de chaque graine. Au niveau collectif (méta-graines), l’ajout des règles botaniques et biologiques permet de synthétiser des distributions spatiales d’essences végétales. Dans notre plate-forme, nous avons utilisé le modèle de graine simple pour gérer le positionnement des plantes (plusieurs types d’arbres) sur le sol.

Motifs de points Couverture du sol Graines générées Figure. 3.9 – Génération de graines à partir des motifs de points et de la couverture du sol.

3.4.2 Motifs génériques

Le motif est la brique de base pour composer un paysage virtuel par tile : c’est une collection de points qui n'ont d'autres propriétés que leurs positions 2D (relatives aux tiles ) dans un plan horizontal. Ces points peuvent donner naissance ou non à des graines en fonction du contenu de la couverture du sol ( Land Cover Classification map ou LCC map ). Concrètement, un motif comporte un ensemble de points de coordonnées relatives ( x, y) et un indice représentant l'ordre dans lequel le point a été créé au sein du motif. Les coordonnées ( x, y) sont utilisées pour accéder au pixel correspondant dans la texture LCC associée au tile . Tandis que l'indice permet de calculer une position (dans une texture) où nous stockons la graine éventuellement générée à partir de ce point. Un point ne générant aucune graine est représenté par la mise à zéro de toutes les propriétés. La structure simpliste des motifs les rend efficaces pour simuler des écosystèmes dont la variété dépendra du nombre de motifs, du nombre de points par motif et des modèles de distribution utilisés. Ainsi, comme illustre la figure 3.10, pour peupler un paysage entier nous composons une série de motifs génériques que nous distribuons de façon apériodique sur notre grille régulière de découpage recouvrant le terrain (voir section 3.2.7). Des variations aléatoires ou contrôlées peuvent être introduites à ce niveau pour briser la stricte répétition des agencements génériques. L’utilisation des motifs présente plusieurs avantages: généricité, économie de stockage, facilité de manipulation sur GPU et envoi d’un nombre réduit de primitives à la carte graphique. Notons que ces motifs sont créés et chargés au niveau de la mémoire GPU au lancement de l’application dans des structures de données appropriées ( VBO ).

- 73 - Chapitre 3 : Amplification à la volée de très grands terrains par des objets naturels

Figure. 3.10 – Motifs de points ( patterns ) géo-spécifiquement distribués sur le terrain.

3.4.3 Pré-calcul de la couverture du sol

Le concept d’amplification à la volée du sursol s’oppose au pré-stockage des graines simples ou des groupes de graines dans une quelconque structure. Néanmoins, le placement des graines est contraint par les images aériennes, puisque les détails visibles qu’elles fournissent doivent être restitués précisément, sous peine d’incohérence spatiale lors de la navigation. Or, aucune méthode performante d’analyse de textures ne permet d’obtenir, en temps réel, la nature du sol en chaque pixel. Par conséquent, on a recours à une étape de pré-classification des images aériennes, qui repose sur l’utilisation des champs de Markov cachés [ Bla07, BLB+08 ]. Le résultat de cette classification est stocké dans des formats de texture facilement accessibles depuis le GPU. Chaque pixel de cette texture peut stocker soit un numéro de classe ( i.e. un identifiant d'une espèce végétale), soit un pourcentage de couverture de chaque classe sur ce pixel. La première méthode permet de traiter de nombreux classes différentes (2 n si on a n bits par pixel). La deuxième méthode ne peut traiter que C+1 classes (si on a C canaux par pixel, C = 4 pour une texture RGBA) mais permet un Mip-mapping trivial, contrairement à la première méthode. Or le Mip-mapping de la carte LCC est nécessaire si la végétation est visible sur une distance incluant plusieurs niveaux de détail (ce qui est le cas des arbres, visibles de très loin). Par conséquent, pour la première technique, la création d’une pyramide de textures LCC limitée aux k premiers niveaux de forte résolution est nécessaire (k est fixé en fonction de la distance d’amplification choisie par l’utilisateur).

3.4.4 Sélection, instanciation & regroupement sous GPU

L'objectif de cette étape est d'attribuer les propriétés nécessaires pour le rendu des plantes, de les faire varier pour créer de la diversité et de les regrouper pour une utilisation

- 74 - Chapitre 3 : Amplification à la volée de très grands terrains par des objets naturels massive de l' instancing 2. Il s'agit aussi d'écarter tous les points où il n'y a pas de plantes mais aussi les plantes cachées par la géométrie du terrain, ou encore éliminées par des contraintes d'écosystèmes. Ainsi, la bande passante est préservée et le minimum nécessaire de la géométrie décrivant les plantes visibles est envoyé à la carte graphique.

3.4.4.1 Sélections et instanciation des graines

Rappelons que les indices tiles concernés par l’amplification avec leurs numéros de motifs respectifs sont calculés par le premier module (voir section 3.2.6.3). Dans cette phase, une opération de rendu dans une texture est effectuée pour l'ensemble des motifs attachés aux tiles « à amplifier ». Cette texture est appelée texture de sélection ( Seed Load Map ou SLM , figure 3.11). Elle regroupe, dans l'ordre d'envoi des points, des graines générées à partir de ces points. Selon le nombre et la taille du codage de ces propriétés, plusieurs textures de sélection peuvent être utilisées. On parle alors d'une opération de rendu dans une MRT ( Multiple Render Targets ). Rappelons aussi que chaque point d'un motif possède une position relative ( x, y). Dans un premier temps, ces coordonnées sont utilisées pour calculer la position absolue ( X, Y, Z) du point sur le terrain. L'altitude Z est obtenue en consultant la texture d'élévation correspondant au tile en cours de traitement, c'est à dire au point ( x, y). L'accès à la texture LCC permet de révéler le type de plante à cet endroit du terrain, s'il y en a. Dans le cas contraire (sol nu), aucune graine n'est générée à partir de ce point (ce qui est représenté par un vecteur de propriétés NULL ).

Figure. 3.11 – Module 3 : sélection/instanciation des graines sous GPU (PASS 3). Module 4 : rendu final des plantes (PASS 4).

2 Instancing : dupliquer à l'identique la géométrie d'un objet autant de fois qu'elle sera sollicitée par un nombre défini par l'utilisateur.

- 75 - Chapitre 3 : Amplification à la volée de très grands terrains par des objets naturels

Dans ce qui suit, nous citons quelques règles de base à prendre en compte dans l’étape de sélection, mais bien évidemment la liste reste ouverte : - Un exemple de règles d'écosystèmes, qu'on peut déjà évoquer à ce niveau, est de ne pas générer de plantes au dessus d'une certaine altitude. Pour les points qui passent ce test, et qui correspondent à des plantes effectives, on compare la profondeur du point avec celle du terrain (disponible dans le depth buffer ) et on écarte tous les points qui sont cachés par la géométrie du terrain. On peut aussi écarter toute plante dont la projection de la boite englobante se trouve à l'extérieur de l'écran.

- Pour alléger la géométrie à envoyer au moment du rendu final des plantes, on définit plusieurs niveaux de détails par type de plante. Ces niveaux sont calculés, d’une manière radiale, en fonction de la distance entre la position de l'observateur et la position absolue de la gaine sur le terrain.

- On modélise la variété perçue dans la nature par deux paramètres : un facteur de mise à l'échelle et un angle de rotation. Ces deux paramètres permettent de faire varier la forme géométrique des plantes de même type et par conséquent, d'enrichir la scène à partir d'un nombre restreint de modèles.

- On peut aussi récupérer la couleur du sol, la normale et d'autres paramètres liés à la simulation de l'atmosphère pour faire varier l'apparence visuelle des plantes ( i.e. prise en compte de la texture des nuages).

Toutes ces propriétés sont ensuite stockées dans la texture (ou les textures superposées) de sélection suivant l'ordre d'envoi en s'appuyant sur l'indice du point dans le motif (figure 3.12). Il est à noter que la première composante de cette texture de sélection est réservée au type de la plante, défini par l'espèce et le niveau de détail de cette dernière.

Figure. 3.12 – Texture(s) de sélection contenant les graines générées (une graine = un type de plante avec ses différents attributs). Les cases colorées sont des graines, tandis que les cases en blanc représentent des points qui n'ont pas généré de graines.

- 76 - Chapitre 3 : Amplification à la volée de très grands terrains par des objets naturels

La figure 3.12 schématise le résultat de l'étape de sélection. La première remarque que l'on peut faire, en observant les couleurs des cases, est que la même plante peut apparaître plusieurs fois mais aussi en plusieurs niveaux de détails (couleur dégradée). La deuxième remarque intéressante est que la texture est creuse (présence de valeurs NULL). Donc, d'une part en regroupant les plantes de même type on doit pouvoir profiter d'une utilisation massive de la technique d'instanciation, et d'autre part, on pourra éviter d'envoyer de la géométrie là où il n'y a pas de plantes et, par conséquent, préserver la bande passante.

3.4.4.2 Regroupement par type de graine

Dans un contexte classique, il faut rapatrier la texture (ou les textures) de sélection pour analyse sur CPU afin de réaliser le rendu final des plantes. Mais, comme nous l’avons déjà évoqué, le pipeline graphique est optimisé dans la direction CPU →GPU. Cette opération s'avère très coûteuse dans un contexte de visualisation temps réel. Une autre alternative consiste à effectuer une opération de tri sur GPU, en se basant sur les types de plantes. Au final, on ne rapatrie sur CPU que le nombre d'occurrences de ces dernières. En 2007, Roger et al . [RAH07] ont mis en œuvre un algorithme permettant de trier et de compter, sur GPU, le nombre d'occurrence de données dans un flux. Cet algorithme a été adapté à notre contexte afin d'éviter la permutation des propriétés des graines lors de cette opération de tri. Donc, au lieu que l’algorithme effectue le tri directement sur la texture de sélection, ce tri est effectué dans une texture d'indirection codant les positions réelles des propriétés de la plante dans la texture de sélection (figure 3.13).

Figure. 3.13 – Regroupement par type de plante des données de la sélection dans une texture d'indirection codant les positions réelles dans la texture de sélection.

3.5 Rendu des objets du sursol

Dans cette étape, nous disposons, au niveau du CPU, du nombre d'instances par type de plantes. Du coté du GPU, dans le même ordre, nous disposons de la position des attributs, liés à chaque instance, dans la texture de sélection.

- 77 - Chapitre 3 : Amplification à la volée de très grands terrains par des objets naturels

Lors du rendu final des plantes, les attributs (position absolue, mise à l'échelle, rotation) propres à chaque instance, sont utilisés pour calculer la matrice de modélisation et de visualisation. Cette matrice est utilisée au niveau du shader pour positionner, orienter et mettre à l’échelle chaque instance de plante affichée sur le terrain. D'autre part, les attributs (couleur du sol, paramètres atmosphériques) sont combinés avec la texture de la plante afin de calculer la couleur finale de cette dernière. Par ailleurs, le rendu des plantes (i.e. les arbres) dans un contexte temps réel nécessite une représentation géométrique assez légère.

3.5.1 Rendu des arbres en temps réel

Grâce à des outils spécifiques comme ceux d’ AMAP ou Xfrog , on sait générer des modèles végétaux tridimensionnels très réalistes, en tenant compte de leurs comportements temporels et saisonniers. Mais leurs géométries complexes sont souvent inadaptées au rendu en temps réel de scènes très peuplées. Les chercheurs ont mis au point des représentations alternatives (à base d’images, de textures volumiques, ou de points) pour afficher ces objets avec nettement moins de polygones, tout en maintenant le maximum de qualité visuelle. Certaines techniques récentes fusionnent plusieurs représentations et bénéficient de leurs avantages respectifs. Par exemples :

- Le rendu par textures volumiques a été proposé par Meyer et al . [MN98] , puis amélioré par Decaudin et al . [DN04] grâce au concept de texcells , proche des motifs de points. Il permet de rendre plusieurs milliers d'arbres en temps réel. Néanmoins il est très difficile d'accéder aux objets individuellement, ce qui l’exclut pour le rendu des graines.

- La méthode de rendu à base de points proposée par Gilet et al . [GMN05] regroupe de bonnes idées et permet une gestion continue du niveau de détail. Elle réduit le nombre de points lorsque l'on s'éloigne et utilise la géométrie originale de l'objet lorsqu'il est très proche du point de vue. L’algorithme élabore un modèle de l'arbre à base de points, chacun d’eux recouvrant entièrement l’un de ses polygones. Il crée une hiérarchie par découpage récursif et regroupement des points proches. Pour le rendu, un tri séquentiel sur leur taille sélectionne les points dont l’empreinte projetée à l'écran est inférieure à quelques pixels. Un découpage de l'arbre en cases permet d'adapter localement et plus finement le niveau de détail. Enfin, un calcul rapide de l'auto ombrage de l'arbre en fonction de la « profondeur » du point apporte plus de réalisme. Néanmoins, l’algorithme reste mal adapté au rendu d'objets n'ayant pas la topologie d'un arbre (un rocher par exemple).

- Le billboarding simple est une méthode très utilisée dans les applications temps réel. A l’origine, elle propose de remplacer un ensemble de polygones par un seul, orienté face à l'utilisateur, sur lequel on projette une texture semi transparente représentant l’image de l’arbre pour un point de vue donné. Malheureusement les objets manquent de relief

- 78 - Chapitre 3 : Amplification à la volée de très grands terrains par des objets naturels

et de volume, même en utilisant deux polygones croisés ou des textures qui dépendent du point de vue.

- Les billboard clouds améliorent le réalisme en créant du volume, mais pas de l’épaisseur. Decoret et al . [DDS+03] ont proposé une méthode de simplification permettant la sélection d'un ensemble de plans ( billboards ) approximant la géométrie d’un objet. L'algorithme se décompose en 4 phases : construction d'un ensemble de plans, calcul d'une valeur de pertinence pour chaque plan, sélection des meilleurs plans, calcul des polygones de taille minimale et des textures recto verso représentant les billboards . La qualité de la simplification est déterminée par la distance maximale autorisée ε entre un plan et les sommets. Fuhrmann et al . [FMU05] ont amélioré plusieurs points de l'algorithme original pour le rendre plus efficace avec les arbres. En utilisant un petit ε, il obtient des modèles de quelques dizaines de billboards , pouvant se décliner en plusieurs niveaux de détail.

C'est cette dernière méthode (billboard clouds ) qu'on utilise pour représenter les différents types de plantes dans notre plate-forme.

3.5.2 Gestion de la transition (texture du sol / plantes)

L’utilisation de plusieurs niveaux de détails pour représenter le même type de plante, permet d’afficher une géométrie légère de cette dernière à partir d’une distance suffisante pour ne pas apercevoir sa brusque apparition. De plus, le fait de mélanger (à un certain pourcentage) la couleur de l’arbre avec celle du terrain (calculée en échantillonnant les pixels autour de la position de la plante) permet aussi de gérer cette transition. Enfin, la prise en compte de d’autres aspects atmosphériques ne fait qu’améliorer d’avantage cette transition.

(a) (b) Figure. 3.14 – Prise en compte de la transition (textures du sol—objets 3D du sursol). (a) Les arbres sont déjà positionnés alors qu’ils n’apparaissent pas distinctement sur la texture du sol. (b) Prise en compte d’effets atmosphériques.

- 79 - Chapitre 3 : Amplification à la volée de très grands terrains par des objets naturels

3.6 Conclusion

Dans ce chapitre, nous avons proposé une approche robuste sur GPU pour peupler à la volée de grands terrains texturés en temps réel avec des éléments de nature végétale ou minérale en s’appuyant sur une pré-classification texturale du terrain. L’approche proposée effectue, en premier lieu, une sélection des graines actives sur l’ensemble du terrain, en utilisant deux algorithmes de visibilité : l’un pour les motifs et l’autre pour les graines. Le couplage de ces deux algorithmes semble optimal compte tenu de l’architecture actuelle des GPU. Ensuite, l’algorithme de rendu final des objets 3D (objets du sursol) utilise efficacement les résultats de la sélection des graines pour positionner et diversifier leurs apparences géométriques et texturales, et cela indépendamment du choix que nous effectuerons sur cet algorithme. Toutefois, cette approche reste « pilotée » par un pavage apériodique de motifs aveugles. Car, aucune connaissance à priori sur le positionnement des motifs génériques (en fonction de leurs densités) n’est prise en compte. La plate-forme que nous avons développée, bien qu’optimisée sur G80 , reste ouverte aux futurs développements des GPU et des algorithmes manipulant la géométrie des terrains et les objets du sursol. Actuellement, elle est capable de visualiser une étendue terrestre comme celle de l’Algérie à une résolution satisfaisante. Cependant, le passage à une échelle planétaire nécessitera une adaptation du module de la carte de chargement. D’autre part, la mise en application nécessitera la mise à disposition de bases de données à grande échelle, ou une simulation de ces dernières. Néanmoins, nous allons présenter dans le chapitre suivant les résultats que nous avons obtenus en intégrant notre modèle de graines dans un moteur de rendu de la planète entière développé au sein de l’équipe EVASION de Grenoble.

- 80 -

Chapitre 4 Résultats et Discussion

Chapitre 4 : Résultats et discussion

Chapitre 4 Résultats et discussion

Dans ce chapitre, nous allons discuter les différentes étapes de notre démarche, en quantifiant et en précisant des détails d’implémentation pour que les développeurs puissent reproduire facilement notre plate-forme. Pour ce faire, le département Alpin de Haute-Savoie a été choisi comme un premier terrain d'expérimentation, en s'appuyant sur les données de la RGD73-74 : photos aériennes à 50 cm de résolution par pixel, modèle numérique de terrain (MNT) à 20m de résolution par point et une carte de classification de la couverture du sol ( LCC map ) à 1 m de résolution décrivant la végétation de la zone de Megève . Ensuite, nous allons présenter une généralisation de notre modèle de graines pour l’amplification de la planète entière en se basant sur les données de la NASA disponibles sur Internet : six modèles numériques de terrains de la terre à 500 m de résolution, et une carte de couverture du sol à 1 Km de résolution (décrivant la distribution de deux types d’arbres). Durant la phase de rendu, cette LCC est, elle-même, amplifiée en temps réel afin de parvenir à une résolution suffisante pour enrichir, à la volée, le sol. Dans ce cas, cependant, le moteur de rendu de terrain utilisé est celui développé par l’équipe EVASION de l’INRIA de Grenoble. Les langages de programmation utilisés pour implémenter nos algorithmes sont : - C++ et la librairie openGL pour la partie du code s’exécutant sur CPU, - GLSL (OpenGL ) pour la partie des , - CUDA (Compute Unified Device Architecture ) pour les algorithmes parallèles.

4.1 Prétraitement des données du terrain

Le premier terrain d’expérimentation, qui s’étale sur une superficie de 66 Km2, est représenté par un MNT à 16 m de résolution horizontale et 10 cm de résolution verticale. Il est stocké dans une texture de taille 4097 ×4097 pixels, où chaque pixel est codé sur une seule composante de 16 bits. De plus, nous disposons des ortho-photos-numériques de ce terrain à 50 cm de résolution. Ces ortho-photos correspondent à des images (ou dalles ) codant, sur 4 composantes (RGBA), les couleurs du sol. Chaque image a une taille de 3200 ×2400 pixels. Pour ce terrain, relativement petit par rapport à la planète entière, l’espace disque occupé par ces dalles s’élève à 60 Go. Par conséquent, stocker et gérer une telle masse de données dans un contexte de visualisation interactive est loin d’être une

- 81 - Chapitre 4 : Résultats et discussion tâche facile. Ceci justifie en partie notre orientation vers les algorithmes de chargements progressifs (Chapitre 3, section 3.2). Afin de préparer les données du terrain (plus précisément les dalles) pour qu’elles soient exploitables par notre plate-forme, nous avons développé plusieurs codes sources (en dehors de notre plate-forme) permettant d’effectuer les tâches suivantes : découpage des dalles, construction de la pyramide des textures, calcul des bordures, compression des textures, etc.

4.1.1 Découpage des dalles

Les dalles sont alignées et découpées en tiles de taille 512 ×512 pixels. Rappelons que cette taille doit être en puissance de deux ( i.e. 64, 128, 256, 512, etc.) pour que le Mip- mapping s’effectue d’une manière intuitive par le processeur graphique. Par ailleurs, notre choix s’est porté sur la valeur 512 pour que la taille de la texture TLM, définie sur GPU, soit raisonnable (pour cet exemple, la grille de découpage est de dimension 256 ×256 cases). En effet, dans notre première implémentation [ AMM07 ], l’analyse de la texture TLM s’effectuait au niveau du CPU et, par conséquent, nous avions intérêt à réduire la taille de cette texture pour pouvoir diminuer son coût de rapatriement. Les tiles obtenus sont enregistrés sur disque avec des noms qui codent les positions de leurs cases respectives dans la grille de découpage. Soit ( i, j) les coordonnées d’une case, l’indice de son tile est calculé comme suit : sizeTLM x j + i (ici, sizeTLM = 256).

Figure 4.1 – Exemple d’une grille de découpage 4x4 tiles .

- 82 - Chapitre 4 : Résultats et discussion

4.1.2 Construction de la pyramide des tiles

Les tiles composant les autres niveaux de la pyramide des textures sont calculés en utilisant l’un des filtres suivants : gaussien, quadratique , cubique , Mitchell , etc. En effet, chaque tile d’un niveau supérieur est calculé à partir des quatre tiles du niveau précédent. Par conséquent, la taille de la nouvelle grille se réduit d’un rapport de 2 (selon les deux directions) à chaque passage d’un niveau à un autre (figure 4.2). Toutefois, le calcul de l’indice du tile se fait de la même manière tout en cumulant ceux des autres niveaux.

- 83 - Chapitre 4 : Résultats et discussion toujours multiple de 4. En adoptant le même raisonnement, la taille de la texture au niveau 2 est de 130 ×130 pixels, non multiple de 4. Donc le mip-mapping ne fonctionnera pas sur ce niveau. De ce fait, nous nous limiterons à 2 niveaux lors de la création de la pyramide de mip-mapping associée à chaque texture du sol.

Figure 4.3 – Une texture du sol avec 4 bordures de chaque coté mip-mappée sur deux niveaux.

4.1.4 Compression des textures

L’objectif attendu derrière la compression des textures avec leurs pyramides de Mip- mapping est double. Il permet, d’une part, de réduire l’espace que peuvent occuper ces textures sur un média de stockage, et d’autre part, d’augmenter la vitesse de chargement et de traitement par le processeur graphique. Ainsi, dans un contexte pratique, le gain direct de cette opération est estimé à 5-10% des performances globales. Ce qui signifie que pour un même temps, le GPU serait capable de traiter plus de textures que dans le cas où nous n’utilisons pas de compression. Récemment, le constructeur des cartes graphiques Nvidia et la commission ARB de normalisation de l’ API OpenGL ont adopté un format de compression très efficace connu sous le nom de S3TC ( S3 1 Texture Compression ). Cette technique de compression, avec perte, permet de réduire de manière significative l’espace de stockage initial tout en préservant leurs qualités. Le tableau 4.1, résume les différentes variantes de cette technique avec leurs taux de compression respectifs. Pour illustrer notre démarche, nous avons opté pour une compression des textures du sol en utilisant la première variante, car c’est-elle qui offre le plus grand taux de compression (8 :1). De plus, la différence (en qualité) entre le résultat des différentes variantes n’est pas vraiment perceptible visuellement. Par ailleurs, nous ne pouvons pas utiliser le canal alpha pour coder l’indice de matière par pixel, puisque cette compression est destructive.

1 , Ltd

- 84 - Chapitre 4 : Résultats et discussion

DX10 Alpha pre- Compression FOURCC Description Texture Type Name multiplied? ratio DXT1 BC1 1-bit Alpha / Opaque N/A 8:1 Simple non-alpha DXT2 (none) Explicit alpha Yes 4:1 Sharp alpha DXT3 BC2 Explicit alpha No 4:1 Sharp alpha DXT4 (none) Interpolated alpha Yes 4:1 Gradient alpha DXT5 BC3 Interpolated alpha No 4:1 Gradient alpha

Tableau 4.1 – Différentes variantes de la technique de compression S3TC.

4.1.5 Codage des textures LCC

Les textures LCC sont découpées et indexées de la même manière que celles du terrain afin de faciliter leurs gestions. C’est plutôt une contrainte imposée par notre mécanisme de chargement progressif. En effet, le fait d’utiliser la même texture TLM pour calculer la liste des textures utiles au rendu et celle des textures nécessaires à l’amplification du terrain, implique que les deux types de textures doivent être de même taille et indexées de la même manière. Cependant, elles sont chargées sur GPU dans des caches différents puisqu’elles n’ont pas le même format de stockage. Pour ce premier terrain, nous disposons d’une classification par classe de matières. Chaque pixel d’une texture LCC code un ou plusieurs types de matières. Or, comme nous l’avons déjà évoqué, ce codage ne permet pas un Mip-mapping trivial, nécessaire lors de l’amplification (voir section 3.4.3). Par conséquent, nous avons mis en place un mécanisme de codage simple permettant de translater cette information (code de matière) du niveau 1 aux autres niveaux de la pyramide propre aux textures LCC (figure 4.4). Cela est indispensable (en l’absence de Mip-mapping), car les objets que nous essayerons de positionner sur le sol sont géo-référencés. Ils peuvent apparaître de très loin (3000-4000 m, pour le cas des arbres) alors que les textures du sol du niveau 0 (niveau dans lequel l’amplification s’effectue) ne sont pas encore visibles. Néanmoins, cette pyramide est limitée à trois niveaux correspondant à une distance d’amplification maximale fixée par l’utilisateur.

Figure 4.4 – Schéma de codage du quadtree LCC (A, R, N sont des indices de matières). Initialement, nous disposons d’une classification à 2 m de résolution. Donc, à partir du niveau 1 nous construisons le niveau 0, ensuite le niveau 2 de la pyramide.

- 85 - Chapitre 4 : Résultats et discussion

Si nous supposons que chaque pixel d’une texture LCC est codé sur une seule composante de 8 bits, le nombre maximal d’objets du sursol que nous pouvons gérer par ce codage est de 4 (dont le 0 pour indiquer l’absence de matière). Cependant, si nous utiliserons 4 composantes de 8 bits par pixel, le nombre d’objets augmente à 255 essences différentes, ce qui est suffisant pour peupler un terrain en interactif avec des écosystèmes. Néanmoins, cela engendre un surcoût de chargement et de stockage des textures LCC.

4.2 Modules « rendu et amplification du terrain »

RMK2 [ Bal03 ] est la librairie choisie pour effectuer le rendu du terrain. Elle implémente une version améliorée de l’algorithme d’affichage de terrain SOAR [ LP02 ], et un algorithme d’amplification géométrique, effectué sur CPU pour l’instant, en attendant de faire mieux avec les « geometry shaders ». RMK2 assure la continuité du maillage adaptatif et la limitation de l’erreur visuelle (que nous avons rendue view-dependant ). La géométrie de base du terrain et ses motifs d’amplification sont stockés dans des heightmaps d’une taille limitée à 4096×4096. Un pavage apériodique de motifs de détail géo-spécifiques, programmé sur GPU, gère la nature, l’amplitude et les transitions des détails ajoutés. On manipule aisément des terrains de plusieurs milliers de kilomètres carrés avec des taux d’amplification supérieurs à 50 en x et en y (figure 4.5).

(a) (b)

(c) (d) Figure 4.5 – Plusieurs représentations du terrain pour un même point de vue. (a) Triangulation de base. (b) Triangulation amplifiée. (c) Ajout de détails. (d) Habillage du terrain par des textures (en utilisant notre plate-forme).

- 86 - Chapitre 4 : Résultats et discussion

4.2.1 Module « Carte de chargement »

La géométrie, produite à chaque frame par RMK2, est acheminée au GPU suite à l’appel de la primitive de dessin glDrawRangeElements . Elle sera cachée dans un VBO, puis rendu sur écran. Au cours de cette opération, cette géométrie va subir les différentes étapes de transformations du pipeline fixe (voir annexe I) ou éventuellement, exécutera les shaders du pipeline programmable suite à son activation. L’objectif est le même : pouvoir représenter une réalité 3D (modélisée par des coordonnées cartésiennes (x, y, z)) dans un espace 2D

(coordonnées écran ( xe, ye)). Comme évoqué précédemment (Chapitre3, section 3.2), la géométrie du terrain est projetée dans un espace texture (texture TLM ) pour estimer le niveau de détail avec lequel chaque case visible sera utilisée (lors de l’habillage du terrain). Deux shaders (VS1 et FS1) ont été élaborés afin d’assurer cette projection. En effet, chaque sommet géométrique exécute ces shaders indépendamment des autres, ce qui permet au GPU d’en traiter plusieurs en même temps. Rappelons que nous devons activer le mélange des couleurs ( blending ) et modifier sa fonction pour pouvoir cumuler les valeurs ( lodMin , lodMax , pIndex , visible ) calculées par chaque fragment se projetant dans une même case. La séquence de code openGL qui nous permet de réaliser cette opération est la suivante : glBlendFunc(GL_ONE, GL_ONE) glBlendEquation(GL_MAX) glEnable(GL_BLEND)

Par ailleurs, le code source commenté des deux shaders est le suivant : Vertex shader 1

uniform vec3 posViewer; varying float LodRad; varying float Distance; varying vec4 PosScreen; varying vec2 XZ; void main (void) { // Coordonnées de texture globales dans [-1, 1] // ('y' est l'élévation dans les coord géo de SOAR) gl_Position.xy = (gl_Vertex.xz / rangeTerrain) * 2.0 - 1.0; // Coordonnées planes du vertex XZ = gl_Vertex.xz; // Coordonnées écran du vertex projeté PosScreen = ftransform(); // Distance caméra -> vertex Distance = distance(gl_Vertex.xyz, posViewer); // Niveau de détail radial (le nombre de niveaux n'est pas limité) if (Distance < 1200.0) LodRad = 0.0; else LodRad = (1.0 + floor(log2(Distance / 1200.0))) / 255.0; }

- 87 - Chapitre 4 : Résultats et discussion

Fragment shader 1 varying float LodRad; varying float Distance; varying vec4 PosScreen; varying vec2 XZ; void main (void) { float pCount = 0.0 ; // On active le frustum-culling à partir d'une certaine distance (6000m semble être suffisant) if ( Distance >= 6000.0 ) { // Remarque : des valeurs de w > 1.0 augmentent la taille du cône de culling if (dot(PosScreen, vec4( 0.0, 0.0, 1.0, 1.0)) < 0.0) discard; //near if (dot(PosScreen, vec4(-1.0, 0.0, 0.0, 1.0)) < 0.0) discard; //left if (dot(PosScreen, vec4( 1.0, 0.0, 0.0, 1.0)) < 0.0) discard; //right if (dot(PosScreen, vec4( 0.0,-1.0, 0.0, 1.0)) < 0.0) discard; //bottom if (dot(PosScreen, vec4( 0.0, 1.0, 0.0, 1.0)) < 0.0) discard; //top if (dot(PosScreen, vec4( 0.0, 0.0,-1.0, 1.0)) < 0.0) discard; //far } else // On élargit le "cône de culling" pour éviter les problèmes de bord { if ( dot(PosScreen, vec4( 0.0, 0.0, 1.0, 1.0)) < -1024.0) discard; //near if ( dot(PosScreen, vec4(-1.0, 0.0, 0.0, 1.0)) < -1024.0) discard; //left if ( dot(PosScreen, vec4( 1.0, 0.0, 0.0, 1.0)) < -1024.0) discard; //right if ( dot(PosScreen, vec4( 0.0,-1.0, 0.0, 1.0)) < -1024.0) discard; //bottom if ( dot(PosScreen, vec4( 0.0, 1.0, 0.0, 1.0)) < -1024.0) discard; //top if ( dot(PosScreen, vec4( 0.0, 0.0,-1.0, 1.0)) < -1024.0) discard; //far

// Calcul de l'index de pattern : nombre pseudo-aléatoire dans l'intervalle 1..P_COUNT if (Distance <= 4800.0) pCount = (1.0 + floor( mod(881 * abs(cos(XZ.x * XZ.y)), P_COUNT) ))/255.0; }

// Ecriture des 4 composantes utiles de la TLM gl_FragColor = vec4( LodRad, 1.0-LodRad, pCount, 1.0); }

A présent, la texture TLM doit être transférée, depuis l’espace de rendu vers l’espace CUDA , pour analyse. Pour ce faire, nous utilisons GL_BGRA au lieu de GL_RGBA comme format interne de la texture TLM. Ensuite, nous attachons son contenu à un PBO pour accélérer son transfert. Par ailleurs, du fait que les deux espaces ne sont pas visibles l’un par rapport à l’autre, nous devons effectuer les opérations suivantes (figure 4.6) pour rendre le PBO visible depuis l’espace CUDA : 1. Désinscrire, de l’espace CUDA , le PBO utilisé pour le transfert de la texture TLM, 2. Effectuer le transfert depuis le (annexe I) vers le PBO au moyen de la primitive glReadPixels , 3. Inscrire le PBO dans l’espace CUDA 4. Mappé le PBO sur une variable CUDA pour que son contenu soit finalement visible.

Pour effectuer l’analyse de ces données, nous lançons (depuis le CPU) une grille de 128 ×128 threads (rappelons que la taille de la TLM est 256 ×256) regroupés en blocs de 256. Chaque thread opère sur quatre éléments adjacents de la matrice des données. Le choix de ces paramètres est expérimental. I est en forte relation avec plusieurs autres facteurs (Annexe II), à savoir : mémoire partagée, registres, nombre de threads par bloc, etc.

- 88 - Chapitre 4 : Résultats et discussion

Figure 4.6 – Transfert de la texture TLM depuis l’espace de rendu vers l’espace CUDA .

4.2.2 Module « Habillage du terrain »

Une fois que le contenu de la texture TLM est analysé, la liste des textures utiles est rapatriée au niveau du CPU. Ainsi, les nouvelles textures nécessaires à l’habillage du terrain pour le frame courant sont chargées depuis le média de stockage vers le cache GPU (une texture de 8192 ×8192 pixels). Les PBO sont de nouveau sollicités pour accélérer ce transfert (CPU →GPU). Ensuite, un autre appel de la primitive de dessin glDrawRangeElements permettra, cette fois-ci, de dessiner la géométrie du terrain (résidante au niveau du GPU) sur écran. Il est important de souligner que le transfert de cette géométrie ne s’effectuera pas une deuxième fois, ce qui nous permet de préserver la bande passante (CPU/GPU). Les deux shaders (VS2 et FS2) suivants sont utilisés pour visualiser la géométrie du terrain tout en l’habillant par les textures chargées au niveau du cache GPU (figure 4.7).

Vertex shader 2 uniform vec3 posViewer; uniform vec4 cloudParam; varying vec2 UV; varying vec4 UVCloud; varying float LodRad; varying float fogZ; void main (void) { // Coordonnées écran du vertex projeté gl_Position = ftransform(); // Coordonnées de texture globales ('y' est l'élévation dans les coord géo de SOAR) UV = gl_Vertex.xz / rangeTerrain; // Paramètres des nuages et du fog UVCloud = cloudParam.xxyy * gl_Vertex.xzxz + cloudParam.zwwz; fogZ = gl_Position.z; // Distance caméra -> vertex float Distance = distance(gl_Vertex.xyz, posViewer); // Niveau de détail radial (le nombre de niveaux n'est pas limité) if (Distance < 1200.0) LodRad = 0.0; else LodRad = 1.0 + floor(log2(Distance / 1200.0)); }

- 89 - Chapitre 4 : Résultats et discussion

Fragment shader 2 #version 120 #extension GL_EXT_gpu_shader4 : require #extension GL_ARB_texture_rectangle : enable uniform sampler2D TexCache; // Puzzle de textures : cache contenant les tiles chargés à chaque frame uniform sampler2DRect TexQuadTree; // Texture codant des pointeurs sur les emplacements des tiles chargés dans le cache uniform sampler2D TexCloud; // Texture des nuages varying vec2 UV; varying vec4 UVCloud; varying float LodRad; varying float fogZ; // Cette procédure récupère conjointement, pour 'uv' global (dans [0, 1]) passé en entrée, la position du tile dans la // texture 'TexQuadTree' et la coordonnée relative 'uvT' dans ce tile float checkQuad (float lod, vec2 uv, out vec2 uvT) { float r0, q0, DD, R, Id, RR = exp2(lod);

R = Resol_Niv_0 / RR; vec2 quot = floor(R * uv); uvT = (R * uv - quot) * ResolTile;

DD = ((RR * RR -1.0) / 3) * 4 * R * R; Id = DD + R * quot.y + quot.x; q0 = floor(Id / ResolTile); r0 = Id - q0 * ResolTile; return( texture2DRect(TexQuadTree, vec2(r0, q0)).x ); }

void main (void) { vec2 UVT; float r0, q0, cloud, fog, posTileCache, lod = round(LodRad);

// Cloud && fog colors cloud = texture2D(TexCloud, UVCloud.xy).a + 0.25*texture2D(TexCloud, UVCloud.zw).a; fog = clamp( exp(-gl_Fog.density*abs(fogZ)), 0.0, 1.0 ); // Calcul de la position du tile dans la texture 'TexQuadTree' // Le "lod radial rasterizé" a une incertitude de 1, car : // a- il peut être exact, // b- égal à lod-1 dans le cas où la rasterization est effectuée entre un niveau i et un niveau inférieur i-1 // c- égal à lod+1 dans le cas d'un fragment interpolé entre un niveau i et un niveau supérieur i+1 if ( (posTileCache = checkQuad(lod, UV, UVT)) <= 0.0 ) // Cas (a) if ( (posTileCache = checkQuad(max(0.0, lod-1.0), UV, UVT)) <= 0.0 ) // Cas (b) posTileCache = checkQuad(min(lod+1.0, 8.0), UV, UVT); // Cas (c) // Calcul des coordonnées de texture 'UVC' dans le cache (puzzle où l'affectation des cases sub-textures est // dynamique). On maintient une correspondance entre l'emplacement réel (géo-spécifique) et l'endroit dans // lequel le tile est chargé. q0 = floor((posTileCache * 65536.0 - 1.0) / ResolCacheTile); // entier en 16 bits r0 = (posTileCache * 65536.0 - 1.0) - q0 * ResolCacheTile; vec2 UVC = ResolTile * vec2(r0, q0) + UVT * decal.x + decal.y; // Couleur du fragment (1.15 règle la saturation des blancs) gl_FragColor = mix(gl_Fog.color, texture2D(TexCache, UVC / ResolCachePixel) * cloud, fog) * 1.15; }

Dans le code précédent (FS2), la procédure checkQuad implémente un algorithme de décodage de la position du tile dans la pyramide des textures et, par conséquent, sa position dans le cache GPU. Ce traitement est effectué pour chaque fragment, candidat de pixel, appartenant à un tile visible.

- 90 - Chapitre 4 : Résultats et discussion

La figure 4.7 illustre le résultat de l’exécution des deux modules précédents (carte de chargement et habillage du terrain). Sur ce point de vue, nous visualisons aussi le contenu de la texture TLM (en dessous à gauche) et celui du cache GPU (en dessous à droite). D’une part, nous remarquons sur l’image de la texture TLM que seuls les fragments appartenant au volume de vision sont retenus (couleur verte), alors que les autres se trouvant à l’extérieur sont écartés (couleur noir). De plus, nous pouvons observer un léger élargissement du cône de vision autour de la position de l’observateur, utilisé comme solution pour remédier au problème de rasterization (voir section 3.2.2). D’autre part, sur l’image du cache GPU, nous remarquons que les textures chargées au niveau du cache sont placées d’une manière non contiguë et occupent à moitié cet espace. Malgré que le point de vue soit à l’horizon, une partie de ces textures ne sont pas utilisée par le point de vue courant (leurs espaces ont été libérés sur CPU). Ceci témoigne de la bonne estimation qu’offre notre algorithme de chargement progressif en matière de nombre de textures nécessaires à un point de vue donné. Par ailleurs, nous pouvons aussi voir le résultat de la simulation des nuages et leurs projections sur les textures habillant le sol.

Figure 4.7 – Habillage du terrain par les textures utiles. Au dessous à gauche, visualisation du contenu de la texture TLM. Au dessous à droite, visualisation du contenu du cache texture. En arrière plan, visualisation du premier terrain par notre plate-forme.

- 91 - Chapitre 4 : Résultats et discussion

4.2.3 Module « Sélection des graines »

Le module de sélection effectue un rendu des motifs génériques dans plusieurs textures superposées. Ces textures (de format interne GL_RGBA32F_ARB ) stockent les différentes propriétés utilisées pour diversifier l’apparence géométrique et visuelle des objets du sursol. Dans notre implémentation, ces textures ont une taille de 512 ×512 pixels, ce qui nous permet de rendre jusqu’à 218 essences. Le code suivant détaille la manière dont nous procédons pour réaliser cette phase.

Vertex shader 3 #version 120 #extension GL_EXT_gpu_shader4 : require attribute vec3 pos; // xyz : position attribute float id; // position 2D dans la texture de sortie attribute vec4 boundingSphere; // xyz : centre, w : ray uniform float translateGraine; uniform vec2 translation; uniform vec3 posViewer; uniform sampler2D heightMap; varying float clip; // clip de graine varying float LodRad; // lod radial de texture varying float computedSize;// taille randomisée varying vec3 position; // xyz : position sur le terrain varying vec3 hposition; // xy : position projetée à l'écran [0, largeur]x[0, hauteur], z : profondeur en mètres

vec4 tex2D_bilinear (vec2 t) { vec2 offset = fract(t.xy * texSize); vec4 t00 = texture2D(heightMap, t); vec4 t10 = texture2D(heightMap, t + vec2(texelSize, 0.0)); vec4 a = mix(t00, t10, offset.x); vec4 t01 = texture2D(heightMap, t + vec2(0.0, texelSize)); vec4 t11 = texture2D(heightMap, t + vec2(texelSize, texelSize)); vec4 b = mix(t01, t11, offset.x); return mix(a, b, offset.y); }

bool IsVisible (vec4 projectedBase, vec4 projectedHead, vec4 projectedLeft, vec4 projectedRight, vec4 projectedFar) { return ((dot(projectedFar , vec4( 0.0, 0.0, 1.0, 1.0)) > -60.0) //near && (dot(projectedRight, vec4(-1.0, 0.0, 0.0, 1.0)) > -60.0) //left && (dot(projectedLeft , vec4( 1.0, 0.0, 0.0, 1.0)) > -60.0) //right && (dot(projectedHead , vec4( 0.0,-1.0, 0.0, 1.0)) > -60.0) //bottom && (dot(projectedBase , vec4( 0.0, 1.0, 0.0, 1.0)) > -60.0)); //top }

void main () { vec2 ID; // Position du pied de l'arbre (retrait de 0.35 m pour l'enterrer) position.xz = pos.xz + translation.xy * PSIZE; position.y = tex2D_bilinear(position.xz / groundSize).x * 6553.5 - 0.35; // Graine Ecartée en fonction de l'altitude (avec variation locale contrôlée par le paramètre 12.8) float random = cos(position.x * position.z / 12.8); if (position.y > (2000.0 + 100.0 * random)) clip = -1.0;

- 92 - Chapitre 4 : Résultats et discussion

else { // Calcul d'une taille pseudo aléatoire réaliste // Les deux paramètres 0.25 et 0.5 ajustent la moyenne et l'écart maximum computedSize = random * 0.25 + 0.5; // Calcul des positions base, head, left, right et far de la sphère englobante de la graine float computedRadius = boundingSphere.w * computedSize; vec3 head = position + vec3(0.0, computedRadius * 2.0, 0.0); vec3 left = position + vec3(-computedRadius, computedRadius, 0.0); vec3 right = position + vec3( computedRadius, computedRadius, 0.0); vec3 far = position + vec3( 0.0, computedRadius, -computedRadius); // Calcul des projections de ces points vec4 projectedHead = gl_ModelViewProjectionMatrix * vec4(head, 1.0); vec4 projectedBase = gl_ModelViewProjectionMatrix * vec4(position, 1.0); vec4 projectedLeft = gl_ModelViewProjectionMatrix * vec4(left, 1.0); vec4 projectedRight = gl_ModelViewProjectionMatrix * vec4(right, 1.0); vec4 projectedFar = gl_ModelViewProjectionMatrix * vec4(far, 1.0); // Test de visibilité de la sphère if (IsVisible(projectedBase, projectedHead, projectedLeft, projectedRight, projectedFar)) { // avec windowSize = (1280/2, 1024/2) on doit ajouter 1.0 après la division par w (pb potentiel de culling) hposition = vec3((projectedHead.xy / projectedHead.w + 1.0) * windowSize, abs(projectedHead.z)); clip = 1.0; // Lod radial des textures de terrains (0, 1 ou 2) float Distance = distance(position, posViewer); if (Distance < 2400.0) LodRad = floor(Distance/1200.0); else if (Distance < 4000.0) LodRad = 2.0; else clip = -1.0; // Graine écartée } else clip = -1.0; // Graine écartée }

// Position 2D dans la texture de sortie ID.y = floor((id+translateGraine)/WidthSLM); ID.x = floor(0.5 + mod((id+translateGraine), WidthSLM)); gl_Position.xy = vec2( ID.x/WidthSLM, ID.y/HeightSLM ) * 2.0 - 1.0; // dans [-1, 1] (IMPORTANT) }

Fragment shader 3 #version 120 #extension GL_ARB_draw_buffers : enable #extension GL_EXT_gpu_shader4 : require #extension GL_ARB_texture_rectangle : enable uniform sampler2DRect depthMap; uniform sampler2DRect treeTexQuadTree; uniform sampler2DRect treeTexCacheLCC; uniform sampler2D treeTexCache; varying float clip; // clip de graine varying float LodRad; // lod radial de texture varying float computedSize; // taille randomisée varying vec3 position; // xyz : position sur le terrain varying vec3 hposition; // xy : position projetée à l'écran [0, largeur]x[0, hauteur], z : profondeur en mètres varying out vec4 selectedDATA[2]; // Extraction des bits forts (7,6,5,4) de l’entier codant l’indice de matière bvec4 HighPartBits (float number){ return ( greaterThanEqual(fract( vec4(number)/vec4(256.0, 128.0, 64.0, 32.0) ), vec4(0.5)) ); }

// Extraction des bits faibles (3,2,1,0) de l’entier codant l’indice de matière

- 93 - Chapitre 4 : Résultats et discussion bvec4 LowPartBits (float number){ return greaterThanEqual(fract( vec4(number)/vec4(16.0, 8.0, 4.0, 2.0) ), vec4(0.5)); } float Matter (bvec2 matter) { return (matter.x ? 2.0 : 0.0) + (matter.y ? 1.0 : 0.0); } // Décodage de l'index de matière float MatterIndex ( vec3 position, vec2 uv, float lodRad) { // Le resultat est soit 0 (sol nu), 1, 2 ou 3 pour les differentes essences float index = round( texture2DRect(treeTexCacheLCC, uv).x * 255.0); if(lodRad > 1.1) //niveau 2 { vec2 temp = position.xz * 0.5 - floor(position.xz * 0.5); bvec4 bits = ( temp.y < 0.5 ? LowPartBits(index) : HighPartBits(index) ); return Matter( temp.x < 0.5 ? bits.zw : bits.xy ); } else return index; }

// Cette procédure récupère conjointement, pour 'uv' global (dans [0, 1]) passé en entrée, la position du tile dans la // texture 'treeTexQuadTree' et la coordonnée relative 'uvT' dans ce tile. float checkQuad (float lod, vec2 uv, out vec2 uvT) { float r0, q0, DD, R, Id, RR = exp2(lod);

R = treeResol_Niv_0 / RR; vec2 quot = floor(R * uv); uvT = (R * uv - quot) * treeResolTile;

DD = ((RR * RR -1.0) / 3) * 4 * R * R; Id = DD + R * quot.y + quot.x; q0 = floor(Id / treeResolTile); r0 = Id - q0 * treeResolTile; return( texture2DRect(treeTexQuadTree, vec2(r0, q0)).x ); } void main (void) { vec2 UVT, UVC, UV; float r0, q0, lod, HALFtreeResolTile, posTileCache; if( clip > 0.0 ) // graine non éliminée dans le vertex shader { // Vérification de l'occlusion (cime comprise) // On tient compte de l'erreur de profondeur due à la simplification de la geometrie par SOAR (50.0) float a = 150000.0 / ( 150000.0 - 1.0 ); // Near = 1.0 float b = 150000.0 * 1.0 / ( 1.0 - 150000.0 ); // Far = 150000.0 float depth = b / ( texture2DRect(depthMap, hposition.xy).r - a ); if(hposition.z < depth + 50.0) { // Calcul des UV dans la texture cache LCC (les mêmes que ceux du terrain) float groundSize = 65536.0; // par cohérence avec VP1, VP2 et FP2 UV = position.xz / groundSize; // Calcul des coordonnées de texture dans le cache // Le lod rasterizé "LodRad" a une incertitude de 1 : // a- il peut être exact, // b- égal à lod-1 dans le cas où la rasterization est effectuée entre un niveau i et un niveau inférieur i-1 // c- égal à lod+1 dans le cas d'un fragment interpolé entre un niveau i et un niveau supérieur i+1 lod = round(LodRad); if ( (posTileCache = checkQuad(lod, UV, UVT)) <= 0.0 ) // Cas (a) if ( (posTileCache = checkQuad(lod-1, UV, UVT)) > 0.0 ) // Cas (b) lod = lod - 1;

- 94 - Chapitre 4 : Résultats et discussion

else{ lod = lod + 1; posTileCache = checkQuad(lod, UV, UVT); // Cas (c) } q0 = floor((posTileCache * 65536.0 - 1.0) / treeResolCacheTile); // entier en 16 bits r0 = (posTileCache * 65536.0 - 1.0) - q0 * treeResolCacheTile; UVC = treeResolTile * vec2(r0, q0) + UVT * treeDecal.x + treeDecal.y;

// Le niveau de détail (0, 3, 6) de chaque graine dépend de sa taille et de sa distance au viewer // le paramètre 1200 régle la distance de transition entre les lods float level = min(floor((hposition.z / computedSize)/1200.0)*3, 6); // Récupération de l'indice de matière : attention, on rajoute 1.25 (le LCC n'est pas décalé) float matter = MatterIndex(position, UVC+1.25, lod); // Si l'index est strictement positif, on sauve la graine et ses propriétés if(matter > 0.1) { // Obtention de la couleur du sol vec3 groundColor = texelFetch2D(treeTexCache, ivec2(UVC), 0).xyz * 255.0; // Multiple render targets // Sauvegarde de size, rotation, color, Level et matter sont combinés pour donner l'indice d'objet à charger. selectedDATA[0] = vec4(floor(level + matter), position); selectedDATA[1] = vec4(computedSize, cos(position.x * position.z), groundColor.b + 256.0*groundColor.g + 5536.0*groundColor.r, 0.0); }else selectedDATA[0] = vec4(0.0, 0.0, 0.0, -1.0); } else selectedDATA[0] = vec4(0.0, 0.0, 0.0, -1.0); } else selectedDATA[0] = vec4(0.0, 0.0, 0.0, -1.0); }

Le résultat de cette étape est stocké dans plusieurs textures superposées contenant l’ensemble des propriétés dans un ordre quelconque qu’il faut regrouper (par type de matière) et compter sur GPU. Cela est nécessaire pour effectuer un rendu efficace des objets du sursol tout en exploitant le mécanisme d’instanciation ( instancing ) disponible sur les processeurs graphiques actuels (G80 ou plus). En effet, l’information qui doit être rapatriée au niveau du CPU pour le rendu final des objets, doit se limiter au nombre d’objets par type d’essence. Pour ce faire, nous avons adapté (figure 4.8), puis intégré dans notre architecture (figure 4.9) l’algorithme de réduction de flux développé par David Roger [RAH07].

Données brutes Etapes intermédiaires Groupement par valeur Figure 4.8 – Etapes d’exécution de l’algorithme de David Roger [RAH07].

- 95 - Chapitre 4 : Résultats et discussion

Figure 4.9 – Regroupement des propriétés par type d’essences. En bas à droite : la texture(s) de sélection, au milieu : des étapes intermédiaires de l’algorithme de regroupement, en haut : regroupement par type d’essence.

4.2.4 Module « Rendu des arbres »

Trois types d’arbres représentés en billboard clouds ont été utilisés pour amplifier « à la volée » la zone de Megève. Chaque modèle étant décliné en trois niveaux de détail différents. Ces modèles nous ont été fournis par Fuhrmann , auteur de la technique de simplification extrême des arbres pour le rendu des forêts [FMU05]. Malheureusement, nous n’avons pas pu avoir une copie de son implémentation, et par conséquent, nous nous sommes limités à ces trois modèles d’arbres pour illustrer le fonctionnement de notre démarche. Le choix de cette technique, pour modéliser les objets du sursol, est motivé par la représentation compacte qu’elle offre : plusieurs plans intersectés sont utilisés pour représenter géométriquement l’arbre et une image en atlas de texture pour l’habiller (figure 4.10). A la sortie de l’algorithme de réduction de flux, nous rapatrierons (sur CPU) les nombres d’essences par type d’arbres. Les arbres de même type sont dessinés au moyen d’un seul appel de la primitive glDrawElementsInstancedEXT. Dès lors, la géométrie de ce type d’arbre (chargée préalablement au niveau de la mémoire vidéo) est dupliquée au niveau du GPU, positionnée, orientée et habillée en fonction de ces propres paramètres. Ces

- 96 - Chapitre 4 : Résultats et discussion paramètres sont lus depuis la (les) texture(s) de sélection. Un peu plus de détail est donné par les shaders ( vertex shader 4 et fragment shader 4).

Figure 4.10 – Atlas de textures des trois modèles d’arbres utilisés pour amplifier la zone de Megève (Haute Savoie).

Vertex shader 4 #version 120 #extension GL_EXT_gpu_shader4 : require

uniform float count; uniform vec4 treeCloudParam; uniform sampler2D texNonPacked0, texNonPacked1, texPacked;

varying vec4 UVCloud; varying vec3 color;

void main(void) { ivec2 UV; vec4 position; vec3 translate, ScaleRotateColor;

// Récupération de l'index "c + 16*(textureWidth*j+k)", // où c représente la catégorie de l'objet et (j,k) sa position dans la texture de sélection int rang = int(gl_InstanceID + count); int ID = int( texture2D(texPacked, vec2(mod(rang,widthSLMPacked), floor(rang/widthSLMPacked))/widthSLMPacked).r / 16 );

// Récupération des paramètres spécifique à chaque instance d'objet UV.x = ID%int(widthSLMPacked); UV.y = ID/int(widthSLMPacked); translate = texelFetch2D(texNonPacked0, UV, 0).yzw; ScaleRotateColor = texelFetch2D(texNonPacked1, UV, 0).xyz;

ScaleRotateColor.y = PI*ScaleRotateColor.y; float cos_ = cos(ScaleRotateColor.y); float sin_ = sin(ScaleRotateColor.y);

position.x = ScaleRotateColor.x*( cos_ * gl_Vertex.x + sin_ * gl_Vertex.z ) + translate.x; position.z = ScaleRotateColor.x*(-sin_ * gl_Vertex.x + cos_ * gl_Vertex.z ) + translate.z; position.y = ScaleRotateColor.x*gl_Vertex.y + translate.y; position.w = 1.0;

gl_Position = gl_ModelViewProjectionMatrix * position;

int groundColor = int(ScaleRotateColor.z); color.x = groundColor/65536; groundColor = groundColor%65536;

- 97 - Chapitre 4 : Résultats et discussion

color.y = groundColor/256; color.z = groundColor%256; color = color/255.0;

// Paramètres des nuages UVCloud.xyzw = treeCloudParam.xxyy * position.xzxz + treeCloudParam.zwwz; gl_TexCoord[0].xy = gl_MultiTexCoord0.xy; }

Fragment shader 4

uniform sampler2D texMaterial, treeTexCloud; varying vec4 UVCloud; varying vec3 color;

void main( ) { // Couleur du fragment (billboard) vec4 col = texture2D (texMaterial, gl_TexCoord[0].xy);

// Mélange de la couleur de sol (color) avec celle du fragment (col) // et multiplication par "cloud color", où 1.15 règle la saturation des blancs float cloud = ( texture2D(treeTexCloud, UVCloud.xy).a + 0.25 * texture2D(treeTexCloud, UVCloud.zw).a ) * 1.15;

gl_FragColor = vec4( cloud*(col.rgb + 0.7 * color.rgb) / 1.7, col.w ); }

4.3 Evaluation des performances

Les résultats que nous allons présenter ont été obtenus sur une station de travail dotée d’un processeur Intel dual-core 2.93 GHz, 2 Go de RAM et une carte graphique Geforce 8800GTX (768 Mo de RAM). La version du driver que nous avons installé pour cette carte graphique est la version 162.01 supportant l’exécution de CUDA 1.0.

4.3.1 Evaluation qualitative

Les figures 4.11 et 4.12 illustrent la qualité visuelle des images obtenues.

Figure 4.11 –Terrain texturé par notre plate-forme (avec la permission de la RGD73-74).

- 98 - Chapitre 4 : Résultats et discussion

Figure 4.12 – Terrain texturé et amplifié par 3 types d’arbres à différentes résolutions (avec la permission de la RGD73-74).

Nous pouvons observer sur ces images les points suivants :

- Positionnement des arbres cohérent avec le contenu des images aériennes, - Diversité géométrique (mise à échelle et rotation) des arbres affichés, initialement de même taille, - Diversité visuelle (prise en compte de la couleur du sol et de la projection des nuages sur les feuilles arbres), - Visualisation des d’arbres en plusieurs niveaux de détails en fonction de la distance à l’observateur, - Rendu d’un nombre important d’arbre par frame - Réalisme des scènes affichées sans popping .

De plus , en mode navigation, nous pouvons aussi observer une transition fluide entre les textures du sol et les objets du sursol au moment de leurs apparitions. Cela est dû à deux facteurs importants : 1. Les objets apparaissent à partir d’une distance suffisante (4800 m) avec une géométrie assez légère, 2. La couleur des objets est mélangée (à un certain pourcentage) avec celle du sol.

- 99 - Chapitre 4 : Résultats et discussion

4.3.2 Evaluation quantitative

Les tableaux suivants donnent un aperçu des temps d’exécution de chaque étape de notre démarche. Les tests ont été effectués sur trois points de vue différents avec les deux résolutions d’écran suivantes : 1280 ×1024( 1) et 1024 ×768( 2) (tableaux 4.2, 4.3, 4.4). Nous remarquons, a travers ces résultats, que les temps d’exécution des shaders (Pass1, 2, 3 et 4) sont négligeables comparés à ceux qui se rapportent aux opérations de transferts (depuis ou vers le GPU). Toutefois, le temps d’exécution lié à l’étape d’analyse de la TLM augmente dès que la taille de cette dernière devient importante (tableau 4.3). Par conséquent, cela sous-entend que cette étape n’est pas encore correctement optimisée. Toutefois, nous pouvons constater que, globalement, les taux de rafraîchissement ( ) obtenus restent élevés malgré le nombre important d’arbres affichés (dépassant 70.000). Par ailleurs, il est important de souligner que notre plate-forme est modulaire. Des améliorations peuvent être apportées à chacun de ces modules sans toucher à son ossature globale. Par conséquent, elle peut être considérée comme une plate-forme de test de plusieurs types d’algorithmes à s’avoir, ceux liés au rendu des terrains et des objets naturels.

Viewpoint 1 2 3 Resolution 1 2 1 2 1 2 Build mesh (CPU) 5.63 4.4 5.41 3.882 1.542 1.374 Mesh VBO and depthMap 1.271 1.268 1.288 1.265 1.262 1.257 Pass 1 0.064 0.061 0.066 0.061 0.063 0.062 PBO transfer for CUDA 0.558 0.557 0.556 0.546 0.511 0.546 TLM analysis with CUDA 0.1191 0.1188 0.1193 0.1191 0.1167 0.1166 GLM readback 0.421 0.420 0.419 0.418 0.420 0.420 Tile streaming tasks 0.751 0.548 0.802 0.721 0.554 0.378 Pass 2 0.034 0.030 0.033 0.032 0.033 0.030 TLM only 1.947 1.734 1.995 1.897 1.699 1.553 Terrain rendering FPS (Hz) 113 135 115 142 222 239 Tableau 4.2 – Analyse des performances (en ms ) des deux premiers modules.

TLM size 128x128 256x256 512x512 1024x1024 2048x2048 Pass1 (ms) 0.066 0.07 0.071 0.073 0.081 Analysis (ms) 0.114 0.1183 0.5374 2.065 6.467 Tableau 4.3 – Evaluation des temps de calcul et d’analyse de la TLM.

Viewpoint 1 2 3 Resolution 1 2 1 2 1 2 Pass 3 0.683 0.661 0.317 0.303 0.221 0.212 SLM packing 0.531 0.539 0.507 0.510 0.379 0.375 SLM readback 0.493 0.494 0.497 0.493 0.495 0.492 Pass 4 8.405 4.701 5.863 3.931 2.382 1.331 Selected seeds 72 769/ frame 32 807/ frame 13 687/ frame Checked seeds 233 920/ frame 141 728/ frame 115 712/ frame Total FPS (Hz) 50 71 62 80 121 127 Tableau 4.4 – Temps d’exécutions des étapes d’amplification et de rendu des objets du sursol pour différentes densités d’essences.

- 100 - Chapitre 4 : Résultats et discussion

4.4 Modèle de graines : cas de la planète entière

Le moteur de rendu dans lequel nous avons intégré notre modèle de graines pour amplifier la terre entière est celui développé par l’équipe EVASION (INRIA RHONE-ALPES). Il est le fruit de plusieurs travaux de recherches menés au sein de cette équipe (rapport de recherche AR08 ). Il est structuré en deux parties: la première est une librairie, nommée ORK, regroupant une panoplie de fonctions liées à la gestion des états, des structures de données et des primitives OpenGL. La seconde partie englobe, sous le nom de PROLAND, les différents mécanismes implémentés pour le rendu proprement dit des terrains.

4.4.1 ORK ( Opengl Rendering Kernel )

Considérée comme indépendante de Proland (voir section 4.4.2), la bibliothèque ORK comporte globalement six espaces de nom, chacun regroupant une multitude de classes extensibles. Nous présentons l'essentiel des fonctionnalités de chacun de ces espaces : - core : comme son nom l'indique c'est le cœur autour duquel communiquent presque toutes les autres classes. Il comporte, en premier lieu, la classe Object qui permet de créer et de référencer les objets. Ces références sont gérées par deux classes de pointeurs ( Ptr, StaticPtr ) qui font en sorte que les objets qui ne sont plus utilisés soient automatiquement supprimés. - math : regroupe des structures de données usuelles (vecteur, matrice, couleur, boîtes englobantes) et fournit plusieurs fonctions de génération de bruit procéduraux. - render : c'est la partie où l'ensemble des structures, des états et des fonctions OpenGL est défini sous forme de classes C++ (allant des fonctionnalités les plus basiques jusqu'aux extensions). - resource : gère le chargement, depuis le média de stockage, des ressources nécessaires à l'exécution (textures, shaders, maillages, fichiers de description XML de la scène). Le point fort de cette partie du code est qu'au moment d'un changement au niveau d'une ressource, la mise à jour est immédiatement prise en compte par l'application sans avoir besoin de la re-compiler ni même de la relancer. - scenegraph : définit un ensemble de nœuds regroupés dans un graphe. Ces nœuds constituent les éléments de la scène. - taskgraph : implémente les mécanismes d'ordonnancement liés à la gestion des différentes tâches (production et/ou chargement des données, mises à jour, visualisation, etc).

4.4.2 PROLAND ( PROcedural LANDscape )

Proland représente le cœur du moteur de rendu. Il permet la gestion en multi-résolution et la visualisation 3D temps réel de vastes terrains texturés. Il prend également en charge le rendu des routes, des forêts volumiques, des prairies, des rivières non animées et enfin de l'atmosphère, qui rajoutent du réalisme aux scènes affichées (figure 4.13). Pour pouvoir

- 101 - Chapitre 4 : Résultats et discussion gérer cette masse de données, des mécanismes de gestion des ressources mémoire ont été mis en œuvre afin de garantir une fluidité d'affichage.

Figure 4.13 – Terrains texturés avec prise en compte des effets atmosphériques.

4.4.2.1 Représentation du terrain

Le terrain est représenté par un ou plusieurs quadtrees qui s'adaptent (se subdivisent) en fonction du point de vue. Plus précisément, chaque feuille du quadtree ou tile est représentée par une grille régulière plane, à laquelle sont associés plusieurs types de textures (altitude, couleur, normale, couverture du sol, etc.). Ces textures sont produites par des producteurs de données (voir section 4.4.2.2) et sont utilisées au moment du rendu pour déformer, colorer et illuminer la grille régulière associée à chaque feuille du quadtree . Dans le cas de la visualisation du globe, six terrains sont dessinés sur les six faces d'un cube. Ces derniers sont ensuite projetés sur la sphère inscrite dans le cube afin de restituer la forme de la planète. Il faut noter que cette projection entraîne des déformations inévitables lorsqu'on tente de cartographier une sphère, et qu'il faudra en tenir compte dans notre modèle de graine.

4.4.2.2 Producteurs de données

Le principal problème pour gérer de très grands terrains vient du fait que le processeur graphique à une mémoire limitée, qui ne peut pas contenir toutes les données du terrain en même temps. Il est donc nécessaire de charger les données progressivement depuis le disque, ou de les produire à la volée. On peut ainsi ne charger les données que pour la partie visible du terrain à un instant donné, qui ne représentent qu'une petite fraction de l'ensemble des données. Pour réaliser cela Proland utilise des producteurs CPU et GPU auxquels il associe des caches dans l'espace mémoire CPU et GPU (figure 4.14). Les producteurs de données ont pour rôle de charger, réutiliser ou produire des données, généralement des textures, pour chaque feuille ou nœud interne du quadtree . Pour chaque nouvelle feuille, un producteur GPU consulte son cache pour savoir si la ou les textures associées à cette feuille existent. Si la réponse est oui, il n'a rien à faire, cette feuille peut être rendue immédiatement. Dans le cas contraire, deux cas de figures sont envisageables: - Dans le cas de données procédurales, le producteur produit lui-même ses données en s'appuyant sur des paramètres procéduraux. - Dans le cas de données non procédurales (ou procédurales mais devant être produites sur CPU), le producteur GPU sollicite un producteur CPU pour fournir ces données. Ce

- 102 - Chapitre 4 : Résultats et discussion

dernier consulte son cache à son tour pour répondre à cette requête. Dans le cas où les données existent, elles sont acheminées au producteur GPU qui les stocke dans son cache. Dans le cas contraire (les données n'existent pas dans le cache CPU) deux autres cas sont à prendre en considération: ou bien, le producteur produit lui même les données grâce à une méthode procédurale, ou bien il va les chercher dans un média de stockage.

Figure 4.14 – Architecture et fonctionnement des producteurs de données.

4.4.3 Sélection/Instanciation sous Proland

En ce qui concerne la visualisation du globe, nous avons évoqué dans la section 4.4.2.1 que la projection des six faces du cube (les six terrains couvrant la terre) entraîne des déformations au niveau des coins. Par conséquent, on se retrouvera avec des tiles qui couvrent une superficie du sol moins importante que celle couverte par ceux qui ne subissent pas de déformations. La densité de points des motifs doit être adaptée en fonction de la surface couverte par un tile . D'autre part, Proland définit pour la visualisation de chaque terrain une matrice de projection, ce qui est pratique puisque le rendu se fait par tile et que ce dernier appartient à un seul terrain. Cependant, lors du rendu des plantes, qui se fait au niveau GPU, on n'a aucun lien vers la matrice de projection à utiliser pour projeter la géométrie de cette dernière sur l'écran. C'est pourquoi on a eu recours au calcul d'une matrice de projection globale par approximation. Cette dernière est calculée par rapport au plan tangent à la sphère (planète) dans un point particulier. Ce point n'est autre que la projection orthogonale de la position de l'observateur sur le globe.

- 103 - Chapitre 4 : Résultats et discussion

Nous présentons, dans ce qui suit, une brève description des stratégies de sélection et d’instanciation que nous avons développées sous Proland.

4.4.3.1 Sélection, groupement et rendu par motif

Cette stratégie consiste à effectuer une opération de sélection puis de regroupement et enfin de rendu des plantes par tile ou plus précisément par motif. En effet, un tile peut contenir un ou plusieurs motifs de points selon qu’il s’agisse de ceux correspondant au niveau le plus détaillé de la texture LCC ou bien des autres niveaux. À chaque étape de rendu d'un motif, dans la texture de sélection, une liste de paramètres uniform sont envoyés au GPU pour accéder aux caches des différentes textures associées à un tile . Il est important de souligner que le nombre de motifs couvrant la géométrie d'un point de vue donné est de l'ordre de quelques milliers. En matière de coût mémoire, cette stratégie est optimale puisque les textures de sélection et de regroupement sont de faible taille. À titre d'exemple, pour un motif contenant au maximum 1000 points et couvrant une zone de 0,147 km 2, les textures doivent avoir une taille de 32 ×32 > 1000. Cependant, en matière de temps d'exécution, le placement des uniforms et les changements de contextes entre les étapes (sélection, regroupement et rendu des plantes) est non négligeable, ce qui diminue considérablement le temps global de rendu. Afin d'alléger l'étape de placement des uniforms, un regroupement par terrain et par motifs peut éventuellement réduire la redondance d'envoi de ces variables, mais aussi permet d'utiliser de l' instancing avec les motifs de même indice. Néanmoins, le rendu ne se fera plus par motif mais plutôt par groupe de motifs.

4.4.3.2 Sélection et rendu par terrain

Dans cette stratégie, l'étape de sélection est faite dans la même texture. Par exemple, une texture de taille 1024 ×1024 est capable de contenir 1 million de graines, ce qui est largement suffisant pour enrichir une scène de quelques kilomètres carrés. Cela permet de réduire à un le nombre de changements de contextes. Une autre amélioration apportée à la première stratégie est l'implémentation d'un mécanisme de décodage du quadtree sur GPU afin de permettre le positionnement des paramètres uniforms une seule fois. Néanmoins, ce décodage engendre un coût dû à de multiples accès textures pour avoir la position d'un tile dans le cache. Par ailleurs, l' instancing est exploité d'une manière optimale pour rendre les plantes (chaque type de plante est envoyée au GPU une seule fois avec son nombre d'occurrence). Cette stratégie améliore, d'une manière significative, le temps de rendu final.

4.4.3.3 Sélection et rendu par tile

L'autre stratégie que nous avons pu tester est le regroupement par motifs dans le même tile . En effet, le nombre de tiles concernés par l'amplification n'est pas très important (une centaines de tiles par point de vue). Le positionnement des uniforms se fait une fois par tile pour l'ensemble des motifs composant ce dernier. Cette stratégie est plus facile à

- 104 - Chapitre 4 : Résultats et discussion implémenter mais n'améliore pas d'une façon significative le temps de rendu global par rapport à la stratégie précédente.

4.4.3.4 Sélection statique

L'idée est de faire une étape de sélection et de groupement des graines par tile « à amplifier », allouer puis sauvegarder le résultat de ces étapes tant que le tile est visible. Bien évidemment, il faut au moins qu'une graine soit retenue. Cela permet de tirer profit de la cohérence spatiale des plantes lors de la navigation. Désormais, pour ce type de tile , nous effectuons directement une opération de rendu sans refaire la sélection ni d'ailleurs le groupement. L'espace mémoire est libéré dès que le tile n'est plus visible. Cette stratégie permet d'avoir un bon positionnement des plantes et pas plus. En effet, le niveau de détail et les paramètres liés à l'atmosphère changent en fonction de la position de l'observateur. Par conséquent, sur le plan visuel et même géométrique, il n'y a pas de cohérence temporelle.

4.4.4 Quelques résultats

Les tests ont été effectués sur un PC-Pentium IV doté d'un processeur d'une fréquence de 2.33 GHz, d'un espace mémoire de 3.25 Go et d'une carte graphique Nvidia 8800 GTS à 640 Mo de mémoire propre. La première stratégie permet d'obtenir un taux de rafraîchissement de l'ordre de trois à quatre images par seconde pour un nombre de graines retenues égale à 158188 sur un nombre de 440278 points envoyés en moyenne. Pour le même point de vue, on obtient 10 images/s pour la deuxième stratégie et 11 à 12 images/s pour la troisième stratégie. Ce taux de rafraîchissement inclut le rendu du terrain, de l'atmosphère et des arbres avec une résolution écran de 1024 ×768 pixels. La proportion des taux de rafraichissement entre les differentes stratégies est relativement maintenu sur plusieurs points de vue (figure 4.15). Toutefois, en terme de qualité, les images obtenues sont très réalistes (figure 4.16).

120 600000 Sélection Points envoy és Graines générées 100 Rendu Plantes 500000 Groupement 80 Rendu 400000 Atmosphère Rendu Terrain 60 300000

40 200000

20 100000

0 0 100 200 300 400 500 600 700 800 900 1000 0 200 400 600 800 1000 1200

Figure 4.15 – Temps d'exécutions (ms) de chaque phase en fonction de la densité des points par motif.

- 105 - Chapitre 4 : Résultats et discussion

Couverture du sol (LCC) de la Haute Savoie Amplification de la Haute Savoie

Prise en compte d’effets atmosphériques Transition textures/objets3D

Couverture du sol (LCC) à l'échelle planétaire Amplification temps réel de la map LCC

Amplification de la planète Rendu des arbres en coché de soleil Figure 4.16 – Quelques prises de vue sur de différents endroits de la terre amplifiés par des arbres.

- 106 - Chapitre 4 : Résultats et discussion

4.5 Conclusion

Ce chapitre a été consacré à une présentation détaillée de l’implémentation réalisée, des tests effectués ainsi que les résultats obtenus. Deux cas de terrains expérimentaux ont été utilisés pour valider notre démarche : la zone de la Haute Savoie et la planète entière. Le terrain de la Haute Savoie a été exploité pour faire une description détaillée de l’intégralité de l’implémentation de la démarche proposée. Les résultats obtenus sont satisfaisants, en terme de qualité des images générées et du taux de rafraîchissement atteint relativement à la quantité importante de données manipulées. Les tests effectués utilisent principalement, dans la phase d’amplification, trois modèles d’arbres décrits dans la carte de couverture, alors que notre démarche est capable de traiter jusqu’à 255 types d’espèces sans engendrer une répercussion importante sur les performances obtenues. Par ailleurs, notre modèle de graines a été intégré au moteur de rendu Proland développé par l’équipe EVASION opérant sur la planète entière. Les résultats obtenus sont meilleurs en terme de qualité d’images grâce à la modélisation de l’atmosphère dans Proland , elle-même prise en compte par notre modèle de graines. Notre plate-forme a l’avantage d’être modulaire, ce qui facilite les coûts de mise à jour des différents modules. De plus, les performances de la démarche proposée sont fortement liées à celles des cartes graphiques utilisées. Les nouvelles générations de cartes ont l’avantage de supporter l’exécution de OpenGL 3.x qui leur est optimisé et adapté. Bien que les résultats présentés dans ce chapitre soient encourageants, ils ont, cependant, été obtenus avec une carte graphique ancienne et sous une version antérieure d’OpenGL.

- 107 -

Conclusions et Perspectives

Conclusions et perspectives

Conclusions et perspectives

Le rendu en temps réel de terrains est un domaine de recherche qui a pris beaucoup d’ampleur depuis une dizaine d'années. Plusieurs applications ( Google Earth , World Wind , GeoPortail , Flight Simulator , etc.) ont vu le jour grâce aux différents algorithmes qui y ont été proposés. Avec la vulgarisation de l’outil informatique, l’impact de ces applications sur le quotidien des personnes est devenu très important. Cependant, elles nécessitent généralement une quantité de calcul considérable, effectuée jusque là sur CPU d’une manière séquentielle, ce qui ralentissait leur exécution.

Dans cette thèse, nous avons pallié à ce problème en proposant une approche qui tente de déporter le maximum de calculs sur GPU, connu pour être beaucoup plus rapide que le CPU. Ceci a eu pour conséquence une augmentation considérable de la marge d’interactivité.

L’approche proposée a permis de rendre de grands terrains tout en amplifiant le sol par des objets naturels du sursol (de type végétal et/ou minéral). Pour cela, quatre modules ont été développés sur GPU:

- Les deux premiers s’occupent du calcul de la liste des textures nécessaires à l’habillage de la géométrie du terrain représentée en multi-résolution. Ils permettent de visualiser, en 3D, la géométrie du terrain tout en l’habillant avec les textures adéquates et cela quelque soit la position de l’observateur. Ces deux modules restent toujours actifs durant l’exécution de notre plate forme.

- Les deux autres s’activent seulement lorsque l’observateur s’approche du sol, là où l’amplification devient nécessaire. Ils implémentent une étape de sélection et d’instanciation des caractéristiques géométriques et texturales des objets du sursol. En se basant sur une carte de couverture du sol, ces objets sont sélectionnés et leurs caractéristiques (taille, orientation, niveau de détail, couleur) subissent des perturbations pseudo-aléatoires. Ces perturbations permettent de créer une diversité géométrique et texturale à partir d’un nombre restreint d’objets du sursol, telle qu’elle est observée dans la nature. Ensuite, la géométrie habillée des objets du sursol est affichée sur le terrain en exploitant le mécanisme d’ instancing , implémenté dans le hardware des dernières générations de processeurs graphiques, afin d’accélérer leur rendu.

- 108 - Conclusions et perspectives

Les tests effectués sur les deux terrains (Haute Savoie et planète entière) témoignent de la qualité des résultats obtenus. En matière de fluidité d’affichage ou d’interactivité, les taux de rafraîchissement ( frame rate ) obtenus sont largement satisfaisants (autour de 70 images/seconde, ou plus, sur certains points de vue comprenant jusqu'à 70.000 objets du sursol). En matière de qualité visuelle, les résultats sont tout autant acceptables, car la géométrie du sol ainsi que son habillage sont effectués en multi-résolution, ce qui permet d’éviter le problème de popping (transition brutale entre des niveaux de détails). De la même manière, le rendu des objets 3D du sursol est également effectué en plusieurs niveaux de détail. De plus, la diversité engendrée par l’étape de sélection et d’instanciation améliore la qualité visuelle des scènes obtenues en proposant une variété géométrique et texturale riche à partir d’un nombre restreint d’objets.

Comme perspectives à notre travail, nous proposons d’étendre le mécanisme de chargement progressif de textures au cas de la planète entière. Cela devrait être possible si nous projetons une géométrie grossière de la planète sur les six faces d’un cube (où chaque face est représentée par une texture), afin d’estimer le niveau de détail avec lequel chaque partie de notre terrain devrait être texturée. La projection de cette géométrie devrait tenir compte de la courbure de la terre en limitant les distorsions engendrées par cette projection. Les modules d’analyse de ces textures devraient être soigneusement élaborés et implémentés d’une manière parallèle afin de calculer d’une manière efficace la liste des textures utiles au point de vue courant.

Enfin, nous proposons de mettre à jour nos codes OpenGL pour qu’ils puissent utiliser la nouvelle version 3.x qui propose plusieurs optimisations susceptibles d’accélérer l’exécution de notre plate forme.

- 109 -

Annexes

Annexe I

Annexe I Cartes Graphiques

Introduction La carte graphique est l’un des composants principaux dans un ordinateur. Elle peut être définie comme suit : « Une carte graphique ou carte vidéo (anciennement par abus de langage une carte VGA), ou encore Adaptateur graphique; est une carte d'extension d'ordinateur dont le rôle est de produire une image affichable sur un moniteur d'ordinateur. Elle permet de convertir les données numériques internes à l'ordinateur en un signal électrique numérique ou analogique compatible avec le moniteur ». L’historique des cartes graphiques a connu l’apparition trois générations : les cartes graphiques 2D, les cartes graphiques 3D non programmables et les cartes graphiques 3D programmables.

I.1 Cartes graphiques 2D

Le rôle des cartes graphiques 2D était, seulement, l’envoi de l’ensemble des pixels à afficher sur l’écran en plus de manipulations graphiques simples telles que le déplacement des blocs, tracé de lignes ou de polygones. Les différentes normes ou modes graphiques qui étaient utilisées sont: - MDA (Monochrome Display Adapter). Elle correspond à la première carte graphique. En 1981, IBM lance le standard MDA sur son premier PC. Le seul mode d’exploitation de la carte MDA est le mode texte en 25 lignes sur 80 colonnes. La carte MDA disposait d’un port imprimante. Puisque elle était monochrome sa mémoire vidéo supportait une seule page d'écran. Le contrôleur vidéo utilisé était le MC6845 de MOTOROLA.

- CGA (Color Graphics Adapter). Malgré que CGA soit sortie dans la même année que la carte MDA, elle avait en plus du mode texte en 25 lignes sur 80 colonnes, un mode graphique: 320x200 pixels avec 4 couleurs ou 640x200 en 2 couleurs. La carte CGA possédait un port série permettant son branchement à un téléviseur. En plus il y avait une sortie RVB (Rouge Vert Bleu). La carte CGA était destinée essentiellement aux jeux vidéo. Le contrôleur vidéo utilisé était le même que dans MDA : MC6845 de MOTOROLA.

- HGC (Hercules Graphics Card). HGC est une carte monochrome compatible avec MDA. Elle offre un mode graphique monochrome de 720x348. Elle est sortie en 1982 par HERCULES. Le contrôleur vidéo était encore le MC6845 de MOTOROLA.

- EGA (Enhanced Graphics Adapter). Après le succès de la carte Hercules, IBM sort, en 1985, la carte EGA (compatible avec MDA et CGA). Sa résolution maximum était de 640x350 en 16 couleurs avec une palette de 64 couleurs. Le contrôleur vidéo n’était pas le

- i - Annexe I

MC6845 mais plutôt les chips VLSI ( Very Large Scale Integration ). L’innovation était la possibilité d’utiliser des polices variables car des jeux de caractères pouvaient être chargés.

- VGA (Video Graphics Array). En 1987, IBM, encore une fois, lance la carte VGA. Elle était compatible avec MDA, CGA, EGA et avait une résolution de 640x480 sur 16 couleurs et 320x200 en 256 couleurs. C’était le premier standard à fonctionner en analogique offrant plus de 260,000 variations de couleurs. La RAM vidéo de la carte VGA avait une capacité entre 256 Ko et 512 Ko. La carte VGA disposait aussi de Bios Vidéo.

- SVGA (Super VGA). La carte SVGA est basée sur la norme VGA. Elle permettait d'afficher 256 couleurs aux résolutions 640x200, 640x350 et 640x480 tout comme la VGA et en plus elle affichait aux résolutions 800x600 et 1024x768. En 1990, le Video Electronics Standards Association ou VESA propose une interface logicielle standard VESA SVGA. A ce moment là, le processeur graphique GPU apparaît. Les cartes graphiques commencent ainsi à dessiner des courbes et des cercles ce qui a permis d’alléger le CPU.

I.2 Cartes graphiques 3D Dans le cas des images 3D, le PC se retrouve devant des calculs énormes pour satisfaire la cadence de 25 images par seconde (fluidité d'image de la télévision). Pour cela, le CPU ne suffit pas ; c’est la raison pour laquelle l’intervention d’un calculateur spécialisé est primordiale : c’est l’arrivée des cartes graphiques accélératrices 3D dotées d’un GPU. Les cartes graphiques récentes se composent de : processeur graphique GPU, mémoire vidéo, BIOS vidéo, RAMDAC, connecteurs, etc. (figure I.1)

Figure. A1.1 – Architecture d’une carte graphique 3D.

- Processeur graphique GPU (Graphical Processing Unit ). Il est considéré comme le composant le plus important de la carte graphique. Il prend en charge les calculs spécifiques à l’affichage, en particulier la 3D ce qui permet de soulager le CPU. Dans la plupart des cas, il est muni d’un ventilateur pour baisser sa température.

- Mémoire vidéo. Les données numériques sont conservées dans la mémoire vidéo. Après leur conversion en images par le GPU, ces dernières sont encore stockées dans la mémoire vidéo pour être affichées. Deux modes d'accès à la mémoire vidéo sont possibles :

- ii - Annexe I le premier permet de recevoir des informations à partir du système (accès direct comme dans la RAM), le deuxième est réservé pour l'affichage à l'écran (accès séquentiel).

- RAMDAC (Random Acces Memory Digital Analog Converter). Le RAMDAC convertit les images générées (qui sont stockées dans le Frame Buffer) par le GPU en des signaux analogiques afin d’être envoyées à l’écran. Les taux de rafraîchissement supportés par la carte graphique sont généralement déterminés par la fréquence du RAMDAC.

- BIOS vidéo. Comme le BIOS de la carte mère, le BIOS vidéo est un programme stocké dans une ROM incluant les paramètres de la carte graphique tels que les modes graphiques supportés.

- Interface. C’est le bus utilisé par la carte graphique pour communiquer avec la carte mère tel que ISA (1984), VLB, PCI (1994), AGP (1997), PCI-Express 1.1 (2004) et le PCI- Express 2.0 (2007).

- Connectique. Les connections qui existent aujourd’hui sont : VGA standard, DVI (Digital Video Interface), S-Vidéo (TV-out), HDMI (High Definition Multimedia Interface).

On distingue deux types de cartes graphiques 3D : non programmables et programmables.

I.2.1 Cartes non programmables Les cartes graphiques non programmables ne permettent pas aux utilisateurs une grande intervention, leurs fonctionnalités sont fixées au préalable par le fabricant. Elles sont divisées en deux générations.

I.2.1.1 Première génération. Les cartes graphiques 3D non programmables de la première génération se composent principalement d’un Setup Engine (découpe les polygones en quadrilatères et en triangles) et d’un Rendering Engine (génère les images à afficher), voir figure I.2.

Figure. A1.2 – Structure des GPU des cartes graphiques de la première génération.

La 3D sur PC fut premièrement proposée, en 1995, par Millenium. Le fabricant de chips 3DFX lance, en 1996, le processeur Voodoo1 pour faire face au défi des consoles des jeux. Il dispose d’un seul pipeline (la notion de pipeline est abordée dans la partie Pipeline Graphique). La première carte accélératrice est lancée en 1998 par 3DFX, c’est la qui contient deux pipelines et permet le mode SLI (possibilité de mettre deux Voodoo2 sur même ordinateur pour doubler les performances). Dans la même année, Matrox lance la carte PowerVR et Nvidia lance la carte TNT (NV4). En 1999 et après le succès de Voodoo2, 3DFX lance la qui est équivalent à deux Voodoo2 en

- iii - Annexe I parallèle. Dans la même année, Nvidia TNT2 (NV5) est apparue. C’était une version accélérée de la TNT1 gérant une mémoire et des textures plus grandes et un RAMDAC accéléré. Ainsi, cette génération de cartes graphique a rendu service au domaine des jeux vidéo qui ont pu atteindre un (taux de remplissage) de 300 Méga Pixels par seconde.

I.2.1.2 Deuxième génération. Les cartes graphiques 3D non programmables de la deuxième génération se composent d’un Transform Engine (applique les transformations aux polygones), d’un Lighting Engine (se charge de la gestion dynamique des effets de lumière) en plus du Setup Engine et du Rendering Engine (figure I.3).

Figure. A1.3 – Structure des GPU des cartes graphiques de la deuxième génération.

GeForce NV10. Tout d’abord, NVidia annonce le NV10 (GeForce256) : un véritable processeur graphique. Ce processeur, contient 23 Millions de transistors (Contre 10 Millions pour le Pentium2) et il dispose de deux étages dans le pipeline : Transform & Lighting (T&L). La transformation d'une scène 3D est très coûteuse et les effets de lumières sont gourmands en ressources, et c’est là où intervienne la nouvelle architecture du GeForce NV10. Le processeur peut être remplacé par le NV10 en ce qui concerne le calcul de scènes complexes car ce dernier prend en charge le pipeline 3D. Cela a permis des scènes détaillées, une intelligence artificielle complexe (car le CPU est soulagé). Le Fillrate du NV10 a atteint 480 Mpixels/s, sa puissance est de 15M de triangles /s (contre 4M pour un Pentium III 550MHz) et une scène optimisée pour le moteur T&L est alors 600% plus rapide. L’écriture en mémoire vidéo est effectuée directement sans passer par la mémoire système grâce à un noyau de 120MHz qui gérant l'AGP 4x "Fast-Write". A noter ici que puisque la GeForce peut produire un nombre important de polygones par seconde, de vraies vagues sur l'eau peuvent être créées sans passer par l'effet moins réaliste du Bump Mapping (une technique qui permet d’améliorer le réalisme des images, des textures et des objets dans un espace 3D en donnant l'illusion de profondeur grâce à des effets de relief).

Voodoo4 et Voodoo5. En 2000, 3Dfx lance Voodoo 4 & 5 composés de plusieurs processeurs de Voodoo 3. Cette dernière Voodoo ne prend pas en charge le T&L ; elle utilise par contre le FSAA (Full Screen Anti-Aliasing) qui fonctionne avec toutes les API. Voodoo4 et 5 n’ont pas atteint les performances de la GeForce.

GeForce NV15. En 2000, et après la réussite de la GeForce face à ses concurrents, elle annonce encore une nouvelle carte : NV15 GeForce2 GTS (Giga Texel Shader). Elle fonctionne à 200MHz au lieu de 120Mhz et possède un moteur de rendu (Texel Engine) avec 4 pipelines avec un Fillrate de 800M pixels/s. La carte GeForce 2 GTS manipule un nouvel effet: le Light Shader permettant de calculer l´intensité et la direction de la lumière au pixel près en temps réel. Ceci améliore le Bump Mapping donnant ce qu’on appelle Bump

- iv - Annexe I

Mapping Dot Product3. Puisque la GeForce 2 GTS était coûteuse, Nvidia lance la GeForce 2 MX qui est en quelque sorte une version légère de sa précédente. Les 2 moteurs de rendu possèdent 2 pipelines au lieu de 4. En plus de ça, la mémoire utilisée est la SDR au lieu de la DDR.

I.2.2 Cartes programmables NVidia GeForce 3 (NV20), apparue en 2001, est la première carte programmable (pipelines programmables). Elle supporte les fonctionnalités récentes de l'API de Microsoft, DirectX et plus particulièrement Direct3d : les shaders. Trois shaders ont été ajoutés pour faire le saut du pipeline fixe vers un pipeline programmable. Le vertex shader a remplacé le moteur T&L, le fragment shader (pixel shader) a remplacé le moteur de textures alors que le geometry shader a été ajouté entre l’étage d’assemblage des primitives et celui de rastérisation (figure I.5 et figure I.6). Toutes ces notions sont bien détaillées dans la prochaine partie Pipeline graphique. Avec l’arrivée des GPU à pipelines programmables, les leaders sont désormais Nvidia et ATI (tableau I.1). Le tableau suivant montre un historique des cartes de ces deux fabricants. Remarquez qu’en 2006, la plus récente génération des GPU intitulée G80 est apparue avec l’apparition de Nvidia 8800.

Année ATI (AMD depuis 2006) Nvidia 2001 FireGL, Radeon7000, 7200, 7500, 8500 GeForce 3 2002 , 9000, 9100, 9500, 9700 GeForce 4 2003 Radeon 9200, 9600, 9800 GeForce 5200, 5600, 5700, 5800, 5900 2004 Radeon 9250, 9550, X300, X600, X700, GeForce 4300, 5500, 5750, 5950, 6200, X800, X850 6600, 6800 2005 Radeon X1300, X1600, X1800 GeForce 7800 2006 Radeon X1650, X1900, X1950 GeForce 7100, 7300, 7600, 7900, 7950, 8800 2007 Radeon HD 2400, HD 2600, HD 2900, HD GeForce 8800, 8600, 8500, 8400 3800 Tableau. A1.1 – Cartes programmables conçues par les deux leaders Nvidia et ATI. Remarquez l’apparition de la génération G80 depuis fin 2006 (GeForce 8800).

La figure ci-dessous illustre l’évolution des GPU Nvidia contre les CPU Intel. On remarque bien que la puissance du GPU dépasse de loin celle du CPU.

Figure. A1.4 – Aperçu de la puissance calculatoire des GPU et CPU.

- v - Annexe I

Dans la section suivante, on jette un coup d’œil sur le pipeline graphique fixe et le pipeline programmable.

I.2.3 Pipeline graphique I.2. 3.1 Architecture Trois shaders ont été ajoutés pour faire le passage du pipeline fixe (figureI.5) vers un pipeline programmable (figureI.6). Le vertex shader a remplacé le moteur T&L et le fragment shader (pixel shader) a remplacé le moteur de textures alors que le geometry shader a été ajouté entre l’étage d’assemblage des primitives et celui de rastérisation (figureI.7). Dans la section suivante, nous reviendrons à la définition des shaders. Les différents étages du pipeline graphique programmable sont décrits, dans l’ordre, dans ce qui suit :

Vertex processors . Quand les données géométriques arrivent à l’étage Vertex Processors, les positions des vertex (sommets), les normales et les coordonnées de textures sont transformées (rotations, déplacements, changements d’échelle). Les calculs de l’éclairage (réflexion et réfraction) sont effectués pour modifier la couleur originale du vertex, les coordonnées de texture peuvent être automatiquement générées.

Figure. A1.5 – Architecture du pipeline fixe.

Figure. A1.6 – Architecture du pipeline programmable.

Puisque les deux fonctions les plus importantes du vertex processors sont la transformation et le calcul d’éclairage, cet étage est souvent appelé TRANSFORMATION

- vi - Annexe I

AND LIGHTING (T&L). A ce stade là, chaque sommet est traité indépendamment des autres vertex. Après le traitement des vertex, tous les attributs (couleur, position, normale, coordonnées de texture) associés avec chaque vertex sont complètement déterminés. Les vertex sont envoyés à l’étage suivant ASSEMBLAGE DES PRIMITIVES.

Assemblage des primitives. A ce stade, les vertex (sommets) sont rassemblés dans des primitives complètes. On exprime un point par un vertex, une ligne par deux vertex, un triangle par trois, un quadrilatéral par quatre, et un polygone peut être représenté par un certain nombre de sommets. L’étage de l’assemblage des primitives rassemble un nombre suffisant de vertices pour construire une seule primitive, puis cette primitive est passée au prochain étage.

Geometry processors. Le geometry shader est exécuté après le vertex shader et son entrée est la primitive entière ou bien celle avec des informations adjacentes. Par exemple, quand on opère sur des triangles, le nombre d’entrées pour le geometry shader est de trois vertices. Le geometry shader peut alors émettre zéro ou plus de primitives, qui sont rastérisées et leurs fragments passés par la suite au pixel shader.

Rasterization. Chaque vertex des primitives géométriques qui sont passées à travers le pipeline contient un ensemble de données. Les primitives (points, lignes, et polygones) sont décomposées en de petites unités correspondant aux pixels du frame buffer. Ce processus est appelé RASTERIZATION. Les petites unités générées par la rastérisation sont appelées FRAGMENT. Par exemple, une ligne peut couvrir cinq pixels sur l’écran, et le processus de rastérisation convertit cette ligne (définie par deux vertices) en cinq fragments. Un fragment contient les coordonnées de fenêtre ainsi que la profondeur et autres attributs associés (couleur, coordonnées de texture). La valeur de chaque attribut est déterminée par l’interpolation entre les valeurs spécifiées (ou calculées) des vertex de primitive.

Fragment Processors. Après la génération des fragments par la rastérisation, un nombre d’opérations est effectué sur eux. L’ensemble des opérations forme l’étage FRAGMENT PROCESSORS. L’opération la plus importante est, peut être, l’application des textures (). Autres opérations qui s’effectuent à ce point sont le brouillard (FOG) et la sommation de couleurs (COLOR SUM). La première consiste à modifier la couleur du fragment selon sa distance du point d’observation de la scène. La deuxième opération combine les valeurs de la couleur primaire et secondaire du fragment.

Per-Fragment Operations. Dans cet étage, les fragments sont soumis aux tests suivants: - Visibilité du pixel de destination ou obscurité, - Fixer les fragments contre une région rectangulaire, - Décider si on doit se débarrasser du fragment en se basant sur la valeur ALPHA du fragment, - Comparer la valeur dans le stencil buffer avec une valeur référence,

- vii - Annexe I

- Compare la profondeur du fragment entrant avec la profondeur sauvegardée dans le frame buffer .

Chaque opération per-fragment est conceptuellement simple et peut être implémentée d’une manière efficace sur matériel. Quelques opérations impliquent aussi la lecture de valeurs à partir du frame buffer (tels que la couleur, la profondeur, ou le stencil).

Frame Buffer Operations. L’étage FRAME BUFFER OPERATIONS manipule entièrement le frame buffer. L’effet global de ces étages est le fait que l’ensemble des primitives graphiques définies par l’application soit converti vers des pixels stockés dans le frame buffer pour un affichage ultérieur (figureI.7).

Figure. A1.7 – Fonctionnement du pipeline programmable.

La section suivante décrit les trois shaders qui font la distinction entre un pipeline programmable et un autre non programmable.

I.2. 3.2 Les Shaders Le terme shader vient du verbe anglais to shade qui veut dire ombrager, estomper ou nuancer. Un shader est un programme utilisé en synthèse d’images pour paramétrer une partie du processus de rendu réalisé par une carte graphique ou un moteur de rendu logiciel. La fonction d’un shader est la description de l'absorption et la diffusion de la lumière, la texture à utiliser, les réflexions et réfractions, l'ombrage, le déplacement de primitives et des effets post-traitement.

a) Le vertex shader Le vertex shader manipule les sommets du maillage à afficher et gère les transformations géométriques et les calculs d'éclairement qui y sont effectués. Il possède deux types de paramètres : variables (les sommets) et constants (les matrices de transformations qui ne sont d’autres que les opérations géométriques à appliquer aux sommets pour les projeter en 2D sur l'écran).

b) Le fragment shader Le fragment shader, ou encore pixel shader, sert à manipuler un pixel pour appliquer un effet sur une l’image : réalisme, Bump-Mapping (figureI.8), ombres, et des effets d’explosion.

- viii - Annexe I

C’est une fonction qui calcule les effets à base de pixel. Dépendamment de la résolution, un excès de deux millions pixels peut nécessiter un éclairage, un ombrage, et une coloration pour chaque frame.

Figure. A1.8 – Bump-Mapping : Sphère sans placage de relief (gauche). Relief qui sera appliqué à la sphère (centre). Sphère avec placage de relief (droite).

c) Le fragment shader Un geometry shader peut générer d’autres primitives à partir de celles qui existent comme les pixels, les lignes et les triangles. Le geometry shader peut être utilisé pour la génération d’une géométrie mosaïque, l’extrusion du volume d’ombre et le rendu à une passe pour un Cube-Map (figureI.9).

Figure. A1.9 – Cube-Mapping.

- ix - Annexe II

Annexe II Compute Unified Device Architecture (CUDA)

Introduction

Un processeur graphique programmable peut ne pas être uniquement exploité dans le domaine du graphisme car, en plus de sa fonction graphique, il possède une fonction calculatrice. En effet, étant donné que le GPU de la dernière génération a une architecture extrêmement parallèle composée de plusieurs processeurs indépendants (chacun ayant ses propres ressources), il peut être vu comme étant une unité de calcul très puissante qui même sert à alléger le CPU. Ce nouveau domaine est appelé GPGPU ( General-Purpose Computing on Graphics Processing Unit ) et vise à répondre à la question « Comment utiliser la carte graphique comme coprocesseur ? ». Pour plus d’informations, le lecteur peut consulter www.gpgpu.org . C’est vrai que dans les applications temps réel, la transformation et le rendu de la scène 3D doivent se faire au niveau du pipeline graphique programmable (les shaders), mais l’idéal serait de balancer, en plus, les calculs non graphiques immenses du CPU vers le GPU. Ceci peut se réaliser uniquement si on voit le GPU comme étant une unité parallèle de calcul graphique et non graphique à la fois. Pour atteindre ce but, Nvidia a conçu un langage de GPGPU, ou plus exactement une API pour ses cartes graphiques GeForce , Tesla et , qu’elle a appelé CUDA. L’acronyme CUDA vient de Compute Unified Device Architecture . Dans le guide de programmation CUDA 1.1, cette dernière est décrite comme étant une architecture matérielle et logicielle pour la gestion et le lancement des calculs sur GPU en tant qu’unité de calcul parallèle sans le besoin d’utiliser une API graphique ( Nvidia CUDA Programming Guide 1.1, 2007). La pile logicielle de CUDA est composée de plusieurs couches comme illustré dans la figure (figure II.1) : un pilote matériel, une interface de programmation d’application avec son Runtime , et deux bibliothèques mathématiques de haut niveau CUFFT et CUBLAS.

Figure. A2.1 – La pile logicielle de CUDA.

- x - Annexe II

L’API CUDA comprend une extension pour le langage de programmation C. Pour une programmation plus flexible, CUDA assure un adressage général à la mémoire DRAM comme illustré dans (figure II.2) par l’utilisation des deux opérations de mémoire Gather et Scatter. Du point de vue de la programmation, ceci se traduit comme la possibilité de lire et écrire l’information n’importe où dans la DRAM comme dans un CPU. CUDA est dotée d’un cache de données parallèle ou autrement dit d’une mémoire partagée embarquée ( on-chip shared memory) , avec des accès très rapides en lecture et écriture. La mémoire partagée est utilisée spécialement pour permettre aux threads (ou processus parallèles) de communiquer entre eux. La figure II.3 montre l’utilité de la mémoire partagée. Elle permet, en fait, aux applications de minimiser les accès à la mémoire DRAM . Donc, être moins dépendantes de la bande passante de la DRAM.

Figure. A2.2 – Les opérations mémoire Gather et Scatter .

Figure. A2.3 – La mémoire partagée rapproche les données des UALs (sans et avec mémoire partagée respectivement à gauche et à droite).

Dans le domaine du GPGPU, le GPU est vu comme étant un dispositif de calcul pouvant exécuter un nombre très élevé de threads en parallèle. Le GPU (ou device ) représente le coprocesseur du CPU (ou host ) et les calculs lourds se trouvant sur ce dernier seront chargés sur GPU. Plus précisément, une portion de l’application qui est exécutée plusieurs fois, mais indépendamment sur différentes données, peut être isolée dans une fonction s’exécutant sur le device en tant que plusieurs threads . La traduction de cette fonction en instructions prises en compte par le device donne ce qu’on appelle un kernel . Ce dernier est qualifié de GLOBAL qui désigne un programme s’exécutant sous GPU et étant appelé du

- xi - Annexe II

CPU. Le kernel peut, à son tour, utiliser des fonctions qualifiées DEVICE (s’exécutant sous GPU et étant appelé du GPU). Une fonction DEVICE peut également appeler une autre fonction DEVICE . Le groupe de threads qui exécutent un kernel est organisé comme une grille de blocs, où chaque bloc étant composé de threads (figure II.4).

Figure. A2.4 – Groupage des threads .

Un bloc est un groupe de threads qui peuvent coopérer ensemble en partageant les données à travers la mémoire partagée et en synchronisant leur exécution pour garantir des accès mémoire cohérents. Chaque thread est identifié par son thread ID qui est le numéro du thread à l’intérieur du bloc. Un bloc de threads peut être unidimensionnel, bidimensionnel ou tridimensionnel. La taille d’un bloc en threads est limitée à un seuil donné (selon la carte graphique). Cependant, pour permettre le lancement d’un nombre plus élevé que ce seuil, il est possible de regrouper des blocs, de même dimension et exécutant le même kernel , dans une grille. De cette manière, les threads appartenant à la même grille et à des blocs différents ne peuvent ni partager de l’information ni synchroniser entre eux. Le GPU exécute les blocs d’une grille en séquentiel s’il a des capacités limitées, entièrement en parallèle s’il a de grandes capacités parallèles, ou bien en combinant les deux variantes, ce qui est le cas de la plus part des algorithmes. Un bloc possède aussi un block ID qui est son numéro à l’intérieur de la grille. La grille peut être unidimensionnelle ou bidimensionnelle.

- xii - Annexe II

Les blocs qui sont traités par un multiprocesseur à la fois sont dits actifs . Chaque bloc actif est divisé en groupes SIMD de threads appelés warps . Chacun de ces warps contient le même nombre de threads et est exécuté par le multiprocesseur dans un mode SIMD. Un thread scheduler échange périodiquement d’un warp à un autre pour maximiser l’utilisation des ressources du multiprocesseur. Un half-warp est soit la première ou la deuxième moitié d’un warp . Précisons, ici, que pour de meilleures performances, il est déconseillé que le kernel soit de poids lourds (concernant le nombre de déclarations, le nombre d’instructions ou le type d’instructions). Ceci se répercute négativement sur le nombre de registres (ressources matérielles) utilisés par un thread . L’idéal serait si un thread exécute un kernel dont le nombre de registres ne dépasse pas 10 (sous une GeForce 8800 GTX), ainsi une bonne exploitation des ressources est obtenue. Le logiciel (fichier EXCEL ) CUDA Occupancy Calculator développé par Mark Harris (chercheur au niveau de Nvidia ) combine plusieurs facteurs (mémoire partagée, registres, nombre de threads par bloc, etc.) pour mesurer l’efficacité d’un kernel. Pour plus d’informations, le lecteur peut visiter le lien http ://developer.nvidia.com/cuda . Sous la partie Device de CUDA, un ensemble d’instructions propres au GPU est utilisé. Sous la partie Host , par contre, il existe deux API différentes : une API de bas niveau appelée Driver API et une autre de niveau plus haut appelée Runtime API . Il faut préciser qu’une application CUDA doit utiliser l’une des deux API: Driver API ou Runtime API et non pas les deux à la fois.

- xiii -

Bibliographie

Bibliographie

Bibliographie

[AM09] Amara, Y., Marsault, X.: A GPU Tile-Load-Map architecture for terrain rendering: theory and applications. Journal of the Visual Computer, volume 25(8), pages 805 –824, August 2009 . [AMM07] Amara, Y., Meunier, S., Marsault, X.: A G PU Framework for the Visualization and On-the-Fly Amplification of Real Terrains. ISVC 2007, Part 1, LNCS vol. 4841, pp. 586–597, Springer, Berlin, 2007. [AR60] Ahlfors, L.V., Sario, L.: Riemann Surfaces. Princeton University Press. Princeton Mathematics Series, No. 26 (32), 1960. [BAC96] Beers, A.C., Agrawala, M., Chaddha, N.: Rendering from compressed textures. In Proceedings of ACM SIGGRAPH, Proceedings, Annual Conference Series, pages 373–378, August 1996. [Bal03] Balogh, A.: Real-time visualization of detailed terrain. Thesis, Automatic and Computing University of Budapest, 2003. [BAV98] Balmelli, L., Ayer, S., Vetterli, M.: Efficient algorithms for embedded rendering of terrain models. In: Proceedings IEEE International Conference on Image Processing ICIP 98, pp. 914–918,1998. [BFH+04] Buck, I., Foley, T., Horn, D., Sugerman, J., Fatahalian, K., Houston, M., Hanrahan, P.: Brook for gpus : stream computing on graphics hardware. ACM Transactions on Graphics, 23(3) :777–786, 2004. [Bla07] Blanchet, J.: Modèles markoviens et extensions pour la classification de données complexes. PhD of Université Joseph-Fourier Grenoble I, France, 2007. [BLB+08] Boudaren, M., Labed, A., Boulfekhar, A., Amara, Y.: Hidden Markov model based classification of natural objects in aerial pictures. In: Proceeding of International Conference of Signal and Image Engineering, London, July 2008. [Bli78] Blinn. J.F.: Simulation of wrinkled surfaces. In Proceedings of ACM SIGGRAPH, volume 12(3), pages 286–292, August 1978. [BLV01] Balmelli, L., Liebling, T., Vetterli, M.: Computational analysis of 4-8 meshes with application to surface simplification using global error. In: Electronic Proceedings of the 13th Canadian Confe rence on Computational Geometry, 2001. [BO06] Boissonnat, JD., Oudot, S. : Provably Good Sampling and Meshing of Lipschitz Surfaces. In Proc. 22th Annu. ACM Sympos. Comput. Geom., 2006. [BPS+04] Bao, X., Pajarola, R., Shafae, M.: SMART: an efficient technique for massive terrain visualization from out-of-core. In: Proceedings Vision, Modelling and Visualization (VMV), pp. 413–420, 2004. [BVI91] Bennis, C., Vézien, J-M., Iglésias, G. : Piecewise surface flattening for non- Bibliographie

distorted texture mapping. In Thomas W. Sederberg, editor, ACM Transactions on Graphics, volume 25, pages 237–246, July 1991. Proceedings of ACM SIGGRAPH. [Cat74] Catmull, E.E.: A Subdivision Algorithm for Computer Display of Curved Surfaces. Phd thesis, University of Utah, December 1974. [CE98] Cline, D., Egbert, K. Interact ive display of very large textures. In Proceedings of VIS, pages 343-350, 1998. [CGG+03a] Cignoni, P., Ganovelli, F., Gobbetti, E., Marton, F., Ponchio, F., Scopigno, R.: BDAM: batched dynamic adaptive meshes for high performance terrain visualization. In: Proceedings EUROGRAPHICS, pp. 505–514, 2003. [CGG+03b] Cignoni, P., Ganovelli, F., Gobbetti, E., Marton, F., Ponchio, F., Scopigno, R.: Planet-sized batched dynamic adaptive meshes (P-BDAM). In: Proceedings IEEE Visualization, pp. 147–155. IEEE Press, Washington, DC, 2003. [CH02] Carr, N.A., Hart, J.C.: Meshed atlases for real-time procedural solid texturing. ACM Transactions on Graphics, 21(2) :106–131, 2002. [CMR+98] Cigogni, P., Montani, C., Rocchini, C., Scopino, R.: A general method for recovering attributes values on simplified meshes. Pages 59–66. ACM Press, 1998. [Coo02] Cool, M.: Sparse Texture Storage for Graphics Accelerators, 2002. Technical Talk. [DBH00] Dollner, J., Baumman, K., Hinrichs, K. Texturing techniques for terrain visualization. In Proceedings of VIS, pages 227-234, 2000. [DCS+02] Deussen, O., Colditz, C., Stamminger, M., Drettakis, G.: Interactive Visualization of Complex Plant Ecosystems. In: Proceedings of the IEEE Visualization Conference, IEEE Computer Society Press, 2002. [DDS+03] Decoret, X., Durand, F., Sillion, F.X., Dorsey, J.: Billboard Clouds for Extreme Model Simplification. Proceedings of the ACM Siggraph, 2003. [DHL+98] Deussen, O., Hanrahan, P., Lintermann, B., Mech, R., Pharr, M., Prunsinkiewicz, P.: Realistic Modeling and Rendering of Plant Ecosystems. In: Computer Graphics, Siggraph, 1998. [DMA02] Desbrun, M., Meyer, M., Alliez, P.: Intrinsic parameterizations of surface meshes. Computer Graphics Forum, 21(3) :209–218, 2002. [DN04] Decaudin, P., Neyret, F.: Rendering Forest Scenes in Real Time. Eurographics Symposium on Rendering Norrköping, Sweden 2004. [DWS+97] Duchaineau, M., Wolinsky, M., Sigeti, D.E., Miller, M.C., Aldrich, C., Mineev- Weinstein, M.B.: ROAMing terrain: Real-time optimally adapting mesh es. In: Proceedings IEEE Visualization, pp. 81–88,1997. [EKT01] Evans, W., Kirkpatrick, D., Townsend, G.: Right-triangulated irregular networks. Algorithmica 30(2), 264–286, 2001. [FFB+01] Fernando, R., Fernandez, S., Bala, K., Greenberg, D., P.: Adaptiv e shadow maps. In Proceedings of ACM SIGGRAPH, pages 387.390.ACM Press, 2001. [FH05] Floater, M.S., Hormann, K.: Surface parameterization: a tutorial and survey. In ISBN 3-540-21462-3 Springer, editor, Advances on Multiresolution in Geometric Modelling, 2005. [FMU05] Fuhrmann, A., Mantler, S., Umlauf, E. : Extreme Model Simplification for Forest Rendering. Eurographics Workshop on Natural Phenomena, 2005. Bibliographie

[FSH04] Fatahalian, K., Sugerman, J., Hanrahan, P.: Understanding the efficiency of gpu algorithms for matrix-matrix multiplication. In Proceedings of the ACM SIGGRAPH / Eurographics Conference on Graphics Hardware. Eurographics Association, August 2004. [FZP+93] Falby, J., Zyda, M., Pratt, D., Mackey, L.: NPSNET: hierarchical data structures for real-time 3-dimensional visual simulati on. Comput. Graph. 17(1), 65–69,1993. [Ger03] Gerstner, T.: Top-down view-dependent terrain triangulation using the octagon metric. Tech. Rep. Institute of Applied Mathematics, University of Bonn, 2003. [Ger99] Gerstner, T .: Multiresolution compression and visualization of global topographic data. Tech. Rep. 29. Institute for Applied Mathematics, University of Bonn,1999. [GGW+98] Guenter, B., Grimm, C., Wood, D., Malvar, H., Pighin, F.: Making faces. In Proceedings of ACM SIGGRAPH, pages 55–66. ACM Press, 1998. [GMN05] Gilet, G., Meyer, A., Neyret, F.: Point-based Rendering of Trees. Eurographics Workshop on Natural Phenomena, 2005. [GP00] Gerstner, T., Pajarola, R.: Topology preserving and controlled topology simplifying multiresolution iso-surface extraction. In: Proceedings IEEE Visualization, pp. 259–266. IEEE Press, Washington, DC 2000. [HAT+00] Haker, S., Angenent, S., Tannenbaum, A., Kikinis, R.: Conformal surface parameterization for texture mapping. IEEE Transac tion on Visualization and Computer Graphics, 6 :181–187, 2000. [Hec86] Heckbert, P.S.: Survey of texture mapping. IEEE Computer Graphics & Applications, 6:56–67, November 1986. [Hec90] Heckbert, P.S.: Adaptive radiosity textures for bidirectional ray tra cing. In Proceedings of ACM SIGGRAPH, pages 145–154. ACM Press, 1990. [HK95] Hebert, D., Kim, H.: Image encoding with triangulation wavelets. In: Proceedings of SPIE, vol. 2569, pp. 381–392. SPIE, Bellingham, WA 1995. [HM91] Heckbert, P.S., Moreton, H.: Interpolation for polygon texture mapping and shading. In State of the Art in Computer Graphics: Visualization and Modeling, pages 101–111. Springer-Verlag, 1991. [HM93] Hitchner, L.E., McGreevy, M.W.: Methods for user-based reduction of model complexity for virtual planetary exploration. In: Proceedings Symposium on Electronic Imaging, pp. 1–16. SPIE, Bellingham, WA 1993. [Hop98] Hoppe, H.: Smooth view-dependent level-of-detail control and its application to terrain rendering. In: Proceedings IEEE Visualization, pp. 35–42. IEEE Press, Washington, DC 1998. [HS93] Haeberli, P., Segal, M.: Texture mapping as a fundamental drawing primitive. In Proceedings of the Eurographics Workshop on Rendering, pages 259–266. Eurographics, 1993. [Hut98] Huttner, T. High resolution textures. In Proceddings of VisSym, 1998. [Kaj85] Kajiya, J.T.: Anisotropic reflection models. In B. A. Barsky, editor, Computer Graphics (Proceedings of SIGGRAPH), volume 19(3), pages 15–21, July 1985. [KE02] Kraus, M., Ertl, T.: Adaptive Te xture Maps. In Proceedings of the ACM SIGGRAPH / Eurographics Conference on Graphics Hardware, pages 7–15. Bibliographie

ACM SIGGRAPH, 2002. [KSG03] Kraevoy, V., Sheffer, A., Gotsman, C.:. Matchmaker: constructing constrained texture maps. ACM Transactions on Graphics, 22(3): 326–333, 2003. Proceedings of ACM SIGGRAPH. [LDN04] Lefebvre, S., Darbon, J., Neyret, F. Unified texture management on arbitrary meshes. Technical Report 5210, INRIA, May 2004. [Lef05] Lefebvre, S. : Modèles d'habillage de surface pour la synthèse d'images. Phd thesis, University of Joseph Fourier - Grenoble (UJF), 2005. [Lév01] Lévy, B.: Constrained texture mapping for polygonal meshes. In Proceedings of ACM SIGGRAPH, Computer Graphics Proceedings, Annual Conference Series, pages 417–424, August 2001. [Lev02] Levenberg, J.: Fast view-dependent level-of-detail rendering using cached geometry. In: Proceedings IEEE Visualization, pp. 259–266. IEEE Press, Washington, DC 2002. [LH04] Losasso, F., Hoppe, H.: Geometry clipmaps: terrain rendering using nested regular grids. ACM Trans. Graph. 23(3), 769–776, 2004. [LKH+95] Lindstrom, P., Koller, D., Hodges, L.F., Ribarsky, W., Faust, N., Turner, G.: Level-of-detail management for real-time rendering of phototextured terrain. Tech. Rep. TR 95-06, Graphics, Visualization, and Usability Center, Georgia Tech, 1995. [LKR+96] Lindstrom, P., Koller, D., Ribarsky, W., Hodges, L.F., Faust, N., Turner, G.A.: Real-time, continuous level of detail rendering of height fields. In: Proceedings ACM SIGGRAPH, pp. 109–118. ACM SIGGRAPH, New York,1996. [LP01] Lindstrom, P., Pascucci, V.: Visualization of large terrains made easy. In: Proceedings IEEE Visualization, pp. 363–370. IEEE Press, Washington, DC 2001. [LP02] Lindstrom, P., Pascucci, V.: Terrain simplification s implified: a general framework for view-dependent out-of-core visualization. IEEE Trans. Vis . Comput. Graph. 8(3), 239–254, 2002. [LPR+02] Lévy, B., Petitjean, S., Ray, N., Maillot, J.: Least squares conformal maps for automatic texture atlas generation. ACM Transactions on Graphics, 21(3):362–371, July 2002. Proceedings of ACM SIGGRAPH. [LPT03] Lario, R., Pajarola, R., Tirado, F.: Hyperblock-QuadTIN: Hyper-block quadtree based triangulated irregular networks. In: Proceedings IASTED Int ernational Conference on Visualization, Imaging and Image Processing (VIIP), pp. 733– 738, 2003. [MGA+03] Mark, W.R., Glanville, R.S., Akeley, K., Kilgard, M.J.: Cg: a system for programming graphics hardware in a c-like language. ACM Transactions on Graphics, 22(3) :896–907, 2003. [MN98] Meyer, A., Neyret, F.: Textures Volumiques Interactives. Journées Francophones d'Informatique Graphique, AFIG, pp 261-270, 1998. [MTP+04] McCool, M., Toit, S., Popa, T., Chan, B., Moule, K.: Shader algebra. ACM Transactions on Graphics, 23(3) :787–795, 2004. [MYV93] Maillot, J., Yahia, H., Verroust, A.: Interactive texture mapping. In Proceedings of ACM SIGGRAPH, Computer Graphics Proceedings, Annual Conference Series, pages 27–34, August 1993. Bibliographie

[OR99] Ohlberger, M., Rumpf, M.: Adaptive projection operators in multiresolution scientific visualization. IEEE Trans. Vis. Comput. Graph. 5(1), 74–93, 1999. [Paj98a] Pajarola, R.: Large scale terrain visualization using the restricted quadtree triangulation. In: Proceedings IEEE Visualization, pp. 19–26, 1998. [Paj98b] Pajarola, R.: Large scale terrain visualization using the restricted quadtree triangulation. Tech. Rep. 292, Dept. of Computer Science, ETH Zürich, 1998. [PAL02] Pajarola, R., Antonijuan, M., Lario, R.: QuadTIN: Quadtree based t riangulated irregular networks. In: Proceedings IEEE Visualization, pp. 395–402. IEEE Press, Washington, DC 2002. [PG07] Pajarola, R., Gobbetti, E.: Survey of semi-regular multiresolution models for interactive terrain rendering. Journal of the Visual Computer, vol.23 pp. 583- 605, 2007. [PMT+01] Proudfoot, K., Mark, W.R., Tzvetkov, S., Hanrahan, P.: A real-time procedural shading system for programmable graphics hardware. In Proceedings of ACM SIGGRAPH, Computer Graphics Proceedings, Annual Conference Ser ies, pages 159–170, August 2001. [Pom00] Pomeranz, A.A.: ROAM Using Surface Triangle Clusters (RUSTiC). Dissertation, University of California at Davis, 2000. [RAH07] Roger, D., Assarson, U., Holzschuch, N.: Efficient Stream Reduction on the GPU. Worksho p on General Purpose Processing on Graphics Processing Units, GPGPU 2007. [Rem96] Remila, E.: Approximate strip packing. In Proceedings of the 37th Annual Symposium on Foundations of Computer Science, page 31. IEEE Computer Society, 1996. [Riv93] Rivara, M.C.: A discussion on the triangulation refinement problem. In: Proceedings of the 5th Canadian Conference on Computational Ge ometry, pp. 42–47, 1993. [Riv95] Rivara, M.C.: A discussion on mixed (longest-side midpoint insertion) delaunay techniques for t he triangulation refinement problem. In: Proceedings of the 4 th International Meshing Roundtable, pp. 335–346, 1995. [RLI+99] Reddy, M., Leclerc, Y., Iverson, L., Bletter, N.: TerraVision II: visualizing massive terrain databases in VRML. IEEE Comput. Graph. Appl. 19(2), 30– 38, 1999. [Sam89a] Samet, H.: Applications of Spatial Data Structures: Computer Graphics, Image Processing, and GIS. Addison Wesley, Reading, MA 1989. [Sam89b] Samet, H.: The Design and Analysis of Spatial Data Structures. Addison Wesley, Reading, MA 1989. [SH02] Sheffer, A., Hart, J.: Seamster: Inconspicuous low-distortion texture seam layout, 2002. [Siv96] Sivan, R.: Surface modeling using quadtrees. Tech. Rep. CS-TR-3609, University of Maryland, College Park, Computer Vision Laboratory, Center for Automation Research 1996. [Smi84] Smith, A., R.: Plants, Fractal and Formal Languages. In: Proceedings of Siggraph, 1984. [SS92] Sivan, R., Samet, H.: Algorithms for constructing quadtree surface maps. In: Proceedings of the 5th International Symposium on Spat ial Data Handling, pp. Bibliographie

361–370, 1992. [SSG+01] Sander, P.V., Snyder, J., Gortler, S.J., Hoppe, H.: Texture mapping progressive meshes. In Eugene Fiume, editor, Proceedings of ACM SIGGRAPH, pages 409–416. ACM Press, 2001. [SW06] Schneider, J., Westermann, R.: GPU-friendly high-quality terrain ren dering. J. WSCG 14(1–3), 49–56, 2006. [TMJ98] Tanner, C., Migdal, J., Jones, T. The Clipmap : A Virtual Mipmap. In Proceedings of ACM SIGGRAPH, pages 151.158. ACM SIGGRAPH, July 1998. [VB87] Von Herzen, B., Barr, A.H.: Accurate triangulations of deformed, intersecting surfaces. In: Proceedings ACM SIGGRAPH, pp. 103–110. ACM SIGGRAPH, New York, 1987. [Vel01] Velho, L.: Using semi-regular 4-8 meshes for subdivision surfaces. J. Graph. Tools 5(3), 35–47, 2001. [VG00] Velho, L., Gomes, J.: Variable resolution 4-k meshes: concepts and applications. Comput. Graph. Forum 19(4), 195–214, 2000. [Whi80] Whitted, T.: An improved illumination model for shaded display. Communications of the ACM, 23(6) :343–349, June 1980. [Wil78] Williams, L.: Casting curved shadows on curved surfaces. Pages 270-274. ACM, ACM Press, 1978. [Wil83] Williams, L.: Pyramidal parametrics. In Computer Graphics (Proceedings of SIGGRAPH), volume 17, pages 1-11, July 1983. [Wlo04] Wloka, M.: Optimizing the . In: Programming Graphics Hardware (Eurographics 2004 Tutorial No. 4). Eurographics Association, Aire- la-Ville, Switzerland, 2004. [WMD+04] Wahl, R., Massing, M., Degener, P., Guthe, M., Klein, R.: Scalable compression and rendering of textured terrain data. J. WSCG 12, 521–528, 2004. AMAP botAnique et bioinforMatique de l'Architecture des Plantes, http://amap.cirad.fr/. Eingana Le premier atlas vivant en 3D et images satellite, Cdrom, EMG, 2001. AR08 Activity Report: Virtual environments for animation and image synthesis of natural objects. RGD73-74 Régie de Gestion des Données des Deux Savoie. http://www.rgd73-74.fr. Xfrog http://www.xfrogdownload.com.

Titre Développement d’une plate-forme de simulation de scènes 3D liées au sol et son occupation.

Résumé Largement poussés par l’industrie vidéo-ludique, la recherche et le développement d’outils destinés à la génération d’images de synthèse ont connu un essor important ces dernières années. Ces outils consistent, principalement, en un ensemble d’algorithmes et de matériels graphiques destinés à produire plus de réalisme et d’interactivité dans les scènes affichées. Notre travail de thèse s’inscrit dans cette perspective. Il consiste à développer une plate- forme de visualisation temps réel de larges terrains texturés tout en faisant surgir, dès que nécessaire, la géométrie verticale correspondant à l’occupation du sol. Ceci implique la manipulation d’une masse colossale de données (de type géométrique et photographique) sur des stations disposant de ressources limitées en espace mémoire et en capacité de calcul. Par ailleurs, les terrains ne représentent, généralement, que l’environnement extérieur nécessaire pour la majorité des simulations 3D. De ce fait, il est impératif de développer des mécanismes permettant l’exportation des calculs relatifs à la représentation de ces terrains sur le processeur graphique (ou GPU, Graphics Processing Units ). Ainsi, l’unité centrale (ou CPU) est libérée pour effectuer d’autres calculs propres à une simulation donnée. Nous avons abouti au développement, sur GPU, d’une plate-forme de visualisation 3D de vastes terrains, avec prise en compte des objets naturels (végétal et/ou minéral) habillant le sol. Les taux de rafraîchissement que nous avons obtenus sont suffisants pour garantir une visualisation 3D interactive avec un réalisme acceptable.

Mots-clés GPU, Pipeline graphique, CUDA, GLSL, Triangulation adaptative, Niveau de détail, Objets naturels, Visualisation 3D, Programmation parallèle.

Title A real-time framework for the visualization and amplification of large terrains.

Abstract Widely pushed by the videogame industry, the research of tools intended for computer-generated images has known a mattering development these last years. These tools consist mainly of a set of algorithms and graphic equipments intended to produce more realism and interactivity in the displayed scenes. Our thesis work joins this perspective. It consists in developing a platform of real-time display of wide textured landscapes while making appear, whenever necessary, the vertical geometry corresponding to the land use. This implies the manipulation of a colossal mass of data (of geometrical and photographic type) on computer stations having limited resources in memory space and in computation capacity. Moreover, for the majority of 3D simulations, landscapes represent generally only the necessary outside environment. Therefore, it is imperative to develop mechanisms allowing the export of the calculations related to the representation of these landscapes on the Graphics Processing Unit (GPU). Hence, the Central Processing Unit (CPU) is freed to make other important calculations that are specific to a given simulation. We have achieved the development, on GPU, of a platform of 3D display of vast grounds, while considering the natural objects (plant and/or mineral) dressing the ground. The rates of refreshment that we have obtained are sufficient to guarantee an interactive 3D visualization with an acceptable realism.

Keywords GPU, Graphics pipeline, CUDA, GLSL, Adaptive triangulation, Level-Of-detail, Natural objects, 3D visualization, Parallel programming.