Ich erstelle ein prozedurales Netz basierend auf einer Kurve und die Größe des Netzes wird in der gesamten Kurve kleiner, wie Sie unten sehen.
Das Problem ist, dass UV-Strahlen im Zick-Zack-Modus auftreten, wenn sich die Größe ändert (dies funktioniert perfekt, wenn die Größe des Netzes in der gesamten Kurve gleich ist).
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();
Wie kann ich das beheben?
unity
procedural-generation
mesh
uv-mapping
fkkcloud
quelle
quelle
id
undcount
? Was machtUVs.ToArray()
das Wie lade ich die Eckpunkte und Texturkoordinaten auf die Karte hoch?id
ist der Index des aktuellen Segments aller Querbalken entlang des Streifens, von denen insgesamt vorhanden sindcount
.List<T>.ToArray()
Gibt ein typisiertes Array aller Einträge in der Liste zurück (also hier aVector2[]
). Diese Datenpuffer werden dem Rendering-System zur Verfügung gestellt, indem sie in den letzten Zeilen derMesh
Instanzmesh
zugewiesen werden. Aber nichts davon ist der besonders interessante Teil des Codes: wie die Scheitelpunkte ausgewählt werden. Diese Details wären nützlicher zu sehen. ;)count
tatsächlich Eckpunkte anstelle von Polygonen bedeutete oder umgekehrt. Nur sicherzustellen, dass alles, was wir denken, wirklich los ist.Antworten:
Typisches UV-Mapping ist eine sogenannte affine Transformation . Das bedeutet, dass die Zuordnung jedes Dreiecks zwischen 3D-Raum und Texturraum Rotation, Translation, Skalierung / Squash und Skew umfassen kann (dh alles, was wir mit einer homogenen Matrixmultiplikation tun können).
Die Sache mit affinen Transformationen ist, dass sie über ihre gesamte Domäne hinweg einheitlich sind - die Rotation, Translation, Skalierung und der Versatz, die wir auf die Textur in der Nähe von Scheitelpunkt A anwenden, sind die gleichen wie die, die wir in der Nähe von Scheitelpunkt B innerhalb eines Dreiecks anwenden. Linien, die in einem Raum parallel sind, werden parallelen Linien im anderen zugeordnet, ohne zu konvergieren / divergieren.
Die allmähliche Verjüngung, die Sie anwenden möchten, ist jedoch nicht einheitlich. Sie ordnet parallele Linien in der Textur konvergierenden Linien im Netz zu. Das bedeutet, dass sich die Skala der über das Band gemessenen Textur kontinuierlich ändert, wenn wir uns den Streifen entlang bewegen. Das ist mehr, als die affinen Transformationen der 2D-UV-Abbildung genau darstellen können: Durch Interpolation von 2D-UV-Koordinaten zwischen benachbarten Scheitelpunkten wird eine konsistente Skalierung entlang der gesamten Kante erhalten, selbst die diagonale Kante, deren Skalierung schrumpfen sollte, wenn sie sich entlang des Streifens bewegt. Diese Nichtübereinstimmung schafft diesen trälelnden Zickzack.
Dieses Problem tritt immer dann auf, wenn wir ein Rechteck einem Trapez zuordnen möchten - parallele Seiten zu konvergierenden Seiten: Es gibt einfach keine affine Transformation, die dies tut, daher müssen wir es stückweise approximieren, was zu sichtbaren Nähten führt.
In den meisten Fällen können Sie den Effekt minimieren, indem Sie mehr Geometrie hinzufügen. Durch Erhöhen der Anzahl der Unterteilungen entlang der Länge des Streifens und Aufteilen des Streifens in zwei oder mehr Segmente entlang seiner Breite, wobei die Diagonalen der Dreiecke in einem Fischgrätenmuster angeordnet sind, kann der Effekt viel weniger auffällig werden. Es wird immer bis zu einem gewissen Grad vorhanden sein, solange wir affine Transformationen verwenden.
Aber es gibt einen Weg, um das zu umgehen. Wir können denselben Trick verwenden, den wir für das 3D-Rendering verwenden, um Trapezoide bei rechteckigen Wänden und Böden perspektivisch zu zeichnen: Wir verwenden projektive Koordinaten !
Affine Texturierung:
Projektive Texturierung:
Dazu müssen wir eine dritte UV-Koordinate (UVW) hinzufügen und unsere Shader ändern.
Wenn Sie an jedem Punkt einen Skalierungsfaktor angeben (z. B. gleich der Breite Ihres Streifens an dieser Stelle), können Sie die projektive 3D-UVW-Koordinate aus Ihrer regulären 2D-UV-Koordinate folgendermaßen konstruieren:
Um diese 3D-UVW-Koordinaten auf Ihr Netz anzuwenden, müssen Sie die Vector3-Überlast Mesh.SetUVs (int channel, List uvs) verwenden.
Ändern Sie unbedingt die Eingabestruktur Ihres Shaders, um eine 3D-Texturkoordinate zu erwarten (hier mit dem standardmäßigen unbeleuchteten Shader dargestellt):
Sie müssen auch das TRANSFORM_TEX-Makro im Vertex-Shader ausschneiden, da es eine 2D-UV erwartet:
Um zu einer 2D-Texturkoordinate für die Texturabtastung zurückzukehren, dividieren Sie einfach durch die dritte Koordinate in Ihrem Fragment-Shader :
Da wir diese 3D-UVW-Koordinate aus unserer gewünschten 2D-Koordinate durch Multiplizieren mit derselben Zahl erstellt haben, werden die beiden Operationen aufgehoben und wir kehren zu unserer ursprünglichen gewünschten 2D-Koordinate zurück, jedoch jetzt mit nichtlinearer Interpolation zwischen den Scheitelpunkten. : D.
Es ist wichtig, diese Aufteilung pro Fragment und nicht im Vertex-Shader vorzunehmen. Wenn dies pro Scheitelpunkt erfolgt, werden die resultierenden Koordinaten wieder linear entlang jeder Kante interpoliert, und wir haben die Nichtlinearität verloren, die wir mit der projektiven Koordinate einführen wollten!
quelle