La cartographie UV typique est ce qu'on appelle une transformation affine . Cela signifie que le mappage de chaque triangle entre l'espace 3D et l'espace de texture peut inclure la rotation, la translation, la mise à l'échelle / le squash et l'inclinaison (c'est-à-dire tout ce que nous pouvons faire avec une multiplication matricielle homogène)
La chose à propos des transformations affines est qu'elles sont uniformes sur tout leur domaine - la rotation, la translation, l'échelle et l'inclinaison que nous appliquons à la texture près du sommet A sont les mêmes que celles que nous appliquons près du sommet B, dans n'importe quel triangle. Les lignes parallèles dans un espace seront mappées à des lignes parallèles dans l'autre, jamais convergentes / divergentes.
Mais la réduction progressive que vous essayez d'appliquer n'est pas uniforme - elle met en correspondance des lignes parallèles dans la texture avec des lignes convergentes sur le maillage. Cela signifie que l'échelle de la texture mesurée à travers la bande change continuellement à mesure que nous avançons dans la bande. C'est plus que ce que les transformations affines de la cartographie UV 2D peuvent représenter avec précision: l'interpolation des coordonnées UV 2D entre les sommets adjacents obtiendra une échelle cohérente sur tout le bord, même le bord diagonal qui devrait rétrécir à mesure qu'il se déplace le long de la bande. Ce décalage est ce qui crée ce zigzag tordu.
Ce problème survient chaque fois que nous voulons mapper un rectangle à un trapèze - des côtés parallèles à des côtés convergents: il n'y a tout simplement pas de transformation affine qui le fait, nous devons donc l'approcher par morceaux, ce qui conduit à des coutures visibles.
Dans la plupart des cas, vous pouvez minimiser l'effet en ajoutant plus de géométrie. L'augmentation du nombre de subdivisions sur la longueur de la bande et la division de la bande en deux segments ou plus sur toute sa largeur, avec les diagonales des triangles disposées en chevrons, peuvent rendre l'effet beaucoup moins perceptible. Il sera toujours présent dans une certaine mesure tant que nous utiliserons des transformations affines.
Mais il existe un moyen de contourner cela. Nous pouvons utiliser la même astuce que nous utilisons pour le rendu 3D pour dessiner des trapèzes en perspective étant donné les murs et les sols rectangulaires: nous utilisons des coordonnées projectives !
Texturation affine:
Texturation projective:
Pour ce faire, nous devons ajouter une troisième coordonnée uv (uvw) et modifier nos shaders.
Étant donné un facteur d'échelle à chaque point (disons, égal à la largeur de votre bande à cet endroit), vous pouvez construire la coordonnée UV projective 3D à partir de votre coordonnée UV 2D régulière de cette façon:
Vector3 uv3 = ((Vector3)uv2) * scale;
uv3.z = scale;
Pour appliquer ces coordonnées uvw 3D à votre maillage, vous devrez utiliser le Mesh.SetUVs de surcharge Vector3 (canal int, liste uvs)
Et assurez-vous de changer la structure d'entrée de votre shader pour vous attendre à une coordonnée de texture 3D (affichée ici en utilisant le shader non éclairé par défaut):
struct appdata
{
float4 vertex : POSITION;
float3 uv : TEXCOORD0; // Change float2 to float 3.
};
// Also do this for the uv sent from the vertex shader to the fragment shader.
Vous devrez également découper la macro TRANSFORM_TEX dans le vertex shader, car elle attend un uv 2D:
// o.uv = TRANSFORM_TEX(v.uv, _MainTex);
o.uv = v.uv;
// If you define a float4 with the special name _MainTex_ST,
// you can get the same effect the macro had by doing this:
o.uv.xy = o.uv.xy * _MainTex_ST.xy + _MainTex_ST.zw;
Enfin, pour revenir à une coordonnée de texture 2D pour l'échantillonnage de texture, il vous suffit de diviser par la troisième coordonnée dans votre shader de fragment :
float2 uv = i.uv.xy / i.uv.z;
Puisque nous avons fait cette coordonnée uvw 3D à partir de notre coordonnée 2D souhaitée en multipliant par le même nombre, les deux opérations s'annulent et nous revenons à notre coordonnée 2D souhaitée d'origine, mais maintenant avec une interpolation non linéaire entre les sommets. :RÉ
Il est important de faire cette division par fragment et non dans le vertex shader. Si cela se fait par sommet, nous revenons à l'interpolation linéaire des coordonnées résultantes le long de chaque arête, et nous avons perdu la non-linéarité que nous essayions d'introduire avec la coordonnée projective!
id
etcount
? Que faitUVs.ToArray()
-il? Comment téléchargez-vous les sommets et les coordonnées de texture sur la carte?