Saya membuat mesh prosedural berdasarkan kurva dan ukuran mesh semakin kecil di seluruh kurva seperti yang Anda lihat di bawah ini.
Dan masalahnya adalah UV akan zig-zag sebagai perubahan ukuran (ini bekerja dengan sempurna ketika ukuran mesh sama di seluruh kurva).
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();
Bagaimana saya bisa memperbaikinya?
unity
procedural-generation
mesh
uv-mapping
fkkcloud
sumber
sumber
id
dancount
? Apa yangUVs.ToArray()
harus dilakukan Bagaimana cara Anda mengunggah koordinat titik dan tekstur ke kartu?id
adalah indeks dari segmen saat ini dari semua bilah di sepanjang strip, di mana adacount
total.List<T>.ToArray()
mengembalikan array yang diketik dari semua entri dalam daftar (jadi di sini, aVector2[]
). Buffer data ini tersedia untuk sistem render dengan menetapkannya keMesh
instancemesh
dalam beberapa baris terakhir. Tetapi tidak satu pun dari ini adalah bagian yang sangat menarik dari kode: bagaimana titik titik dipilih. Detail-detail itu akan lebih bermanfaat untuk dilihat. ;)count
sebenarnya berarti simpul, bukan poligon, atau sebaliknya. Memastikan semua yang kita pikir sedang terjadi benar-benar terjadi.Jawaban:
Pemetaan UV khas adalah apa yang disebut transformasi affine . Itu berarti pemetaan setiap segitiga antara ruang 3D dan ruang tekstur dapat mencakup rotasi, terjemahan, penskalaan / squash, dan condong (mis. Apa pun yang dapat kita lakukan dengan perkalian matriks homogen)
Hal tentang transformasi affine adalah bahwa mereka seragam di seluruh domain mereka - rotasi, terjemahan, skala, dan condong yang kami terapkan pada tekstur dekat vertex A sama dengan apa yang kami terapkan di dekat vertex B, dalam salah satu segitiga. Garis-garis yang paralel dalam satu ruang akan dipetakan ke garis-garis paralel di ruang lain, tidak pernah konvergen / menyimpang.
Tetapi tapering bertahap yang Anda coba terapkan tidak seragam - memetakan garis paralel dalam tekstur ke garis konvergen pada jala. Itu berarti skala tekstur yang diukur di seluruh band berubah terus-menerus saat kami bergerak ke bawah jalur. Itu lebih dari transformasi affine dari pemetaan UV 2D yang dapat secara akurat mewakili: interpolasi koordinat 2D uv antara simpul yang berdekatan akan mendapatkan satu skala yang konsisten di sepanjang tepi, bahkan tepi diagonal yang harus menyusut dalam skala ketika bergerak ke bawah strip. Ketidakcocokan itu adalah apa yang menciptakan zigzag warbling ini.
Masalah ini muncul kapan saja kami ingin memetakan persegi panjang ke trapesium - sisi paralel ke sisi konvergen: tidak ada transformasi affine yang melakukan ini, jadi kami harus memperkirakannya sedikit demi sedikit, yang mengarah ke jahitan yang terlihat.
Untuk sebagian besar tujuan, Anda dapat meminimalkan efek dengan menambahkan lebih banyak geometri. Menambah jumlah subdivisi sepanjang panjang strip, dan membelah strip menjadi dua atau lebih segmen sepanjang lebarnya, dengan diagonal segitiga yang diatur dalam pola herringbone, dapat membuat efeknya kurang terlihat. Akan selalu ada sampai batas tertentu selama kita menggunakan transformasi affine.
Tapi ada jalan lain. Kita dapat menggunakan trik yang sama yang kita gunakan untuk rendering 3D untuk menggambar trapesium dalam perspektif yang diberikan dinding & lantai persegi panjang: kita menggunakan koordinat proyektif !
Affine texturing:
Tekstur projektif:
Untuk melakukan ini, kita perlu menambahkan koordinat uv ketiga (uvw) dan memodifikasi shader kita.
Diberikan faktor skala pada setiap titik (katakanlah, sama dengan luas strip Anda di tempat itu), Anda dapat membuat koordinat 3D proyektif uvw dari koordinat 2D uv biasa dengan cara ini:
Untuk menerapkan koordinat 3D uvw ini ke mesh Anda, Anda harus menggunakan Vector3 overload Mesh. SetUVs (saluran int, List uvs)
Dan pastikan untuk mengubah struct input shader Anda untuk mengharapkan koordinat tekstur 3D (ditampilkan di sini menggunakan shader unlit default):
Anda juga harus memotong makro TRANSFORM_TEX di vertex shader, karena mengharapkan 2D uv:
Akhirnya, untuk kembali ke koordinat tekstur 2D untuk pengambilan sampel tekstur, Anda hanya membaginya dengan koordinat ketiga dalam shader fragmen Anda :
Karena kami membuat koordinat uvw 3D ini dari koordinat 2D yang dikehendaki dengan mengalikannya dengan angka yang sama, kedua operasi dibatalkan dan kami kembali ke koordinat 2D yang dikehendaki, tetapi sekarang dengan interpolasi non-linear antar simpul. : D
Sangat penting untuk melakukan pembagian ini per fragmen dan tidak di vertex shader. Jika dilakukan per titik, maka kita kembali menginterpolasi koordinat yang dihasilkan secara linier di setiap sisi, dan kami telah kehilangan nonlinier yang kami coba perkenalkan dengan koordinat proyektif!
sumber