
Dans cet article, j'expliquerai un algorithme de répartition de texture qui vous permet de créer un terrain plus naturel. Cet algorithme peut être utilisé dans les shaders de jeux 3D ainsi que dans les jeux 2D.
L'un des moyens les plus courants de texturer le terrain consiste à mélanger plusieurs couches de tuiles. Chaque couche a une carte d'opacité qui définit l'étendue de la présence de texture sur le terrain. La méthode fonctionne en appliquant une carte d'opacité aux niveaux supérieurs, révélant les couches sous lesquelles la carte d'opacité est partiellement ou complètement transparente. La carte d'opacité est mesurée en pourcentage. Bien sûr, sur chaque point d'un terrain, la somme des opacités de toutes les couches fait cent pour cent car le terrain ne peut pas être transparent. Au lieu de textures de tuiles, la carte d'opacité s'étend entièrement sur tous les terrains et a donc un niveau de détail assez faible.
Passons maintenant à la partie la plus intéressante - les algorithmes de mélange de textures. Pour plus de simplicité et d'évidence, notre terrain sera composé de sable et de gros pavés.

Le moyen le plus simple de mélanger consiste à multiplier la couleur de la texture par l'opacité, puis à additionner les résultats.
float3 blend(float4 texture1, float a1, float4 texture2, float a2) { return texture1.rgb * a1 + texture2.rgb * a2; }
Une telle technique est utilisée dans Unity3D dans l'éditeur de terrain standard. Comme vous pouvez le voir, la transition est douce mais non naturelle. Les pierres semblent souillées uniformément par le sable, mais dans le monde réel, cela ne se passe pas comme ça. Le sable ne colle pas aux pierres, au lieu de cela, il tombe et remplit les fissures entre elles, laissant le sommet des pierres pur.
Essayons de simuler ce comportement dans les tracés Excel. Comme nous voulons que le sable soit «tombé» entre les pavés, nous avons besoin pour chaque texture de la carte de profondeur. Dans cet exemple, nous considérons que la carte de profondeur est générée à partir d'une image en niveaux de gris et stockée dans le canal alpha d'une texture. Dans Unity3D, cela peut être fait dans l'inspecteur de texture en définissant le drapeau "Alpha From Grayscale".
Tout d'abord, nous considérerons le modèle simplifié de carte en profondeur du sable et des pierres.

La ligne bleue sur l'intrigue symbolise la carte de profondeur du sable et le rouge est des galets. Notez que les sommets des pierres se trouvent plus haut que le niveau du sable. Compte tenu de ce fait, nous allons essayer de dessiner des pixels de cette texture qui est au-dessus.
float3 blend(float4 texture1, float a1, float4 texture2, float a2) { return texture1.a > texture2.a ? texture1.rgb : texture2.rgb; }

Excellent! Les sommets de pavés restent purs tandis que le sable se trouve entre les fissures. Mais nous n'avons pas encore considéré l'opacité des calques. Pour l'utiliser, nous additionnons simplement la carte de profondeur-profondeur et la carte d'opacité.
float3 blend(float4 texture1, float a1, float4 texture2, float a2) { return texture1.a + a1 > texture2.a + a2 ? texture1.rgb : texture2.rgb; }
Au détriment de la sommation, une texture moins transparente sera plus élevée que d'habitude.


Nous avons donc une transition plus naturelle du sable aux pierres. Comme vous pouvez le voir, des grains de sable commencent à remplir les fissures entre les pavés, les cachant progressivement. Mais au fur et à mesure des calculs, pixel par pixel, des artefacts commencent à apparaître à la frontière entre les textures. Pour obtenir un résultat fluide, nous prendrons plusieurs pixels en profondeur au lieu d'un et les mélangerons.
float3 blend(float4 texture1, float a1, float4 texture2, float a2) { float depth = 0.2; float ma = max(texture1.a + a1, texture2.a + a2) - depth; float b1 = max(texture1.a + a1 - ma, 0); float b2 = max(texture2.a + a2 - ma, 0); return (texture1.rgb * b1 + texture2.rgb * b2) / (b1 + b2); }
Dans le code ci-dessus, nous obtenons d'abord une partie d'un sol vu à une certaine profondeur.

Et puis nous le normalisons pour obtenir de nouvelles opacités.


En conséquence, nous avons trouvé l'algorithme de mélange de textures, ce qui nous permet d'atteindre près d'une image de terrain naturel.