Fr/Tutoriel: Usage de l'effet de Normal Maps

From FlightGear wiki
Jump to navigation Jump to search

Flightgear 2.0 marque l'apparition des "Effets", une façon efficace d'utiliser les Shaders dans FG, sans avoir à écrire de code C. Depuis Mars 2010, la version CVS de Flightgear inclut un effet nommé "BumpSpec"(Effects/bumpspec.eff), qui gère le déplacement de surface par "normal maps" ainsi que le mapping de spécularité. Ce tutoriel décrit comment appliquer cet effet à un aeronef dans FlightGear. Une approche similaire pourrait aussi aussi être utilisée pour appliquer d'autres effets.


Si vous ne savez pas ce qu'est une "normal map", vous pouvez l'apprendre ici


Créer une "normal map"

Pour créer une Normal Map, il existe plusieurs solutions.

On peut envisager une approche "2D" du problème . On utilisera alors un programme pour convertir une carte de relief en un mapping de normales. Il existe un bon plugin GIMP pour cette opération. Il est accessible ici

Une autre approche consiste à modéliser un modèle à haute densité de points dans un programme d'édition 3D, à générer une carte de normales depuis ce modèle, et appliquer cette carte à un modèle allégé. Vous pourrez trouver plus de renseignement sur cette méthode appliquée à Blender ici


Voyons d'abord l'approche "2D":

