Affichage et rendu 3D pour un environnement Java d`analyse d`image

publicité
Master 2 IICI - Projet 150 heures – année 2007/08
Affichage et rendu 3D pour un environnement
Java d'analyse d'image
Encadrant : Sébastien Lefèvre
Etudiants : Matthieu Dirrenberger / Vincent Colas
Rapport de projet 150h – M2 IICI – Affichage et rendu 3d pour un environnement Java
1
Rapport de projet 150h – M2 IICI – Affichage et rendu 3d pour un environnement Java
Sommaire
Introduction............................................................................................................................................. 3
Les Choix technologiques ........................................................................................................................ 4
OpenGL 2.0 .......................................................................................................................................... 4
Shaders GLSL ....................................................................................................................................... 5
Java 3d ................................................................................................................................................. 6
JOGL ..................................................................................................................................................... 6
Mise en place de JOGL............................................................................................................................. 8
Installation ........................................................................................................................................... 8
Configuration de la machine virtuelle Java ......................................................................................... 8
Matériel graphique requis : ................................................................................................................. 8
Algorithme de rendu 3d topographique ................................................................................................. 9
Algorithme ........................................................................................................................................... 9
Algorithme de rendu volumique : ......................................................................................................... 11
Comment afficher 134 000 000 de cubes ?....................................................................................... 11
Comment passer de 1Go à 10 Mo de données et l’animer de façon fluide ? ................................... 12
Algorithme : ....................................................................................................................................... 13
Exemples : ......................................................................................................................................... 14
Traitements d’image 2d accélérés par Shaders : .................................................................................. 16
Les filtrages :...................................................................................................................................... 16
Le FrameBuffer : ................................................................................................................................ 18
Algorithmes divers :........................................................................................................................... 18
Conclusion : ........................................................................................................................................... 19
2
Rapport de projet 150h – M2 IICI – Affichage et rendu 3d pour un environnement Java
Introduction
Le sujet que nous avons choisi de traiter consiste à pouvoir visualiser en 3d des données n’étant pas
initialement prévues pour un rendu 3d. En effet, les coupes 2d d’un scanner ne sont pas aisément
visualisables, car elles nous donnent des données volumiques et non pas surfaciques, ce qui pose
quelques problèmes tels que la taille des données à traiter ou des soucis de qualité d’affichage.
Le travaille réalisé s’articule autours du la librairie Pelican qui est une plate forme de développement
et d’outils liés à l’imagerie 2d. Cette plate forme est développée en Java permettant ainsi une grande
compatibilité et une redistribution on-line plus facile.
Nous verrons par la suite les choix techniques que nous avons faits pour pouvoir intégrer nos outils
de visualisation 3d à Pelican, puis nous présenterons une méthode de rendu 3d topographique pour
images 2d en niveaux de gris, ainsi qu’une méthode de rendu 3d volumique de coupes en niveaux de
gris. Enfin nous présenterons quelques techniques de traitement d’image 2d développées grâce aux
shaders qui permettent un traitement très rapide des images, notamment une technique basée sur
le « frame buffer » qui permettra d’affiner le rendu 3d en temps réel.
3
Rapport de projet 150h – M2 IICI – Affichage et rendu 3d pour un environnement Java
Les Choix technologiques
OpenGL 2.0
Dans un souci de compatibilité inter-systèmes il paraît évident d’utiliser OpenGL pour gérer
l’affichage 3d. OpenGL est une interface permettant de communiquer directement avec la carte
graphique en lui envoyant des primitives 3d telles que des coordonnées de sommets 3d à afficher. Le
seul concurrent sérieux d’OpenGL 2.0 est Microsoft DirectX 10, mais cela nous contraindrait à utiliser
uniquement Windows pour nos Viewers 3d car l’interfaçage DirectX/Java n’est que supporté sous
Windows dans Java3d. De plus cette version est incomplète par rapport à la version OpenGL de Java
3d.
Quand nous parlons d’OpenGL, nous précisons OpenGL 2.0 car nous utiliserons par la suite les
shaders GLSL (OpenGL Shaders Language) de la carte graphique, qui sont de petites unités de calcul
parallèles très utiles et puissantes. Il est à noter qu’OpenGL jusqu’à sa version 1.4 ne supporte pas la
programmation des shaders, et qu’ils ne sont disponibles qu’à partir de la version 2.0.
Pour pouvoir utiliser OpenGL en Java nous avons besoin de Binding Java/OpenGL. La plupart des
implémentations OpenGL sont écrites en C. Donc nous ne pouvons pas y accéder tel quel. On
utilisera JNI (Java Native Interface) qui permet d'utiliser du code natif écrit en C/C++ dans du Java.
Ceci permet de mettre en œuvre l'idée du binding OpenGL à travers JOGL. Il s'agit d'une API utilisant
JNI pour accéder à l'implémentation en C d'OpenGL. Donc toute cette gestion d'accès au code natif
est faite à l'intérieur de cette API. Au final, nous avons des API permettant d'utiliser l'OpenGL
(presque) comme si l'on développait en C. Pour ce qui est des performances, elles sont quasiment
identiques à celles du C (en ajoutant les appels JNI et diverses petites choses).
Il est nécessaire d’éclaircir quelques peu le fonctionnement des shaders GLSL car nous en parlerons
tout au long du rapport.
http://www.opengl.org/
4
Rapport de projet 150h – M2 IICI – Affichage et rendu 3d pour un environnement Java
Shaders GLSL
L’utilisation des shaders GLSL est primordiale, c’est là que réside tout l’intérêt d’OpenGL 2.0 en
permettant d’accélérer les calculs par le biais des unités de calcul vectorielles.
Ces deux vues du pipeline graphique permettent de voir la différence entre les « vertex programs »
gérants la géométrie c'est-à-dire les coordonnées des sommets dans R3, et les « fragments
programs » gérants le remplissage des polygones dessinés en appliquant une interpolation des
couleurs entre les différents sommets (une couleur est définie pour chaque sommet).
Il est avant tout important de comprendre que ces unités de calcul vectorielles sont nombreuses et
travaillent en parallèle pour accomplir ces tâches. Bien qu’étend initialement prévues pour gérer des
questions d’affichage 3d, nous allons montrer par la suite comment détourner leur utilisation en vue
de faire du traitement d’image 2d, et du rendu 3d topographique et volumique.
http://www.opengl.org/documentation/glsl/
5
Rapport de projet 150h – M2 IICI – Affichage et rendu 3d pour un environnement Java
Java 3d
Bien que nous utilisions JOGL, il paraît important de citer Java 3d qui aurait pu être utilisé. En effet,
Java 3d est une API interagissant avec OpenGL 1.4. Comme nous l’avons précisé précédemment
OpenGL 1.4 ne permet pas l’accès aux shaders, ce qui nous aurait pénalisés sachant que nous les
avons utilisés dans tous les algorithmes. Il faut cependant bien voir que si nous n’avons pas choisi
Java 3d, ce n’est pas pour son incapacité à gérer les shaders mais bien parce qu’il est trop lent pour le
volume de données que l’on a à traiter en rendu volumique. Bien qu’OpenGL fonctionne directement
avec le driver de la carte graphique, il est ici appelé par la machine virtuelle après interprétation du
code objet Java ce qui entraine une certaine perte de performances. Il faut également préciser que le
langage de l’API Java 3d est très différente syntaxiquement à OpenGL ce qui ne facilitera pas la
maintenance du code par une tierce personne. Au contraire JOGL reprenant exactement OpenGL, il
sera facile pour une personne connaissant OpenGL de reprendre le code.
Par ailleurs, Java 3d requiert également l’installation de dll ou de so dans son répertoire pour
pouvoir communiquer avec OpenGL.
Java3D est développé par Sun mais est devenu libre. Il n'évolue plus énormément pour privilégier
JOGL, mais depuis peu il a retrouvé un certain engouement auprès des développeurs. Le projet LG3D
de Sun (VM en 3D) l'utilise. Il est construit directement au dessus d'OpenGL et de Direct3D pour
Windows (même si cette dernière API va être abandonnée par Java3D). Il est encore pas mal utilisé
mais pas pour les jeux et autres applications où les performances sont primordiales. Cependant son
architecture est très bonne car il s'agit d’un modèle hiérarchique représentant le monde 3D, orienté
objet, sous forme d'un arbre acyclique.
JOGL
JOGL est la clé de voute du projet, c’est ce qui nous permet de réellement faire de la 3d. En effet
nous disions précédemment que Java 3d avait quelques problèmes de vitesse d’exécution et qu’il
n’intégrait pas la programmation des shaders ne gérant pas OpenGL 2.0 mais seulement OpenGL 1.4.
JOGL permet de régler ce problème car il fait le lien direct entre les commandes OpenGL dans le code
Java et le driver OpenGL 2.0 ce qui nous permet d’obtenir une vitesse d’exécution proche du C et
surtout cela nous permet de profiter pleinement d’OpenGL dans sa dernière version en passant outre
les problèmes d’interfaçage/surcouche logiciel de Java 3d.
L’API JOGL est développée par Sun et Silicon Graphics, elle est libre et est sous Licence BSD. C'est
l'API de référence pour faire de l'OpenGL en Java. JOGL est une API dans un style OO (Object
Oriented), c'est à dire que l'API est orienté objet, alors que l'implémentation en C ne l'est pas. Un des
points intéressants est le fait que le JSR-231 (évolution actuelle de JOGL) va remplacer l'ancien JOGL
et sera certainement incorporé directement dans le futur JDK. En effet pour le moment JOGL
nécessite l’utilisation de quelques dll ou .so pour fonctionner, et même si elles ne sont pas lourdes
(moins de 300 Ko) il faut encore les intégrer dans le répertoire où se trouve le Jar et indiquer le bon
ClassPath lors de l’exécution. Une fois le JSR-231 intégré au JDK, ces librairies dynamiques ne seront
plus nécessaires.
6
Rapport de projet 150h – M2 IICI – Affichage et rendu 3d pour un environnement Java
Un autre point intéressant est à prendre en compte. Si la librairie est intégrée au projet il deviendra
également possible de l’utiliser pour les applications 2d du projet Pelican. L’implémentation de Java
2d dans la version 6.0 du JDK (Mustang) permet une interopérabilité parfaite et puissante avec JOGL.
Il suffira d’utiliser des GLJPanel widget pour obtenir une intégration Swing à 100% accélérée de façon
Hardware par OpenGL. Ces accélérations peuvent notamment servir à améliorer la qualité de la
fluidité lors de lectures vidéo et non pas juste pour l’affichage 3d. Des explications sont données à
l’adresse suivante : https://jogl.dev.java.net/BOF-3908-JOGL-slides.pdf
Nous comprenons bien que le fait que c’est une réelle difficulté d’inclure des librairies sous forme de
dll ou so au projet, mais il faut voir qu’il sera impossible de traiter le problème du rendu volumique
sans utiliser OpenGL de façon directe. Pour donner un exemple en terme de performance, le rendu
avec utilisation de shaders n’est que moyennement fluide lorsque l’on tourne un objet codé en
niveau de gris sur 512*512*81 voxels, avec un PC équipé d’un processeur Intel E6600 Core2duo, de
2 Go de mémoire à 800MHz et d’une carte graphique GeForce 8800 GTS 640 Mo. On peut donc voir
ici que le problème de lenteur est déjà présent sans une gestion CPU de l’affichage mais uniquement
à cause des calculs intermédiaires effectués par Java qui ralentissent l’affichage. C’est pour ça qu’il
faut déporter un maximum les calculs vers le GPU.
Nous avons fait une version CPU de l’algorithme de rendu topographique qui fonctionne sans
shaders, mais cela n’enlève pas la contrainte d’avoir accès à OpenGL pour l’affichage… Nous
expliquerons également comment le faire pour le rendu volumique. Cependant cela demanderait
beaucoup de prétraitements, mais nous y reviendront en détails dans la partie traitant du rendu
volumique.
Pour résumer les avantages et les inconvénients des deux technologies existantes pour afficher de la
3d en Java :
-
Java 3d est plus lent mais plus objet, c'est-à-dire plus « Java »
JOGL est très similaire à OpenGL et donc très rapide avec une accélération matérielle égale à
ce que permet un programme codé en C. La seule limitation en performance viendra des
temps de traitements de données par Java.
7
Rapport de projet 150h – M2 IICI – Affichage et rendu 3d pour un environnement Java
Mise en place de JOGL
Installation
Pour faire fonctionner nos algorithmes dans Pelican, il faut installer la librairie JOGL et configurer le
CLASSPATH du système lors de l’exécution pour pouvoir accéder à la librairie.
L’installation de la librairie se résume à créer un répertoire contenant les fichiers suivants :
jogl.jar
jogl.dll / jogl.so
gluegen-rt.jar
gluegen-rt.dll / gluegen-rt.so
jogl_awt.dll / jogl_awt.so
Configuration de la machine virtuelle Java
On commence par configurer la machine virtuelle java pour avoir suffisamment de mémoire vive en
RAM allouée. On défini 1 Go de mémoire mémoire RAM allouée :
-Xmx1G
On désactive l’affichage standard pour Java 2d de manière à ce qu’il ne cause pas de conflits sous
windows et on active OpenGL (optionnel) :
-Dsun.java2d.noddraw=true
-Dsun.java2d.opengl=true
On utilisera la commande suivante pour configurer le CLASSPATH et lui indiquer où trouver la
librairie:
-Djava.library.path=C:\DIRECTORY –classpath
Dans le cadre de notre projet il sera plus simple d’intégrer les Jar dans le répertoire des librairies de
Pelican ainsi que les dll ou so correspondants.
Matériel graphique requis :
Cartes graphiques minimales supportant les shaders OpenGL 2.0 (fragments+vertex shaders):
-
nVidia GeForce 256
ATI Radeon 7500
S3 Savage 3D
8
Rapport de projet 150h – M2 IICI – Affichage et rendu 3d pour un environnement Java
Algorithme de rendu 3d topographique
L’algorithme de rendu 3d topographique est basé sur une technique classique utilisée en imagerie.
Nous l’avons adaptée de manière à utiliser les shaders pour le calcul de la hauteur, ce qui apporte un
gain de rapidité.
Le conceptt de base consiste à définir un pseudo cube dans lequel sera dessiné l’image 2d en niveau
de gris. Les axes X et Y restent similaires à ceux de l’image 2d originale. Seul l’axe Z varie en fonction
de l’intensité du niveau de gris de chaque pixel. Il en résulte
résulte une image dans laquelle les pixels
sombres sont plus bas et les pixels clairs sont plus hauts. Ce type d’image s’appel « carte de
hauteurs » d’une image.
Ce procédé est couramment utilisé en imagerie 3d pour stocker et afficher le relief d’un paysage à
grande échelle, cependant cela pose quelques limites. On ne peut pas avoir deux hauteurs
différentes au même endroit, donc les grottes et falaises abruptes sont impossibles à représenter
avec ce modèle. Ceci dit, il a l’avantage d’être léger et rapide à calculer.
Algorithme
L’algorithme utilise des GL_QUAD reliés entre eux. Chaque pixel correspond à un GL_QUAD et
chacun de ces GL_QUAD se situe à la hauteur normalisée correspondant à l’intensité du pixel
concerné. Un GL_QUAD est unee primitive OpenGL composée de quatre sommets dans R3, c'est-àc'est
dire un carré positionné dans un espace 3d.
Chacun des GL_QUAD a une taille correspondant aux dimensions de visualisations divisées par le
nombre de pixels à voir. Ainsi un shader détermine la position en X, Y en fonction des coordonnées
du pixel en cours de traitement. La position en Z du GL_QUAD est déterminée par l’intensité du pixel.
9
Rapport de projet 150h – M2 IICI – Affichage et rendu 3d pour un environnement Java
Exemple de code du shader concerné :
uniform float pasZ;
varying vec4 colors;
void main()
{
//gl_Position = gl_ProjectionMatrix * gl_ModelViewMatrix * gl_Vertex;
vec4 postmp=gl_Vertex;
colors=gl_Color;
float color=colors.r+colors.g+colors.b;
float tmp=(color/3.0);
vec4 pos=vec4(postmp.x,tmp,postmp.z,postmp.a);
gl_Position = gl_ProjectionMatrix * gl_ModelViewMatrix * pos;
}
Pour plus d’informations concernant le fonctionnement des shaders GLSL rendez-vous sur la page
suivante : http://www.opengl.org/documentation/glsl/
Il faut préciser que chacune des unités de calcul vectoriel de la carte graphique calcule en parallèle
un autre pixel. Sachant que dans une carte récente on trouve jusqu’à 128 unités de calcul, on peut
facilement imaginer le gain en temps de calcul par rapport à un calcul entièrement supporté par le
processeur central de la machine…
Voici un exemple de rendu topographique à l’aide notre viewer 3d topographique qui permet de
manipuler l’image grâce à un trackball virtuel :
10
Rapport de projet 150h – M2 IICI – Affichage et rendu 3d pour un environnement Java
Algorithme de rendu volumique :
L’algorithme de rendu volumique nous est de loin la chose qui nous a le plus intéressé dans ce projet.
La mise au point de cet algorithme nous ai pris beaucoup de temps, car il est délicat d’afficher un
grand nombre de voxels à l’écran.
Comment afficher 134 000 000 de cubes ?
Une première approche naïve que nous avons testée est d’afficher simplement chaque voxel sous la
forme d’un cube, sachant qu’un voxel s’apparente à un cube …
Pour donner un exemple concret, il suffit d’imaginer un petit
cube de voxels de 512*512*512, ce qui donne 134 217 728
voxels à afficher. Si l’on converti ce nombre en cubes, cela
revient à afficher: 134 217 728 voxels * 6 faces * 2 triangles
par faces soit 1 610 612 736 triangles. On ajoute à ce nombre
de triangles : 1 610 612 736 triangles * 3 sommets * 4 octets
pour stocker en mémoire les indices des sommets ce qui
donne 18 Go de données simplement pour stocker les
indices des sommets des triangles de nos faces… Pour la liste
des sommets on a 134 217 728 voxels * 8 sommets * 3
coordonnées * 4 octets (float) soit 12 Go de données. On précise bien sûr qu’on se situe dans le
cadre d’un modèle binaire et qu’il ne faut pas 4 octets pour stocker un niveau de gris…
Ces nombres éloquents démontrent clairement que même avec une bande passante de 1 To et des
capacités de plus en plus importantes, les cartes graphiques et les machines d’aujourd’hui arrivent
difficilement à calculer un tel affichage. Il faut préciser que ce calcul n’est vraiment pas optimisé
sachant que l’on peut assez facilement réduire le nombre de sommets en les partageant, de même
pour les faces. Cela nous amènerait tout de même à une charge mémoire de l’ordre du Giga octet ce
qui reste impossible à afficher tel quel. Bien sûr nous parlons ici d’un affichage pré-calculé et géré par
le CPU, l’affichage des données étant lui seul attribué à la carte graphique.
Nous avons tout de même testé cette solution pour vérifier rapidement que nos
données étaient bien chargées en mémoire. Il a fallu élargir quelques peu la
capacité mémoire de la machine virtuelle en mettant 1Go. Nous avons décidé
d’utiliser une technique de sous-échantillonnage, car nos machines n’arrivaient
pas à afficher le modèle de base. Le sous-échantillonnage a été testé à trois
niveaux 1/8, 1/64 et 1/512. Sous-échantillonner à 1/8 ne change pas beaucoup le
problème d’affichage. La machine arrive à afficher à raison d’une image toutes
les 15 secondes. Le sous-échantillonnage à 1/512 est quand à lui un peut trop
drastique… Enfin le sous-échantillonnage à 1/64 a donné des résultats
visuellement convenables, cependant, l’affichage reste trop lent avec une image
toutes les 3 secondes…
11
Rapport de projet 150h – M2 IICI – Affichage et rendu 3d pour un environnement Java
Comment passer de 1Go à 10 Mo de données et l’animer de façon fluide ?
On peut se demander comment gérer cet affichage car même si nous trouvons d’autres polygones
simplifiés permettant d’afficher le résultat de chaque voxel, il restera quand même 134 217 728
éléments à afficher. Nous avons du réfléchir autrement.
Si on part de la structure de données initiale, on obtient des coupes 2d empilées les unes sûr les
autres. Ces coupes 2d peuvent être vues comme des textures empilées ou plus simplement une
texture 3d. A partir de là, on sait que nos shaders peuvent faire des calculs et interagir lors du
remplissage de la couleur d’une texture.
L’idée finalement très simple est de charger chaque plan 2d du modèle de départ dans une texture
3d OpenGL. Cette texture pourra par la suite être traitée par le shader qui calculera le niveau de
transparence de chaque pixel et sa couleur. Toute la difficulté étant maintenant de trouver un
système d’affichage ne présentant pas d’artefacts trop flagrants. En effet, à partir du moment où l’on
affiche des textures sur des plans, un certain nombre de problèmes apparaissent. Lorsqu’on affiche
des plans parallèles les uns aux autres et que la profondeur en Z est simplement donnée par
l’espacement des plans il y a des zones vides qui sont visibles si l’on place une camera sur le côté.
Pour palier à ce problème nous avons créé un system qui fabrique des textures pour chaque angle de
vue. Ainsi les textures correspondantes à l’angle de vue courant sont affichées. Cela peut créer un
léger effet de « popping » si l’on déplace d’avant en arrière l’objet à une zone frontière, mais la
résolution étant généralement assez élevée, cela n’est pas vraiment problématique.
12
Rapport de projet 150h – M2 IICI – Affichage et rendu 3d pour un environnement Java
Dans les différents exemples qui suivront, c’est la carte graphique qui par le biais de ses unités de
calcul évalue pour chaque « pixel » son opacité et sa couleur, ce qui déporte un maximum les calculs
et laisse le CPU tranquille. Il est cependant possible de faire tout ces calculs sur le CPU en précalculant les pixels de chacune des 6 séries de textures possibles. Ce prétraitement prendrait
beaucoup de temps (plusieurs secondes) mais permettrait d’afficher simplement ces textures précalculées à l’aide d’OpenGL 1.4. L’intérêt serait simplement de pouvoir faire fonctionner l’algorithme
sur un ordinateur équipé d’une vieille carte graphique ne gérant pas les shaders 2.0 (cartes
graphiques avant 2003).
Algorithme :
13
Rapport de projet 150h – M2 IICI – Affichage et rendu 3d pour un environnement Java
Exemples :
Voici quelques exemples de résultats obtenus sur l’objet dont nous disposions. Il faut préciser que
cet objet a une résolution de 512*512*81 voxels ce qui représente tout de même 21 233 664 voxels,
ceci dit, l’objet s’anime de façon fluide lorsqu’on le fait pivoter à l’aide de la souris.
On peut voir sur ces exemples différents réglages de couleurs ou de transparences selon les
composantes (intervalles d’intensités) choisies. Grace à ces réglages, on peut facilement faire
ressortir la composante désirée.
14
Rapport de projet 150h – M2 IICI – Affichage et rendu 3d pour un environnement Java
Voici deux exemples en vues multiples :
15
Rapport de projet 150h – M2 IICI – Affichage et rendu 3d pour un environnement Java
Traitements d’image 2d accélérés par Shaders :
Lors de nos expérimentations durant la mise au point des algorithmes de rendu topographique et
volumique, nous avons utilisé des shaders. Maîtrisant bien l’utilisation de ces unités de calcul
performantes, nous nous sommes dit qu’il serait intéressant d’intégrer des traitements d’image 2d
classique dans Pelican grâce aux shaders.
Le schéma suivant illustre la façon la plus simple d’effectuer un traitement d’image 2d en la
chargeant sous la forme d’une texture appliquée sur un quad OpenGL que l’on envoie à la carte
graphique :
Les filtrages :
Les algorithmes de filtrages sont conçu d’une manière qui les rends très facilement parallelisables ce
qui nous a permis d’assez facilement intégrer les fonctions de filtrage classiques à Pelican sous forme
de shaders.
16
Rapport de projet 150h – M2 IICI – Affichage et rendu 3d pour un environnement Java
Voici le code d’un filtrage gaussien sous forme d’un fragment shader GLSL :
#define KERNEL_SIZE 9
const float kernel[KERNEL_SIZE] =
1.0/16.0,
2.0/16.0,
1.0/16.0,
};
{
2.0/16.0, 1.0/16.0,
4.0/16.0, 2.0/16.0,
2.0/16.0, 1.0/16.0
uniform sampler2D colorMap;
uniform float width;
uniform float height;
const float step_w = 1.0/width;
const float step_h = 1.0/height;
const vec2 offset[KERNEL_SIZE] = {
vec2(-step_w, -step_h), vec2(0.0, -step_h), vec2(step_w,
-step_h),
vec2(-step_w, 0.0), vec2(0.0, 0.0), vec2(step_w, 0.0),
vec2(-step_w, step_h), vec2(0.0, step_h), vec2(step_w,
step_h)
};
void main(void)
{
int i = 0;
vec4 sum = vec4(0.0);
vec4 tmp = texture2D(colorMap, gl_TexCoord[0].st + offset[0]);
sum += tmp * kernel[0];
tmp = texture2D(colorMap, gl_TexCoord[0].st + offset[1]);
sum += tmp * kernel[1];
tmp = texture2D(colorMap, gl_TexCoord[0].st + offset[2]);
sum += tmp * kernel[2];
tmp = texture2D(colorMap, gl_TexCoord[0].st + offset[3]);
sum += tmp * kernel[3];
tmp = texture2D(colorMap, gl_TexCoord[0].st + offset[4]);
sum += tmp * kernel[4];
tmp = texture2D(colorMap, gl_TexCoord[0].st + offset[5]);
sum += tmp * kernel[5];
tmp = texture2D(colorMap, gl_TexCoord[0].st + offset[6]);
sum += tmp * kernel[6];
tmp = texture2D(colorMap, gl_TexCoord[0].st + offset[7]);
sum += tmp * kernel[7];
tmp = texture2D(colorMap, gl_TexCoord[0].st + offset[8]);
sum += tmp * kernel[8];
gl_FragColor = sum;
}
Cet exemple nous montre très clairement qu’il est facile d’utiliser des unités de calcul vectorielles
pour ce type d’opérations.
17
Rapport de projet 150h – M2 IICI – Affichage et rendu 3d pour un environnement Java
Le FrameBuffer :
Le FrameBuffer est le buffer d’affichage d’OpenGL et il est intéressant de pouvoir faire des
traitements 2d dessus pour le rendu final.
Si on applique un filtrage 2d sur le FrameBuffer qui est similaire à une image ou une texture, on peut
filtrer le rendu d’une scène 3d. Comme par exemple faire un filtrage à l’aide d’une gaussien sur notre
rendu volumique pour lisser les imperfections graphique en temps réel.
Le point fort est le filtrage/traitement temps réel qui s’effectue sur une fenêtre de taille conséquente
en temps réel grâce aux shaders.
Exemple avec lissage Gaussien temps-réel sur la scène de rendu volumique:
Cette technique est d’ailleurs utilisée dans la plupart des jeux pour lisser le rendu sans consommer
trop de ressources.
La fonctionnalité n’est pas encore tout à fait implémentée par manque de temps, mais elle le sera
probablement rapidement.
Algorithmes divers :
Il sera tout à fait possible d’adapter d’autres algorithmes plus complexes aux shaders, c’est d’ailleurs
dans cette optique que nous avons testé les applications 2d avec shaders.
Les filtrages et le FrameBuffer sont les plus faciles à implémenter et par manque de temps, nous
avons préféré faire fonctionner ces algorithmes simples plutôt que de perdre trop de temps sur un
algorithme plus complexe qui n’aurait peut être pas fonctionné au final.
18
Rapport de projet 150h – M2 IICI – Affichage et rendu 3d pour un environnement Java
Sachant que le traitement 2d par shader n’était pas un élément du sujet nous n’avons pas passé trop
de temps dessus, cependant nos recherches ont permis d’aboutir à la conclusion suivante : Quand
Pelican intégrera JOGL, il sera possible de repasser un grand nombre d’algorithmes de traitements 2d
sur shaders et du coup rendra la plate forme beaucoup plus performante.
Certes le calcul vectoriel ne permet pas tout, mais les dernières évolutions en termes de pipeline des
cartes graphique permettent des traitements plus évolués avec des boucles et des accès en écriture
dans les textures. Il n’y a donc quasiment plus de limite concernant les algorithmes. Evidemment
certains algorithmes très linéaires et itératifs n’ont aucun intérêt à être codés de cette façon, mais
tous les autres ont tout intérêt à l’être.
Conclusion :
mlkmlk
19
Téléchargement