1

Graphe de Scène SceneGraph

Jean-Christophe Lombardo

[email protected]

2 Pattern composite

• Objectif : Traiter de façon unifiée un objet ou un composite • Moyen : Classe de base dérivée en feuille et en composite class Base {...};

class Leaf : public Base {...};

class Composite : public Base { public: void addChild(Base *) ... };

• Application au rendu 3D = graphe de scène !

[email protected]

3

Merci de votre attention ! 4

OpenGL 5 OpenGL

Très proche du hardware

Machine à états •Transformation courante •Matériaux courant •Texture courante •…

Pile pour stocker •Les transformations •Les attributs •... Performance : Limiter les changement d'état N'envoyer que ce qui est visible à la carte graphique

[email protected]

6 Comment ça marche ?

Mémoire Mémoire Graphique Principale r p n e f o O i f n

t p t u o a i n O z B t

e i

a r x e u m e e l t t g m r a s a a e a v r r

CPU E V R F F

GPU

[email protected]

7 Rappel : OpenGL = pipeline f d p TexCoord .

e TexCoord t Courante a t s / 1 . 1 n Vertex Matrice o i s r ModèleVue TexGen e Normale v

/ Normale s Courante c

e Éclairage & p Couleur s / Couleur Couleurs n Courante o Matrice i t a t Texture n Texture e

m Assemblage des primitives u

c Matrice o d

/ Projection g r o Viewport . l Clipping g (division par w) n e Pixel mode p o

. (stockage w / transfert) Rasterisation w w / / : p t t

h Frame buffer Mémoire Opérations sur les fragments (Image) Texture [email protected] 8 Rappel : OpenGL = pipeline f d p TexCoord .

e TexCoord t

Courante V a t s /

e 1 . 1

r n Vertex Matrice

t o i

e s r ModelVue TexGen e Normale x v

/ Normale s Courante c

e Éclairage & p Couleur s / Couleur Couleurs n Courante o Matrice i t a

P t Texture n Texture e

r m

Assemblage des primitives i u

m

c Matrice o d

/ Projection

i g

t r t

i o Viewport

. v l Clipping n g

(division par w) e n e e Pixel mode

s p o

. (stockage m w / transfert) Rasterisation w g w / / : a p Pixels t r t h Mémoire Frame buffer F Opérations sur les fragments (Image)0 Texture [email protected] 9 Exemple

• •

osgplanets [email protected]

10 Exemple : OpenGL

Draw sun

Rotate (Y)

Translate

Rotate (D)

Draw earth

[email protected]

11 Exemple : OpenGL

Draw sun

Rotate (Y)

Translate

glPushMatrix() Rotate (D)

Draw earth

glPopMatrix()

Rotate (M)

Translate

Draw moon

[email protected]

12 Exemple : Ajout d'une planète

• •

[email protected]

13 Exemple : OpenGL

Draw sun

Rotate (Y)

Translate

glPushMatrix() Rotate (D)

Draw earth

glPopMatrix()

Rotate (M) Rotate ? Translate Translate

Draw moon Draw mars

[email protected]

14 Exemple : OpenGL

Draw sun glPushMatrix()

Rotate (Y)

Translate

glPushMatrix() Rotate (D)

Draw earth

glPopMatrix() • Soit on anticipe et on Rotate (M) push/pop tout le temps glPopMatrix() → Performances ! Translate Soit on anticipes pas Rotate • Draw moon → maintenance du code ! Translate

Draw mars

[email protected]

15 Exemple : Graphe de Scène

• •

osgplanets [email protected]

16 Graphe de Scène

Composé de •Groupe •Feuille

[email protected]

17 Graphe de Scène

Approche Orientée Objet Composé de • Groupe – À des fils – Plusieurs types – Groupe – Transformation (Matrice) – Sélection – Niveau de détail – ... • Feuille – Effectue l'opération de dessin – De nombreux types

[email protected]

18 Exemple : Graphe de Scène

World

Rotate (Y) sun Translate

Rotate (M) Rotate (D) Translate

earth moon

[email protected]

19 Exemple : Graphe de Scène

World

Rotate (Y) Rotate sun Translate Translate

Rotate (M) Rotate (D) mars Translate

earth moon

[email protected]

20

Historique 21 Historique : Préhistoire et Antiquité

70s = PHIGS 80s = sgi ( Inc.) •IrisGL •SGI Onyx Reality Engine •Bas niveau, C 1992 : OpenGL 1.0 •Spécifications issues de IrisGL •Mark Segal et Kurt Akeley •Consortium •Bas niveau, C

[email protected]

22 Historique : Moyen âge

1988 : Iris Inventor (sgi) •Idée : simplifier l'écriture des appli 3D •Objectif : vendre des machines ! •Graphe de Scène, Librairies C++ •Problème : performance •Évolution – (sgi puisTGS) – OpenSource => Coin3D – VRML, X3D, ...

[email protected]

23 Historique : Renaissance

1991 : Iris Performer, OpenGL Performer, Performer (sgi) •Idée : Performance •Librairies C++ •Environnement complet pour l'écriture de simulateur : – Graphe de Scène – Gestion du parallélisme – Gestion de la mémoire – ...

1995-2000 Tentatives d'unification •Cosmo 3D, OpenGL ++, Fahrenheit, ... => Échecs

[email protected]

24 Bilan : deux approches

Famille Inventor Famille Performer •VRML, X3D, OpenSG, ... •Vega, VegaPrime, •Event driven OpenSceneGraph – Boucle passive •Framerate driven – Scène statique – Boucle active – Priorité Utilisateur – Scène dynamique •Création de scène et d'application – Priorité au rendu facile •Simulation •Performance – Multi thread (App Cull Draw) – Niveaux de détails – Database paging – Optimisations diverses

[email protected]

25 Ok, et le reste ?

VTK Ogre3D