Une fois que vous avez installé le plugin GIMP "normalmap", vous allez créer la carte de normales ainsi :


  1. Identifiez un objet auquel vous voulez ajouter l'effet de normal mapping, en utilisant Blender, AC3D, etc...
  2. Trouvez la portion de la texture utilisée par cet objet. Du fait que, la plupart du temps, les textures sont organisées de façon intelligible, cela ne devrait pas poser de problème. On utilisera le même mapping UV pour la carte de normales.
  3. Ouvrez la texture de couleurs dans GIMP et créez un nouveau calque noir par dessus. On utilisera la texture existant comme un guide pour créer la carte de normales.
  4. Ajustez l'opacité du nouveau calque, de sorte que vous pouvez voir la texture de couleurs en dessous. Le nouveau calque sera une carte de relief de l'objet. Le NOIR représente les points les plus bas, le BLANC, les points les plus élevés par rapport à la surface moyenne de l'objet. Pour l'instant, le calque étant tout noir, tous les points sont au niveau le plus bas.
  5. A présent, utilisez la technique de dessin qui vous semble la plus appropriée pour définir la hauteur de déplacement. Si vous souhaitez des arètes franches, utilisez un outil de dessin au contour dur.


  1. Une fois que vous êtes satisfait de votre carte de relief, supprimez le calque de fond, et rétablissez l'opacité du calque superieur à 100 %. Sauvez en tant que nouveau fichier.
  2. Maitenant il va falloir convertir la carte de relief en carte de normales. Pour ce faire, utilisez Filtres->Normalmap. Si ce filtre n'est pas accessible, vous avez mal installé le plugin...Veuillez suivre de nouveau les instructions citées plus haut.
  3. Les options par défaut du plugin devraient fonctionner sans problème, si ce n'est que vous devrez inverser l'axe Y ( Dans OpenGL, l'origine des axes est en haut a gauche, et non en haut à droite comme le suppose le plugin GIMP ). Quoi qu'il en soit, l'auteur du plugin GIMP préconise l'emploi de l'option Prewitt 5x5. Lorsque vous êtes satisfait des options, cliquez sur "OK", et la teinte générale de votre image va tourner au bleu, avec de jolies irisations arc en ciel là où vous avez dessiné votre carte de relief en blanc. Vous êtes en présence de votre "normal map".
  4. Sauvez l'image en tant que fichier png, dans le répertoire de votre avion, et notez bien le chemin complet de cette image.


Voyons ensuite l'approche 3D, dans blender.

( ceci est une autre solution, et ne necessite pas de suivre les explications précedentes )


  1. Dans Blender, vous avez modélisé un modèle à faible densité de points. C'est ce modèle qui sera exporté vers FG, appellons le "low poly".
  2. Créez un mappage UV pour cet objet ( edit mode, select all, U ) , puis associez une nouvelle image à ce mappage ( UV/image editor, new )
  3. Dupliquez l'objet "low poly". Nous appellerons cette nouvelle copie "high poly" .
  4. Ajoutez des détails à la copie "high poly", là où c'est nécessaire. ( sans la déplacer ! cette méthode nécessite que les deux objets aient le même centre ! utilisez éventuellement des calques pour simplifier la vision lors du travail ) Vous pouvez utiliser "multires", ou bien des déformeurs subsurface, ou bien encore vous pouvez le faire "à la main". Les fonctions de sculpture de Blender sont appréciables également! La méthode employée ne dépend que de vous, et de vos habitudes de travail.


Lorsque vous êtes satisfait du niveau de détail du "high poly" , il va s'agir de créer la carte de normales de cette copie , et de la transférer au "low poly". L'interface puissante de Blender permet d'effectuer ceci en une seule opération :

  1. En mode Objet , séléctionnez d'abord l'objet "high poly", PUIS, "SHIFT-selectionnez" l'objet "low Poly" pour l'ajouter à la séléction.
  2. Dans la fenêtre de boutons "scene" ( F10 ) , cliquez sur l'onglet "bake", et assurez vous de séléctionner les options "selected to active", "normals". Dans le menu déroulant sous les options "dist" et "bias", choisissez comme espace de normales l'option 'tangent'. Vous pouvez laisser 'quad split auto' tel quel.
  3. Il est bon d'indiquer une marge de bavure dans 'margin', afain de s'assurer que la texture couvre bien toute la surface des faces. Une douzaine de pixels suffisent dans la plupart des cas pour FlightGear.
  4. Lorsque tout est prêt, cliquez sur le gros bouton "bake". Si vous avez bien suivi les instructions précédentes, vous devriez voir apparaitre votre normal map dans l'UV/image editor. Sauvez l'image au format png, et retenez bien où vous l'avez sauvée.


Malheureusement, l'espace de travail de blender et l'espace de travail du shader de FlightGear sont différents.... il va falloir inverser les axes X et Y de la carte de normales sous peine de voir votre effet inversé... C'est très simple :

  1. Ouvrez votre image dans gimp, suivez le menu "Couleurs -> Composants -> Décomposer". Choisissez l'option 'RVB', ainsi que 'décomposer en calques'. Cliquez sur valider.
  2. Dans la nouvelle image qui s'ouvre, inversez les valeurs pour les claques ROUGE ( red ) et VERT ( green ).
  3. Puis de nouveau, "Couleurs -> Composants", mais cette fois "Recomposer". Choisissez l'option 'RVB', et validez.
  4. Une nouvelle image s'ouvre , fort semblable à votre carte d'origine, mais avec cependant des differences. Sauvez cette image.


Bien que la dominante bleue soit conservée, en observant bien, vous constaterez que les niveaux de rouge et de vert ont été inversés. Votre nouvelle carte est maintenant prête à etre utilisée par le shader dans FlightGear.


Bien que plus compliquée, cette méthode permet de génerer des effets de déplacement fort complexes, et d'une façon bien plus précise que la simple conversion de carte de relief. Il est ainsi possible de travailler sur les 3 axes, de créer des recouvrements, des zones concaves, etc... etc...tout en gardant le control total sur la "quantité de déplacement" désirée, simplement lors du modelage de l'objet "high poly". Vous pouvez voir un tutoriel de cette technique en images ici

Créer l'effet de Normales dans FlightGear

Maintenant que nous avons notre carte de normales, nous devons l'appliquer au modèle. Pour ce faire, nous devons créer un nouvel effet, basé sur le fichier existant : Effect/bumpsec.eff, puis nous devrons l'appliquer à l'objet correspondant dans le modèle.

  1. Ouvrez Effects/bumpspec.eff dans un éditeur de texte. Quelques indications en anglais dans le texte peuvent vous aider
  2. Copiez le premier bloc XML ( entre les balises <PropertyList> et </PropertyList> ) dans un nouveau fichier .eff, dans le répertoire de votre aéronef.
  3. Editez ce nouveau fichier de sorte qu'il ait des balises <name> et <image> appropriées. Par exemple dans ce cas nous avons créé l'effet Aircraft/c172p/Models/Effects/bumpspec, et nous utilisons la carte de normales Aircraft/c172p/Models/Liveries/wing-normal.png :
<PropertyList>
  <name>Aircraft/c172p/Models/Effects/bumpspec</name>
  <inherits-from>Effects/bumpspec</inherits-from>
  <parameters>
    <texture n="2">
      <image>Aircraft/c172p/Models/Liveries/wing-normal.png</image>
      <filter>linear-mipmap-linear</filter>
      <wrap-s>repeat</wrap-s>
      <wrap-t>repeat</wrap-t>
      <internal-format>normalized</internal-format>
    </texture>
  </parameters>
</PropertyList>

Maintenant nous disposons d'un nouvel effet, basé sur l'original : Effects/bumpspec.eff, mais qui utilise sa propre carte de normales.


Appliquer l'effet au modèle

Pour terminer, nous devons appliquer l'effet au modèle. C'est très simple. Il suffit d'ajouter une section au fichier .xml de votre modèle, pour indiquer quel effet utiliser, et à quel(s) objet(s) cela doit s'appliquer.

Par exemple :

<effect>
  <inherits-from>Aircraft/c172p/Models/Effects/bumpspec</inherits-from>
  <object-name>wing_1</object-name>
</effect>

A présent, lancez FLightGear avec votre nouveau modèle et admirez le résultat:



Notes finales

  • La carte de normales utilise le même espace de coordinées UV que la texture de couleurs. Cependant, l'echelle peut etre différente, vous pouvez donc utiliser une image plus petite ou plus grande si nécessaire.
  • Il est nécessaire de créer un nouvel effet pour chaque carte de normales. Dans les faits, cela signifie que si vous avez deux objets, qui utilisent chacun une carte différente, vous devrez définir deux effets distincts.
  • Le shader bumpspec.eff utilise le canal alpha de l'image ( transparence ) pour définir le niveau de spécularité de de chaque point ( défini par shininess dans les fichiers .ac ). Ceci peut etre utilisé pour rendre brillantes les parties extrudées.
  • Si vous trouvez que l'effet est trop prononcé, vous pouvez varier l'option "scaling" dans le plugin normalmap de GIMP. <0.1> donne de bons résultats pour un effet de rivets.
  • Assurez vous que toutes les faces de l'objet auquel vous appliquez l'effet sont bien associées à une texture, sinon vous allez provoquer un crash au niveau de la couche OpenGL ( au dessous de OSG ) , car les vecteurs tangents et binormaux de l'effet sont calculés en utilisant les coordonnées du mapping UV de l'objet. Si vous essayez de fournir un objet non texturé au générateur, celui ci retournera un vecteur nul par défaut, et lorsqu'il passera ce vecteur nul au pilote, on obtiendra une erreur de segmentation.