Je crée un maillage procédural basé sur une courbe et la taille du maillage diminue sur toute la courbe comme vous le voyez ci-dessous.
Et le problème est que les UV sont zigzagués lorsque la taille change (cela fonctionne parfaitement lorsque la taille du maillage est la même tout au long de la courbe).
Vertices.Add(R);
Vertices.Add(L);
UVs.Add(new Vector2(0f, (float)id / count));
UVs.Add(new Vector2(1f, (float)id / count));
start = Vertices.Count - 4;
Triangles.Add(start + 0);
Triangles.Add(start + 2);
Triangles.Add(start + 1);
Triangles.Add(start + 1);
Triangles.Add(start + 2);
Triangles.Add(start + 3);
mesh.vertices = Vertices.ToArray();
//mesh.normals = normales;
mesh.uv = UVs.ToArray();
mesh.triangles = Triangles.ToArray();
Comment puis-je réparer cela?
unity
procedural-generation
mesh
uv-mapping
fkkcloud
la source
la source
id
etcount
? Que faitUVs.ToArray()
-il? Comment téléchargez-vous les sommets et les coordonnées de texture sur la carte?id
est l'indice du segment actuel sur toutes les barres transversales le long de la bande, d'où il ycount
en a au total.List<T>.ToArray()
renvoie un tableau typé de toutes les entrées de la liste (alors ici, aVector2[]
). Ces tampons de données sont mis à la disposition du système de rendu en les affectant à l'Mesh
instancemesh
dans les dernières lignes. Mais rien de tout cela n'est la partie particulièrement intéressante du code: comment les points de sommet sont choisis. Ces détails seraient plus utiles à voir. ;)count
signifiait en fait des sommets au lieu de polygones, ou vice-versa. S'assurer que tout ce que nous pensons se passe vraiment.Réponses:
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:
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):
Vous devrez également découper la macro TRANSFORM_TEX dans le vertex shader, car elle attend un uv 2D:
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 :
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!
la source