Informatique Graphique

Texture et shaders

Guillaume Gilet

Histoire de modèles

  • Les scènes avec les objets prédéfinis manquent de diversité
  • Three.js permet l'ajout de modèles 3D définis à base polygones.
  • Plusieurs formats sont disponibles (collada, js, binaire...)
  • Il faut ajouter la ligne suivante à votre fichier
    
    import { OBJLoader } from 'https://unpkg.com/three@0.121.1/examples/jsm/loaders/OBJLoader.js';
    						

Principe du chargement

  • Un objet Three.js est composé d'une géométrie et d'une apparence
  • La géométrie est maintenant lue dans un fichier contenant le modèle
  • Exemple : le chargeur d'objet OBJ
    
    						 var loader = new THREE.OBJLoader();
    loader.load( "Bunny.obj", function(objet){...});
    						
  • avec function(objet) une fonction callback (appelée lorsque le chargement est fini avec l'objet en paramètre)

La fonction callback

  • Cette fonction est appelée lorsque l'objet est totalement en mémoire locale
  • En général, il faut créer un matériau et ajouter l'objet à la scène
  • Exemple :
    
    						function(objet){
    var material = new THREE.MeshBasicMaterial( {color: 0xffffff}  );
    objet.material = material;
    scene.add(objet);
    }
    						
  • Egalement, on retrouve souvent dans cette fonction les traitements géométriques appliqués au modèle (calcul des normales...)

Le lapin, le lapin

  • Voici un modèle en format obj (Bunny.obj)
  • Essayez de charger ce modèle et de l'afficher au centre de votre scène.
  • Attention, ce modèle est de taille de 1 unité et peut donc nécessiter (en fonction des dimensions de votre scène) une mise à l'echelle avant d'être visible (utiliser pour cela objet.scale.set(sX,sY,sZ))

Attention au chargement des objets locaux

  • Les navigateurs modernes interdisent par défaut l'accès à des fichiers locaux
  • Il faut modifier la configuration de votre navigateur pour pouvoir charger des modèles présents sur votre compte
  • Une solution est de désactiver temporairement cross origin request security (attention à la sécurité) : ici
  • ou de passer par un serveur : Suivre la documentation ici
  • Il existe différents chargeurs de géométrie en fonction du format de fichier (obj,json,collada...) disponibles dans la librairie three.js

Habillage et texture

  • Les modèles dans une application 3D sont rarement de couleur uniforme
  • Pour rajouter de la diversité, il est possible d'utiliser une image (une texture) pour habiller la géométrie
  • Cela modifiera la couleur de la surface de l'objet
  • Il faut pour cela créer un objet texture :
    
    					var texture = new THREE.TextureLoader().load( "MyTexture.png"  );
    						
  • et indiquer au matériau de l'objet de l'utiliser :
    
    					material.map = texture;
    						

Habillage du lapin

  • Pour pouvoir utiliser une texture, les modèles doivent avoir des coordonnées de texture
  • Les textures doivent correspondre avec le modèle
  • Essayez d'habiller le lapin avec cette texture

Shaders et programmation du pipeline graphique

  • Le but de cette partie est de réaliser un ensemble d'exercices afin de vous familiariser avec les shaders et la programmation en GLSL
  • Commencez par vous familiariser (si besoin) avec les exemples présentés en cours
  • Rappel : le cours se trouve ici

Shaders et programmation du pipeline graphique

  • La première étape est de créer un ensemble de shaders reprenant le pipeline fixe (cf cours)
  • Vous devez voir votre objet 3D affiché dans la couleur de votre choix

Vertex Shader et transformations

  • Dans le vertex shader, créez une variable couleur de nature varying et de type vec3. Cette variable sera transmise au fragment shader qui doit l'utiliser pour définir la valeur de couleur du fragment (il faudra donc créer une variable de même type dans le fragment shader). Cette variable prendra les valeurs suivantes :
    • Une valeur arbitraire (définie en dur dans le code)
    • La valeur absolue de la position dans l'espace objet de chaque sommet (variable position)
    • Pour la suite des exercices, utilisez la valeur absolue de la normale (variable normale) comme couleur

Vertex Shader et déformation

  • Ces exercices (indépendants du premier) reposent sur la déformation de la géométrie dans le vertex shader.
    • Déplacez, dans l'espace de l'objet, chacun des sommets ayant une coordonnée X supérieure à 0 de 0.03 unités le long de sa normale.
    • Déplacez, dans l'espace de l'objet, chacun des sommets ayant une coordonnée Y supérieure à 0 de 0.2 unités le long de son axe X. Il suffit d'augmenter la valeur de la coordonnée x de la position du sommet.
    • Réalisez cette dernière opération dans l'espace écran (après projection, donc avec la variable gl_Position). Que constatez vous ?

Vertex Shader et déformation (bis)

  • Utilisez une variable temps (définie par le CPU dans l'application javascript) afin de réaliser une animation du modèle basée sur le temps
  • Commencez par déformer les sommets du lapin dans l'espace objet en fonction du cosinus de cette variable temps (par exemple,pour un sommet : x = x + 0.1*cos(y*time))
  • Réalisez ensuite la même opération dans l'espace image (gl_Position) et commentez
  • Beaucoup d'autres déformations sont possibles. A vous d'expérimenter !

Fragment program

  • Assignez au canaux x et y de chaque fragment la valeur contenue dans les coordonnées de texture. Attention, ces coordonnées sont définie depuis le vertex shader. Il faudra les transmettre au fragment shader. Utilisez la syntaxe suivante pour transmettre la texture au fragment shader.
    				
    					var uniforms = { 
    texture1: { type: "t", value: new THREE.TextureLoader().load( "MaTexture.jpg" ) }
    };
    				
    				
  • Transmettez maintenant la texture de votre choix au fragment shader et assignez à chaque fragment la couleur contenue dans la texture, en fonction des coordonnées de textures.
  • Bonus : utilisez la variable temps précédente pour faire varier l'apparence de l'objet en fonction du temps.

A rendre pour ce TP

  • Un objet 3D (lapin, autre...)
  • Une camera orbit permettant de déplacer la caméra autour de l'objet
  • L'apparence de l'objet doit être générée par un shader complexe en fonction de ses coordonnées de texture (un exemple shadertoy (a citer) que vous adapterez, un filtre de sobel sur une texture, une apparence animée...)