Direct3D Les textures

Un article de Mangue.org, l'encyclopéde libre.


Si des objets colorés peuvent donner un résultat graphiquement agréable, force est d'avouer que ce n'est rien en comparaison du résultat produit par une utilisation judicieuse des textures. Voyons ici les quelques notions théoriques indispensables.


Sommaire

Introduction


Une texture n'est rien d'autre qu'une image que l'on va appliquer à un objet 3D. Dans les versions précédentes de DirectX existait l'API DirectDraw, qui permettait de gérer la 2D, et donc les images. Ces images étaient stockées dans des surfaces, qui permettaient d'en faire une gestion optimisée. Si DirectDraw a disparu, le concept de surface n'a pas été perdu et est aujourd'hui utilisé au sein de l'objet DirectX destiné aux textures, afin de stocker les images qui la composent. (une texture peut contenir plusieurs images) Voyons en premier lieu comment ces images sont stockées en mémoire.


Le pitch


En mémoire, une image est représentée par une suite consécutive d'octets qui définissent ses pixels. (pour les textures, on parle de "texels", pour "TEXture ELements") Ainsi, pour par exemple lire la couleur du quatrième pixel de la troisième ligne de l'image, on serait tenté de se rendre à l'octet ((taille d'un pixel en octet) * (largeur de l'image) * 3) + 4. Cependant, même si les octets se suivent en mémoire, il peut arriver, pour des raisons d'optimisation en mémoire, que DirectX rajoute des pixels virtuels à l'image. (cf. image ci-dessous) Ceux-ci ne sont bien sûr pas affichés, mais rendent la formule précédente caduque. La largeur réelle de l'image en mémoire est appelée le pitch. C'est cette valeur, accessible via des appels de méthodes de DirectX, qu'il convient d'utiliser lorsqu'on veut effectuer une opération de ce genre.


Image:D3d_cours3-1.gif

La valeur du pitch correspond à la largeur réelle de l'image en mémoire.


Taille des textures


Les cartes 3D imposent parfois des limites très contraignantes quant aux dimensions des textures qu'elles peuvent stocker. Certaines acceptent de remplir toute leur mémoire avec une seule texture, (ex : des textures de 4096 par 4096 pixels en 32 bits pour les cartes embarquant 64mo de mémoire) tandis que d'autres, comme les voodoos, n'accepteront que des textures de 256 par 256 pixels. Certaines cartes imposent même le fait que les textures soient carrées (largeur et hauteur identiques) et/ou que ces valeurs soient des puissances de deux. Le cas le plus fréquemment rencontré n'impose pas de limite de taille (dans les limites de la mémoire que la carte comporte) mais demande que les dimensions des textures soient des puissances de deux. DirectX comporte des méthodes qui, à partir d'une image ayant n'importe quelles dimensions, vont créer des textures ayant une taille acceptable par le matériel. Cependant, il est bien plus efficace de prévoir cette éventualité lors de la création des textures, et de leur donner des dimensions correctes dès le départ. De même, plus vos textures ont des dimensions importantes, plus cela consomme des ressources, il convient donc d'éviter de travailler avec des textures énormes.


Niveau de surface et mipmaps


Dans un jeu en 3D, la caméra est rarement statique. Ainsi, nous serons certainement amenés à voir un objet, par exemple un bâtiment, de près comme de loin. Comme nous voulons un beau bâtiment, nous allons lui appliquer une superbe texture de brique avec de monumentales dimensions de 2048x2048. (soit 16mo de mémoire) De près, le bâtiment est sompteux, mais chose étrange, plus on s'en éloigne, plus il y apparait de petits artefacts visuels du plus mauvais goût. Cela se produit car plus on s'éloigne, plus l'objet devient petit, donc plus la texture devra être rapetissée avant d'être appliquée à l'objet 3D. Comme cela doit être fait en temps réel, il est impossible d'appliquer les algorithmes qui produisent le meilleur résultat. De plus, cela donne un travail supplémentaire au matériel. Pour remédier à cela, nous pouvons utiliser les mipmaps. Cette technique consiste à stocker, dans la texture, plusieurs exemplaires de l'image à des tailles différentes, la carte s'occupant de choisir l'exemplaire qui convient le mieux à la situation. Nous pouvons ainsi produire des versions rapetissées de notre texture originelle en utilisant les algorithmes qui produisent le meilleur résultat. Au sein de l'objet DirectX correspondant à la texture, ces différentes versions de l'image seront accessibles via les niveaux de surface, ou "surface levels".


Image:D3d_cours3-5.gif

Une texture peut être répétée plusieurs fois à des tailles différentes dans une chaine de mipmap.


{{Remarque|Origine du terme "mipmap"


Même si l'on n'avait cure des texels et autres vertex shaders à l'époque de la Rome antique, la dénomination "mip" trouve son origine dans la langue latine. En effet, mip est l'acronyme de "multim im parvo", qui signifie grossièrement "beaucoup de choses dans un seul petit endroit". Fin de la minute culturelle, vous pouvez retourner à vos claviers. ;-) |}


Coordonnées de textures


Les coordonnées de textures servent à indiquer à DirectX comment une texture va être appliquée sur un objet. Une coordonnée fait correspondre un vertex donné à un endroit précis de la texture. En général, les coordonnées de texture varient entre 0.0 et 1.0 et sont appelées u et v. Exprimées en nombre flottants, ces coordonnées, permettent bien de distinguer chaque texel. (pour une texture de dimensions 128x128, 1.0 correspond à 128, 0.5 à 64, etc) Par exemple, pour mapper une texture sur un rectangle, on donnera au vertices les coordonnées (0.0, 0.0), (1.0, 0.0), (0.0, 1.0), (1.0, 1.0). La première coordonnée sera le coin supérieur gauche, la seconde celle du coin supérieur droit, etc. Notez que la forme de la texture à l'écran dépendra des vertices: si la texture est en 128x128 mais que le rectangle sur lequel elle est mappée couvre un écran de 1024x768, la texture sera étirée pour atteindre cette taille.


Image:D3d_cours3-2.gif

La texture couvre toute la surface.


Les valeurs inférieures à 1.0 autres que 0.0 sont tout à fait valables. Si l'on remplace tous les 1.0 par des 0.5 dans les coodonnées précédentes, c'est le quart supérieur gauche de la texture qui sera mappée sur le rectangle.


Image:D3d_cours3-4.gif

Avec ces coordonnées, on ne voit que le quart supérieur gauche de la texture.


Une valeur supérieure à 1.0, elle, provoquera par défaut une répétition de la texture. La répétition permet de limiter la taille des textures. Pour texturer une champ, il est plus malin de créer une texture d'herbe qui se répète plutôt qu'un map énorme couvrant la totalité du champ.


Image:D3d_cours3-3.gif

La texture est répétée.


Conclusion


Nous voici enfin arrivés au terme de la série des articles théoriques! Même si cela peut paraitre rébarbatif, les notions précédemment acquises constituent un mini bagage théorique qui se révèlera très rapidement indispensable, comme vous pourrez le constater au fil de votre lecture.

Outils personels