Démarre fin 1993 Démarre fin 2001 Pipeline : on empile les filtres qui Wrapper orienté objet au dessus sont appliqués sur les data à la d'OpenGL et DirectX demande Pas vraiment d'organisation des → post traitement données

[email protected]

26

OpenSceneGraph

http://www.openscenegraph.org/projects/osg 27 OpenSceneGraph

Boite à outils graphique haute performances •Open Source •Multi plateformes – /unix – Windows – MacOS X •Graphe de scène → Framework Orienté Objet au dessus d' OpenGL Objectifs: •Libérer le développeur de l'implémentation et de l'optimisation des appels graphiques de bas niveaux •Fournir un ensemble d'outils permettant le développement rapide d'applications graphique (simulateurs, jeux, réalité virtuelle, visualisation scientifique, …)

[email protected]

28 OSG : Caractéristiques 1/2

•Performance – Culling (view-frustum, occlusion, small feature) – Sorting – Niveaux de détail (LOD) – À jour p/r OpenGL (2.x, 3.x, vertex array, vertex buffer objects, GLSL, …) – Accès facile à OpenGL (extension) •Code de très bonne qualité – Coding rules strictes et suivies – Design Patterns •Extensible – Plugins pour la lecture/écriture des données – Node Kits pour ajouter de nouvelles possibilités •Projets liés – Virtual Planet Builder (génération de terrain) – Present3D (+/- powerpoint 3D) – ... [email protected]

29 OSG : Caractéristiques 2/2

•Portable – IRIX, Linux, Windows, FreeBSD, Mac OSX, Solaris, HP-UX, AIX, OpenGL ES (iPhone & co) et même PlayStation2 ! – Coeur indépendant du système de fenêtrage – osgViewer → systèmes natifs X11, Win32 et Carbon – osgViewer → facilement intégrable (Qt, GLUT, FLTK, SDL, WxWidget, Cocoa MFC) – Interfaces avec Java, Lua et Python •Scalable – Multi CPU – Multi GPU •Communauté dynamique – Support – Extensions – Intégration avec d'autres API (Delta3D)

[email protected]

30 C++ Moderne

Utilisation de smartpointers standard template library Design pattern •Composite •Singleton •Chaine de responsabilité / Chain of responsibility •Visiteur / Visitor •…

[email protected]

31 Architecture

•Dernière version stable : 2.8.2 •Nodekits •Version actuelle : 2.9.6 – osgFX •Core – osgParticle – osg – osgSim – osgUtil – osgManipulator – osgDB – osgShadow •Viewer/Windowing Utility – osgTerrain – osgGA – osgText – osgViewer – osgAnimation – osgWidget – ... •Plugins – lecture/écriture (~70) – pseudo loader

[email protected]

32 Le coeur d'osg

