Song of the Myrne... et Unity en général en fait: texture leaking

Publié le 06 juin 2014 par Beldarak @Beldarak

Hello les lecteurs !
C'est la fête aujourd'hui !
Je viens de coder une correction à un soucis qui me hante depuis looooooongtemps (depuis que j'utilise des atlas de textures en fait). Et ce dans tous mes jeux.
Comme certains devs me suivent, je me suis dit que ça pouvait en intéresser quelques uns de définir le problème et la solution.
Accrochez vous à vos slips ! On descend dans les profondeurs obscures d'Unity et des trucs techniques.

Le soucis


Vous l'avez très probablement déjà vu dans What Lies Beneath, parfois, quand vous vous tenez à un endroit précis, de petites barres moches viennent se mettre dans les textures.

Ça arrive aussi parfois sur certains casques quand vous jouez en une certaine résolution.
Ça peux paraître un détail (pour vous mais pour moi ça veux dire beaucoup) mais c'est vraiment un soucis qui me dérange énormément, ça donne un aspect amateur et mal maîtrisé aux jeux.

Le pourquoi du comment


Alors ces lignes, c'est quoi ?
En fait ce sont les pixels adjacents à la texture dans l'atlas qui "fuitent" dans la texture appliquée au quad (ces petits bâtiments sont constitués de plusieurs petites plaques, qu'on appelle des "quads").
Vous n'avez rien compris ? C'est normal !

Comme vous le voyez ici, on retrouve ce soucis dans le tapis. Il y a deux points jaunes qui viennent se mettre au milieu du tapis bleu.
A droite, vous avez le morceau concerné de l'atlas de textures du tapis. On peux voir la case qui déconne en jeu, le coin renversé (j'ai mis le carré en évidence sur l'image). Et sur la case au dessus dans l'atlas, on peux voir que c'est de là que viennent nos deux points jaunes (les deux parties entourées).
Ils ont dépassé de leur case sur notre case de coin.
Pourquoi ?
C'est à cause de la transformation des pixels de l'image en pixels du jeu. Un pixel sous Photoshop n'égale pas un pixel dans le jeu (heureusement sinon vous auriez besoin d'une grosse loupe pour jouer^^).
Unity va donc essayer de retranscrire au mieux les pixels de l'image en pixels de votre écran (selon votre résolution donc). Ce qui mène parfois à de petites imperfections (probablement dues à des arrondis de calculs).
Je ne vais pas plus loin dans l'explication, je ne sais pas trop comment ça fonctionne vraiment ><
Mais vous avez saisi l'idée je pense, parfois Unity (et ça le fait aussi sous d'autres engines hein) se rate et affiche des pixels qu'il ne devrait pas.
Petite précision: si le reste du tapis n'affiche pas de lignes jaunes, c'est simplement parce que les textures à côtés dans l'atlas ont la même couleur. Par exemple la case de notre exemple n'a pas de leak jaune sur le côté gauche, tout simplement parce que la case de gauche est totalement bleue, tout comme la partie gauche de notre case. Il y a aussi une fuite de pixels mais on ne la voit pas puisque des pixels bleus dépassent sur des pixels bleus.

La solution


Elle est simple et compliquée à la fois.
La solution c'est qu'il n'y a pas de solution à proprement parler. Il suffit d'espacer ses textures dans l'atlas, comme ça :

Comme vous le voyez je peux alors doubler les côtés des textures pour qu'en cas de leak, la couleur qui "coule" soit la même que celle du pixels dans lequel elle arrive.

Conclusion


Ah bah c'est super ! On ne verra plus ces vilains bugs alors ?!
Hmmm... Ce soucis n'arrivera plus dans mes futurs jeux.
Malheureusement, pour ce qui est de SotM et WLB ça arrivera encore. Changer mes atlas de textures vers ce nouveau modèle prend énormément de temps, donc ne pensez pas que ces petits leaks auront disparus dès la prochaine update.
Je vais progressivement changer mes atlas, en commençant par les trucs où ça gêne le plus (les tapis par exemple) et en procédant par scripts (tous les murs, sols et façades utilisent le même script, mais pas les casques par exemple).
Au fur et à mesure des updates donc, vous devriez voir ces petits glitchs graphiques de moins en moins jusqu'au jour lointain où ils ne seront plus qu'un mauvais souvenir.
Voilà voilà !
Encore une bonne chose de faite^^.