•osg •osgUtil (cont') – Le scene graph lui meme – Modulaire, permet des (Node) implémentations alternatives – Les états openGL (Sate) – Les primitives (Drawable) •osgDB – Les maths – Interface d'entrée sortie – Quelques outils de base osgDB::readNodeFile(file); (ref_ptr, ...) osgDB::writeNodeFile(node, file); osgDB::readImageFile(file); osgDB::writeImageFile(img, file); osgUtil • – Système de plugins – La boite à outils d'osg REGISTER_OSGPLUGIN(ext, class) – Visiteurs – Outils de gestion de fichier – Optimisations (paths, exensions, etc) – Triangulations – Intersections

[email protected]

33 Viewer/Windowing Utility

•osgGA – Gestion d'évènements clavier/souris – Transforme les évènements en matrice (Manipulator)

•osgViewer – En remplacement de Producer (versions osg <2.0) – Fonctionnalité de haut niveau pour créer des viewer – Support des systèmes natifs (Win32, X11 et Carbon) – Facilite l'intégration dans des toolkits existants (Qt, wxWidget, ...) – Gestion de viewer composite (plusieurs vues, plusieurs scènes)

[email protected]

34 Nodekits 1/2

•osgFX – Gestion d'effets spéciaux (bump mapping, rendu cartoon, éclairage anisotrope) •osgParticle – Système de particules •osgSim – Extension pour la simulation visuelle (Cf flight simulator) •osgManipulator – Outils pour la manipulation 3D interactive (Cf. OpenInventor) •osgShadow – Gestion des ombres portées. Plusieurs méthode de calcul temps réel dispo. •osgTerrain – Extension pour la représentation de terrain, de SIG (Cf. VPB) •osgText – Gestion de textes de haute qualité

[email protected]

35 Nodekits 2/2

•osgWidget – GUI intégrée au graphe de scène •osgAnimation – Animation keyframe + interpolation •osgVolume – Rendu Volumique

Lien avec CAO / 3D Modelling Plugins import/export ou export seul pour les logiciels – 3DSMax – Maya – Blender – Microstation (DGN)

[email protected]

36 OpenThread

Projet frère, +/- intégré maintenant Couche fine au dessus des threads natifs (pthread, winthread, sproc) Gestion des thread (création, politique, priorité) et de la concurrence •Thread – Méthode run() virtuelle pure •Mutex – Exclusion mutuelle •Barrier – Attend que N Thread soient présents •... Rôle crucial dans une API comme celle là !

[email protected]

37 Les noeuds

osg::Referenced smartpointers

IO osg::Object Nom UserData

StateSet Sphère englobante osg::Node accept() du pattern visiteur Base du pattern composite

osg::Group osg::Geode

Composite Feuille Drawables

[email protected]

38 osg::Geode

Feuille du graphe Supporte la géométrie : 1 ou plusieurs osg::Drawable (abstract)

osg::Drawable

osg::DrawPixels osg::Geometry osg::ShapeDrawable

→ glDrawPixels() Primitives de bas Primitives de haut niveau : Triangles, niveau : osg::Shape : Quad, TriStrip, ... Box, Cone, Sphere, ...

+ NodeKits...

[email protected]

39 osg::Geode

Feuille du graphe, une seule dérivation : osg::Billboard Supporte la géométrie : 1 ou plusieurs osg::Drawable (abstract)

osg::Drawable

osg::DrawPixels osg::Geometry osg::ShapeDrawable

→ glDrawPixels() Primitives de bas Primitives de haut niveau : Triangles, niveau : osg::Shape : Quad, TriStrip, ... Box, Cone, Sphere, ...

En mode direct ou display list ou vertex buffer object, au choix !

[email protected]

40 osg::Group

Organise la hiérarchie du graphe Dérivé en une multitude de classes dont : •osg::Transform → fixe une position, orientation et facteur d'échelle (mat 4x4) – osg::MatrixTransform → accès directe à la matrice – osg::PositionAttitudeTransform → accès via pos, rot et scale – osg::AutoTransform → reste aligné par rapport à l'écran – osg::Camera → défini une caméra (viewport, projection, etc) •osg::Switch → permet d'afficher au choix l'un de ses fils, tous ou aucun •osg::Sequence → cycle automatiquement entre ses fils •osg::LOD → niveaux de détails, sélectionne le fils affiché en fonction de la distance de la caméra courante. – osg::PagedLOD → LOD dont les fils sont stockés sur disque. Gère le chargement/déchargement asynchrone des fils → scènes complexes •osg::LightSource → porte une osg::Light (glLight) •...

[email protected]

41 Conventions mathématiques

Système direct (main droite) comme OpenGL Z en haut, X vers l'est et Y vers le nord Matrices, vecteurs et quaternions •osg::Vec[234][fd] •osg::Matrix[fd] •osg::Quat Surcharge des opérateurs •S = v1 * v2 produit scalaire •v3 = v1 ^ v2produit vectoriel •M3 = M1 * M2 Multiplication de matrice •V' = v * M Multiplication matrice/vecteur

[email protected]

42 Conventions de Nommage

•Modules – namespace osg – include/osg – src/osg – lib/libosg.so •Classes : CapitalCapital → osg::MatrixTransform •Template - small_smal<> → osg::ref_ptr<> •Méthode - smallCapitalCapital → osg::Node::getStateSet() •Variable membre - _smallCapitalCapital → osg::Geometry::_vertexArray •Variable générale - smallCapitalCapital → int i •Variable statique - s_smallCapitalCapital → s_cantThinkOfName

[email protected]

43

Les états OpenGL 44 Les états OpenGL

Les modes et les attributs associés (voir glEnable, glGet) • glActiveTexture, glAlphaFunc, glBlendFunc, glClipPlane, glColorMaterial, glCullFace, glDepthFunc, glDepthRange, glFog, glLight, glLightModel, glLineWidth, glLineStipple, glLogicOp, glMap1, glMap2, glMaterial, glNormal, glNormalPointer, glPointSize, glPolygonMode, glPolygonOffset, glPolygonStipple, glSampleCoverage, glScissor, glStencilFunc, glStencilOp, glTexGen, glTexImage1D, glTexImage2D, glTexImage3D,... Définissent l' état de la machine OpenGL

Problèmes : • Changement d'état couteux • Gestion complexe (mode vs attribut)

[email protected] 45 États openGL : osg::StateSet

Performance → ne pousser que les attributs/modes modifiés • Un osg::State global à la scène • Des osg::StateSet sur les osg::Node et les osg::Drawable • Les attributs non modifiés sont hérités • Possibilité pour le père de forcer des StateSet sur ses enfants, et pour ses derniers de se protéger – OverrideValue = OVERRIDE | PROTECTED Facilité d'utilisation • une classe par attribut/mode • possibilité de fixer simultanément le mode et l'attribut • osg::Node::getOrCreateStateSet() osg::Drawable::getOrCreateStateSet()

[email protected]

46 Approche OpenSceneGraph

Performance → ne pousser que les attributs/modes modifiés • Un osg::State global à la scène • Des osg::StateSet sur les osg::Node et les osg::Drawable • Les attributs non modifiés sont hérités par défaut OverrideValue = OVERRIDE | PROTECTED | INHERIT Facilité d'utilisation • une classe par attribut/mode • possibilité de fixer simultanément le mode et l'attribut • osg::Node::getOrCreateStateSet() osg::Drawable::getOrCreateStateSet()

[email protected] 47 osg::StateSet

[email protected] 48 Exemple

root

sun earth moon

osg::ref_ptr root = new osg::Group; osg::ref_ptr sun = new osg::Geode; sun->addDrawable(new osg::ShapeDrawable( new osg::Sphere(osg::Vec3(0,0,0), 10))); root->addChild(sun.get()); osg::ref_ptr earth = new osg::Geode; earth->addDrawable(new osg::ShapeDrawable( new osg::Sphere(osg::Vec3(-20,0,0), 3))); root->addChild(earth.get()); osg::ref_ptr moon = new osg::Geode; moon->addDrawable(new osg::ShapeDrawable( new osg::Sphere(osg::Vec3(-25,0,0), 1))); root->addChild(moon.get());

[email protected] 49 Exemple

root

sun earth moon yellow blue

osg::ref_ptr yellow = new osg::Material; yellow->setDiffuse(osg::Material::FRONT, osg::Vec4(1,1,0,1)); sun->getOrCreateStateSet()->setAttribute(yellow.get());

osg::ref_ptr blue = new osg::Material; blue->setDiffuse(osg::Material::FRONT, osg::Vec4(0,.5,1,1)); earth->getOrCreateStateSet()->setAttribute(blue.get());

[email protected] 50 Exemple

root

sun earth moon yellow blue LINE FILL

sun->getOrCreateStateSet()->setAttribute( new osg::PolygonMode(osg::PolygonMode::FRONT_AND_BACK, osg::PolygonMode::LINE) );

earth->getOrCreateStateSet()->setAttribute( new osg::PolygonMode(osg::PolygonMode::FRONT, osg::PolygonMode::FILL), osg::StateAttribute::PROTECTED);

[email protected] 51 Exemple

root POINT

sun earth moon yellow blue LINE FILL

root->getOrCreateStateSet()->setAttribute( new osg::PolygonMode(osg::PolygonMode::FRONT, osg::PolygonMode::POINT) );

[email protected] 52 Exemple

root POINT

sun earth moon yellow blue LINE FILL

root->getOrCreateStateSet()->setAttribute( new osg::PolygonMode(osg::PolygonMode::FRONT, osg::PolygonMode::POINT), osg::StateAttribute::OVERRIDE );

[email protected] 53

Éclairage 54 Éclairage

Formulation générale (cas surfacique) L X ,  =L  X ,    X ,  ,L  X ,,d  0, 0 e 0, 0 ∫ bd 0, 0, i

[email protected] 55 Éclairage

Formulation générale (cas surfacique) L X ,  =L  X ,    X ,  ,L  X ,,d  0, 0 e 0, 0 ∫ bd 0, 0, i

La lumière reçue en X depuis la direction (θ ,φ ) o o

La lumière émise en X dans la direction (θ ,φ ) o o

La part de la lumière provenant du reste de la scène en X et réfléchie dans la direction (θ ,φ ) o o

[email protected] 56 Éclairage

Formulation générale (cas surfacique) L X ,  =L  X ,    X ,  ,L  X ,,d  0, 0 e 0, 0 ∫ bd 0, 0, i

BRDF (Bi-Directional Reflectance Distribution Function) La lumière reçue enCaractéristique X depuis la direction du matériau (θ ,φ ) Peut se mesurer o o Ratio de la lumière arrivant au point X La lumière émise en X dans la direction (θ ,φ ) depuis la direction (θ,φ) o o étant ré-émis dans la direction (θ ,φ ) o o

La part de la lumière provenant du reste de la scène en X et réfléchie dans la direction (θ ,φ ) Lumière incidente o o arrivant au point X depuis la direction

[email protected] 57 Éclairage

Formulation générale (cas surfacique)

L X ,  =L  X ,    X ,  ,L  X ,,d  0, 0 e 0, 0 ∫ bd 0, 0, i

Pas de solution analytique → Méthodes itératives et approximations • ρ constant – Surfaces diffuses – Radiosité ρ = ρ si ( (θ,φ) = sym (θ ,φ ) ), 0 sinon • 0 n 0 0 – Surfaces spéculaires – Lancer de rayons • Échantillonnage de stochastique ρ et de Ω – Monte Carlo

[email protected] 58 Ok, et OpenGL ?

Approximation tellement grossière qu'il est difficile de se ramener à l'équation de départ... Lumières et matériaux sont étroitement liés 3 composantes calculées aux sommets

[email protected] 59 Ok, et OpenGL ?

Approximation tellement grossière qu'il est difficile de se ramener à l'équation de départ... Lumières et matériaux sont étroitement liés 3 composantes calculées aux sommets • Ambiante – Constante

[email protected] 60 Ok, et OpenGL ?

Approximation tellement grossière qu'il est difficile de se ramener à l'équation de départ... Lumières et matériaux sont étroitement liés 3 composantes calculées aux sommets • Ambiante – Constante • Diffuse – Dépend de la direction de la source

[email protected] 61 Ok, et OpenGL ?

Approximation tellement grossière qu'il est difficile de se ramener à l'équation de départ... Lumières et matériaux sont étroitement liés 3 composantes calculées aux sommets • Ambiante – Constante • Diffuse – Dépend de la direction de la source • Spéculaire – Dépend de la direction de la source et de l'observateur Interpolation bilinéaire

[email protected] 62 Implémentation OSG

Lampe par défaut osg::Material • Interface de glMaterial • Ambiante, diffuse, spéculaire, émissive • Shininess, transparence osg::LightModel • Interface de glLightModel • Simple face ou double face osg::Light • Interface de glLight osg::LightSource • Place un osg::Light dans la scène

[email protected] 63 osg::Light (StateAttribute)

Implémente glLight • Numéro de lampe GL • Composantes (ambiant, diffus, spéculaire) • Position – osg::Vec4(x, y, z, w) – W = 0 → infini • Spot – Direction, cutoff (angle d'ouverture), exponent (netteté du bord) • Atténuation Constante k , linéaire k, quadratique k – c l q – En notant d la distance entre la source de lumière et l'objet 1 atténuation= 2 k cd kld k q

[email protected] 64 osg::LightSource (Group)

Un groupe avec un osg::Light osg::LightSource::setLight(osg::Light *)

Pas trop compris a quoi ça sert... a vérifier !

[email protected] 65 Exemple

root

sun earth moon yellow blue

[email protected] 66 Exemple

root

sun earth moon Light Source yellow blue light

osg::ref_ptr light = new osg::Light; light->setLightNum(0); light->setPosition(osg::Vec4(10,10,50,1)); light->setAmbient(osg::Vec4(1,0,0,1)); light->setDiffuse(osg::Vec4(1,1,0,1)); light->setDirection(osg::Vec3(0,0,-1));

root->getOrCreateStateSet()->setAttribute(light.get());

[email protected] 67 Exemple

root

sun earth moon Light Source yellow blue light

osg::ref_ptr light = new osg::Light; light->setLightNum(0); light->setPosition(osg::Vec4(10,10,50,1)); light->setAmbient(osg::Vec4(1,0,0,1)); light->setDiffuse(osg::Vec4(1,1,0,1)); light->setDirection(osg::Vec3(0,0,-1));

osg::ref_ptr ls = new osg::LightSource; ls->setLight(light.get());

root->addChild(ls->get());

[email protected] 68

Textures 69 Textures

Idée • Plaquer une image sur une géométrie • Ou plusieurs ! (multi-texturing) • Définir une fonction pour transformer les coordonnées 3D de l'objet en coordonnées 2D de l'image (mapping) Principe • Coordonnés de texture sur l'objet – Définies (comme les coordonnées) – Générées (osg::TexGen) • Définir la texture courante • Et le mode d'application Voir osgtexture2D

[email protected] 70 Texture 1D

+ =

[email protected] 71 osg::TexGen 1/2

1, 2, 3 ou 4 coordonnées (s, r, t, q) Mode • OBJECT_LINEAR → dans le repère de l'objet • EYE_LINEAR → dans le repère de l'œil

Chaque coordonnée est calculée comme la distance à un plan c = p x + p y + p z + p w • 1 2 3 4 où – c est la coordonnée de texture générée (s,r,t ou q), – (x,y,z,w) le point concerné, (p ,p , p , p ) le « plan » openGL spécifié – 1 2 3 4

[email protected] 72 osg::TexGen 2/2

Environnement mapping L'objet est un miroir parfait, il reflète son environnement Mode • SPHERE_MAP → comme si la texture était plaquée sur une sphère autour de l'objet. Demande une texture distordue. • NORMAL_MAP → utilise les normales comme coordonnées de texture • REFLECTION_MAP → utilise la direction de réflexion spéculaire (Fresnel)

α β

α = β

[email protected] 73

Rendu multi-passes Rendu multi-passes 74 Multipass rendering

Idée : • Dessiner plusieurs fois la scène pour obtenir des effets spécifiques Moyen • Utiliser des décorateurs – Groupe dont on modifie le osg::StateSet Exemple • Rendu scribe

[email protected] 75 Effet « Scribe » : 1ère passe

Root

Scene

[email protected] 76 Effet « Scribe » : 2ème passe

Root

Decorator

Scene

ss = decorator->getOrCreateStateSet(); ss->setAttributeAndModes( new osg::PolygonMode( osg::PolygonMode::FRONT_AND_BACK, osg::PolygonMode::LINE)); ss->setAttributeAndModes( new osg::PolygonOffset(1.1f, 4.0f)); ss ->setAttributeAndModes(new osg::LineWidth(2.0f)); ss->setMode(GL_LIGHTING, osg::StateAttribute::OFF); [email protected] 77 Effet « Scribe » : Résultat

Root

Decorator

Scene

[email protected] 78

Base de données 79 osgDB

Objectif • Localiser et charger des fichiers • Gestion des images et des scènes Moyens • Mécanisme de plugins • Identification par l'extension du fichier • Soit – Plugin déjà chargé et enregistré – Charger un librairie dynamique à la volé – Convention de nommage des librairies : osgdb_.so – Utilisation d'un proxy pour obtenir une instance La grosse astuce • Pseudo-loader

[email protected] 80 osgDB : Utilisation

Lecture de données • #include • Lecture d'une image: osg::Image *osgDB::readImageFile(const std::string &filename) • Lecture d'une scène: osg::Node *osgDB::readNodeFile(const std::string &filename) Écriture de données • #include • Écriture d'une image: bool osgDB::writeImageFile(osg::Image &img, const std::string &filename) • Écriture d'une scène: bool osgDB::readNodeFile(const osg::Node &scene, const std::string &filename)

[email protected] 81 osgDB : Comment ça marche ?

Une classe de base : osgDB::ReaderWriter • Avec des méthodes virtuelles – read/write pour les Image, les Node, les Shader, les HeightField, etc – bool acceptsExtension(const std::string &ext) const Renvoie vrai si l'extension est supportée, faux sinon • Et une gestion des archives, etc Un mécanisme de registre (osgDB::Registry) qui conserve un pointeur sur les instances des loader déjà chargés Une convention de nommage des librairies dynamiques Et un point d'entrée identifié

Les 3 derniers points se gèrent grâce à des macro → pas de prise de tête ! [email protected] 82

3 étapes pour une image 83 3 étapes pour une image 1/3

A chaque image (frame) •Update : – Traitement de l'interaction avec l'utilisateur – Simulation – Mise à jour de la scène et de la caméra •Cull : – Trier ce qui est visible de ce qui ne l'est pas – Organiser le graphe de rendu •Draw : – Dessiner effectivement les objets sélectionnés

[email protected]

84 3 étapes pour une image 2/3

Et tout ça en parallèle

Update f t 0

t+1

t+2

t+3

[email protected]

85 3 étapes pour une image 2/3

Et tout ça en parallèle

Update f t 0

Update Cull t+1 f f 1 0

t+2

t+3

[email protected]

86 3 étapes pour une image 2/3

Et tout ça en parallèle

Update f t 0

Update Cull t+1 f f 1 0

Update Cull Draw t+2 f f f 3 1 0

t+3

[email protected]

87 3 étapes pour une image 2/3

Et tout ça en parallèle

Update f t 0

Update Cull t+1 f f 1 0

Update Cull Draw t+2 f f f 3 1 0

Update Cull Draw t+3 f f f 2 3 1

[email protected]

88 3 étapes pour une image 3/3

Et dans le cas multi GPU

Update f t 0

Update Cull Cull Cull t+1 f f f f 1 0 0 0

Update Cull Cull Cull Draw Draw Draw t+2 f f f f f f f 3 1 1 1 0 0 0

Update Cull Cull Cull Draw Draw Draw t+3 f f f f f f f 2 3 3 3 1 1 1

p p p g g g 0 1 2 0 1 2

[email protected]

89

Culling 90 Rappel sur le volume de vue

Projection Projection orthographique perspective Viewing Frustum

Near Near Far Far L’observateur ne voit que les objets à l’intérieur du volume

[email protected]

91 View-frustum Culling

Niveau face : Niveau primitiveEcran : Coordonnées de la face projetéePrimitive hors de situé l’écran hors du volume englobant Face éliminée Primitive éliminée Un test par face, intérêt limitéUn test par primitive, intéressant, en particulier pour des objets avec beaucoup de triangles Géré automatiquement par OpenGLNon Géré par OpenGL

[email protected]

92 SceneGraph → Hiérarchie de Bounding Vol. cercles=BVs

scene graph root

[email protected]

93 SceneGraph → Hiérarchie de Bounding Vol. cercles=BVs

scene graph root

Culled ! Culled !

[email protected]

94 Comment ca marche pour une primitive ?

1. Calcul de la boîte englobante de la primitive (bounding box) . Précalcul (une seule fois pour toute la visualisation) si l’objet n’est pas déformable 2. Test de la position de la bounding box par rapport au volume de vue . Il y a culling seulement si la bounding box est entièrement à l’extérieur du volume de vue

[email protected]

95 SceneGraph → Hiérarchie de Bounding Vol. cercles=BVs

scene graph root

[email protected]

96

OpenGL Shaders 97 Shaders

Shader : anglais, du verbe to shade : ombrager ou estomper, nuancer Programmer certaines zones du pipeline • Vertex Shaders • Fragment Shaders (ou Pixel Shaders) Plusieurs langages • Cg -> Nvidia • HLSL = High Level Shading Language -> Microsoft (Direct X / XBox) • GLSL (GLSLang) = OpenGL Shading Langage (GL 2.0) Très puissant ! • Utilisé pour autre chose que du rendu 3D • GPGPU (General Purpose computing on Graphic Processing Unit) – Cuda (Nvidia) : – OpenCL : Open Computing Language

[email protected] 98 Shaders TexCoord TexCoord

Courante V

e

Vertex Matrice r

t ModelVue TexGen e

Normale x Normale Courante Éclairage & Couleur Couleur Couleurs Courante Matrice Texture Texture Assemblage des primitives t n

e Pixel mode (stockage m / transfert) Rasterisation g a r Mémoire F Opérations sur les fragments Texture [email protected] 99 2 types de shaders bien différents

Vertex shader • Transformations et éclairage • Floating point, Opérations complexes • Des centaines de millions de sommets par secondes Fragment shader • Mixage de couleur et textures • Fixed point, Opérations simples • Des dizaines de milliards de fragments par secondes

[email protected] 100 2 types de shaders bien différents

Vertex shader • Transformations et éclairage • Floating point, Opérations complexes • Des centaines de millions de s !!! s fixe sommets par secondes nalité ction s fon Fragment shader NT le ACE MPL • Mixage de couleurrs R Eet textures hade • FixedL epoints s , Opérations simples • Des dizaines de milliards de fragments par secondes

[email protected] 101 Fonctionnalité fixe : Vertex

• Transformation des sommets • Transformation et normalisation des normales • Génération des coordonnées de textures • Éclairage • Calcul des couleurs d'après les matériaux

[email protected] 102 Fonctionnalité fixe : Fragment

• Opération sur les valeurs interpolées • Accès aux textures • Mixage des couleurs

[email protected] 103 GLSL : Le langage

Proche du C/C++ • Un shader = Un programme = Une fonction main() • Des types • Des variables avec des modifieurs • Des fonctions • Des boucles et des branchements, ... • Accès aux entités OpenGL (ie gl_Vertex, gl_ModelViewMatrix, ...) Les programmes doivent être • Compilés • Et linkés • Pour pouvoir être exécutés..

• Possibilité d'avoir plusieurs « fichiers »

[email protected] 104 GLSL : Les Types 1/2

• Scalaires : float, int, bool • Vecteurs – float : vec2, vec3, vec4 – int: ivec2, ivec3, ivec4 – bool: bvec2, bvec3, bvec4 • Matrices mat2, mat3, mat4 (float uniquement) • sampler pour l'accès aux textures • Structures – Prédéfinies (ie struct gl_MaterialParameters) – Utilisateur • Tableaux (la taille n'est pas forcément fixée à l'avance, dans ce cas c'est le compilateur qui la détermine)

[email protected] 105 GLSL : Les Types 2/2

Des différences majeures avec le C • Les vecteurs – Accès par index ou par champ : pos[0] = pos.x – Position : (x,y,z,w) – Couleur : (r,g,b,a) – Coordonnées de texture (s,t,p,q) – Swizzling : vec3 a = pos.xyz; vec2 b = col.br; – Opérations courantes : dot(), cross(), length(), ... – Opérations par composante : vec3 p,q; p*q=vec3(p.x*q.x, p.y*q.y, p.z*q.z); • Pas de cast ! float f=3; FAUX float f=3.0; OK

[email protected] 106 GLSL : Les variables

Déclaration et portée • À la demande, comme en C++ for (int i=0; i<10; ++i) { ... } Initialisation par constructeur • vec2 p = vec2(1.0, 2.0); • vec3 q = vec3(p, 3.0); Des modifieurs • const : constante, en lecture seule • uniform : passé par le CPU aux shaders, en général constant pour une image • attribut : passé par le CPU aux shaders, en général attaché à un sommet • varying : calculé par le vertex shader, puis passé au fragment shader (interpolation par la partie fixe du pipeline au passage)

[email protected] 107 GLSL : Les fonctions

Utilisateur • Types de de paramètres – in (par défaut) – out – inout Prédéfinies • Il y en beaucoup, beaucoup... • Elles sont optimisées • Toujours se demander : « Est-ce qu'il existe une fonction built-in qui fait ce que je veux ? » • Exemple – mix(x, y, alpha) -> x*(1-alpha) + y*alpha – clamp(x, min, max) -> (x>min) ? min : ( (x>max) ? max : x)

[email protected] 108 GLSL : Divers

Préprocesseur • Semblable au C #define, #ifdef, ... Contrôle de flux • Similaire au C – for, while, do-while, if-else – break, return • Mais – Un opérateur logique en plus : ^^ = XOR – Pas de switch ni de goto – Pas de récursion

[email protected] 109 GLSL : Divers

Préprocesseur • Semblable au C #define, #ifdef, ... Contrôle de flux • Similaire au C – for, while, do-while, if-else – break, return • Mais – Un opérateur logique en plus : ^^ = XOR – Pas de switch ni de goto – Pas de récursion • ATTENTION ! Pipeline -> expression conditionnelles TRES couteuses

[email protected] 110 GLSL : Lien avec OpenGL

Const, Uniform, Attribute & Varying prédéfinis • const int gl_MaxTextureUnits; • uniform mat4 gl_ModelViewMatrix • attribute vec4 gl_Color; • attribute vec3 gl_Normal; • attribute vec4 gl_Vertex; • attribute vec3 gl_MultiTexCoord0; • varying vec4 gl_FrontColor; • etc •Des variables spéciales spécififiques vertex/fragment • vec4 gl_Position (V) • vec4 gl_FragColor (F) • vec4 gl_FragCoord (F) • Etc

[email protected] 111 Vertex Shader

Doit calculer • gl_Position Peut calculer • gl_FrontColor Et toute information que l'utilisateur • gl_TexCoord veut fournir au fragment shader... • etc À partir de • gl_Vertex • gl_ModelViewMatrix • gl_Color • gl_Normal • gl_FrontMaterial • etc • Et des uniform/attribut passés par le programme principal [email protected] 112 Fragment Shader

Doit calculer • gl_FragColor Peut calculer Il existe une instruction spécifique • gl_FragData[] au fragment shader : • gl_FragDepth discard() À partir de qui élimine le fragment concerné. • gl_Color • gl_TexCoord[] • Etc

• Et de toute information fournie par le programme principal (uniform) ou le vertex shader (varying)

[email protected] 113

Lien avec OpenSceneGraph 114 Lien avec OpenSceneGraph

Trois classes • osg::Program – Dérive de osg::StateAttribute – Gère des osg::Shader • osg::Shader – Peut être soit osg::Shader::VERTEX, soit osg::Shader::FRAGMENT – Gestion de fichiers • osg::Uniform – Interface unique pour glUniform – Nombreux constructeur en fonction du type Quelques uniform supplémentaires • osg_FrameTime • osg_ViewMatrix

[email protected] 115

Exemple 116 Exemple : coté osg

osg::Vec3 diffus(1.0, 0.8, 0.5); osg::Vec3 ambient(0.1, 0.1, 0.2); osg::ref_ptr prog = new osg::Program; osg::ref_ptr vert = new osg::Shader(osg::Shader::VERTEX); vert->loadShaderSourceFromFile("hemiLight.vert"); prog->addShader(vert.get()); osg::ref_ptr frag = new osg::Shader(osg::Shader::FRAGMENT); frag->loadShaderSourceFromFile("hemiLight.frag"); prog->addShader(frag.get()); osg::ref_ptr ss = root->getOrCreateStateSet(); ss->setAttributeAndModes(prog.get(), osg::StateAttribute::ON); osg::ref_ptr sky = new osg::Uniform("SkyColor", diffus); osg::ref_ptr ground = new osg::Uniform("GroundColor", ambient); ss->addUniform(sky.get()); ss->addUniform(ground.get());

[email protected] 117 Exemple : HemiLight

Idée : • Intégrer l'apport lumineux de la voute céleste

S

k

y

G

r

o

u

n

d

[email protected] 118 Exemple : HemiLight

Idée :

S

k

• Intégrer l'apport lumineux de la voute y céleste

Color= SkyColor1−GroundColor G

0 r

o

où =1.0−0.5sin si90 u 0 n =0.5 sinsi90 d

Problème • Calcul conditionnel • => Approximation =0.50.5cos

[email protected] 119 Exemple : Vertex shader

uniform vec3 SkyColor; uniform vec3 GroundColor; varying vec4 DiffuseColor; void main(void) { vec3 LightPosition = gl_LightSource[0].position.xyz; vec3 ecPosition = vec3(gl_ModelViewMatrix * gl_Vertex); vec3 tnorm = normalize(gl_NormalMatrix * gl_Normal); vec3 lightVec = normalize(LightPosition - ecPosition); float costheta = dot(tnorm, lightVec); float a = 0.5 + 0.5 * costheta;

DiffuseColor = vec4(mix(GroundColor, SkyColor, a), 1); DiffuseColor *= gl_FrontMaterial.diffuse;

gl_Position = ftransform(); }

[email protected] 120 Exemple : Fragment shader

varying vec4 DiffuseColor; void main(void) { gl_FragColor = DiffuseColor; }

[email protected] 121 Exemple : Résultat (fonctionnalité fixe)

[email protected] 122 Exemple : Résultat (shader)

[email protected] 123 Autre exemple

[email protected] 124 Quickref 1/2

[email protected] 125 Quickref 2/2

[email protected] 126 Conclusions

Références • OpenGL Shading Language Randi J. Rost http://3dshaders.com

• http://mew.cx • http://openGL.org • http://openSceneGraph.org

• https://graphics.stanford.edu/wikis/cs448-07-spring/Lectures

[email protected] 127

Callbacks dans osg 128 Callbacks dans osg

Définition (dans le contexte osg) • Callback = fonction définie par l'utilisateur exécutée automatiquement lors de la traversée correspondante du graphe de scène (Update, Cull) • Un callback peut être associé à un noeud particulier ou à un type de noeud. Rôle • Outil très puissant pour définir des comportements spécifiques sans écrire trop de code... 129 Callbacks : Implémentation

• Class osg::NodeCallback • Méthodes pour les noeuds – osg::Node::setUpdateCallback(cb) → appelé 1 fois par frame, au début → modification de la scène – osg::Node::setEventCallback(cb) → traitement direct des évènements clavier/souris – osg::Node::setCullCallback(cb) → appelé lors du culling, permet de d'implémenter des algo de culling spécifiques • Méthodes pour les drawables – +/- les même sur osg::Drawable – osg::Drawable::setDrawCallback(cb) → appelé lors du Draw 130 Callbacks : Création

• Deriver une classe de osg::NodeCallback • Implementer la seule méthode virtuelle void operator()(osg::Node *node, osg::NodeVisitor *nv) • operator() DOIT appeler traverse(node,nv) pour assurer la traversée du graphe • Exemple : class UpdateCallback : public osg::NodeCallback { virtual void operator()(osg::Node* node, osg::NodeVisitor* nv) { std::cout<<"update callback – pre traverse"<

• Pour un noeud donné node->setUpdateCallback(new UpdateCallback()); • Pour faire plus sophistiqué, on utilise un visiteur

Voir OpenSceneGraph/examples/osgcallback/osgcallback.cpp

Voir la doc, les exemples et le code • de osg::Drawable::CullVisitor • et de osg::Drawable::DrawCallback 132

Manipulateurs 133 Nodekit osgManipulator

Manipuler une matrice de transformation via une métaphore visuelle 134 OsgManipulator : Principales classes • osgManipulator::Dragger – C'est la métaphore visuelle – Dérivé en de nombreux dragger, par exemple – osgManipulator::TrackballDragger – osgManipulator::TranslateAxisDragger

• osgManipulator::Selection – Établi le lien entre le dragger et la scène manipulée – Dérive de osg::MatrixTransform – Converti les MotionCommand envoyés par le Dragger connecté en transformation sur la matrice • osgManipulator::CommandManager – Connecte un osgManipulator::Dragger et un osgManipulator::Selection • osgManipulator::PointerInfo – Facilite le picking et la conversion des mouvements entre repère écran et repère scène 135 osgManipulator : utilisation

Code review • OpenSceneGraph/examples/osgmanipulator/osgmanipulator.cpp

En résumé • Copier/Coller – osg::Node *addDraggerToScene(...) – class PickModeHandler • Pour ajouter un dragger au noeud node : – Remplacer les occurences de node dans la scene par addDraggerToScene(node) • Pour gérer les évenements – viewer.addEventHandler(new PickModeHandler()); 136

Animation 137 Animation

Jusque là : Scènes statiques

On veux passer à autre chose • Déplacer les objets • Déformer les objets

Plusieurs méthodes • Animation précalculée • Simulation

Nodekit osgAnimation en cours de développement (osg 2.7.x) 138 Animation précalculée 1/2

Image par image (keyframe)

osg::Sequence

voir osg::Sequence 139 Animation précalculée 2/2

Mouvement • Trajectoire + abscisse = f(t)

Cf osg::AnimationPath 140 Animation simulée

Mécanique du point • Facile à comprendre • Facile à implémenter Mécanique du solide • Plus complexe Objets déformables • En général, approximation par des éléments discrets – Masses / ressorts – Systèmes de particules • Quand c'est nécessaire, approximation du continu – Éléments finis 141

The End 142 Radiosité 1/2

•Algorithme • Discrétisation de la scène en un ensemble de n surfaces (patchs). • Calcul, pour chaque couple de surfaces à l’intérieur de la scène, de la fraction d’énergie qui émise par la première sera réceptionnée par la seconde (facteur de forme). • Constitution d’un système de n équations linéaires à n inconnues où les n inconnues sont les quantités d’énergie émises par chaque facette. • Résolution de ce système d’équations linéaires. • Affichage final par un algorithme d’élimination des parties cachées classique (Z-Buffer ou lancer de rayons).

[email protected] 143 Radiosité 2/2

•Intérêt • Illumination globale • Le calcul, hors affichage, est indépendant du point de vue • Soft shadows •Inconvénient • Cout de calcul et de stockage des facteurs de forme • Cout de calcul de la solution analytique • Surfaces diffuses uniquement •Améliorations • Radiosité progressive – Émission d'énergie facette par facette en commençant par la plus énergétique • Radiosité hiérarchique – On subdivise les patchs au besoin (variance)

[email protected] 144 Lancer de rayons 1/2

Principe • Reconstruire le trajet de la lumière parvenant à l'œil de l'observateur Algorithme • Pour chaque pixel p de l'écran – Tirer un rayon r partant de l'œil et traversant p – Si r entre en collision avec un objet de la scène – Calcul de l'éclairage direct diffus – Tirer un rayon vers chaque source lumineuse – Si le rayon atteint la source, ajouter la contribution lumineuse de la source – Calcul de l'éclairage indirect – Tirer un rayon réfléchi – Tirer un rayon réfracté

[email protected] 145 Lancer de rayons 2/2

Intérêt • Facile à implémenter • Traitement correct des objets transparents Inconvénients • Temps de calculs • Explosion du nombre de rayons secondaires • Surfaces spéculaires uniquement • Calculs dépendants du point de vue Améliorations • Utiliser des structures accélératrice pour la détection d'intersection rayon/objets • Exploiter la cohérence spatiale (Les rayons voisins ont de fortes chances de toucher les mêmes objets)

[email protected] 146 Monte Carlo

À mi chemin entre radiosité et lancer de rayons Idée • Reconstruire la solution exacte par méthode mathématique d'approximation d'intégrales Algorithme • Type lancer de rayon • Pour un pixel, lancer d'un rayon primaire, puis lancer de rayons secondaires aléatoirement (en fonction de la BRDF au point d'intersection) • Pour être valide, plusieurs centaines de rayons par pixels Bilan • Très lent • Très bonne qualité → Solution de référence

[email protected]