Làm cách nào tôi có thể sửa các tạo phẩm ánh xạ UV zig-zagging trên lưới được tạo mà chỉnh sửa?


10

Tôi đang tạo một lưới thủ tục dựa trên một đường cong và kích thước của lưới sẽ nhỏ hơn trong suốt đường cong như bạn thấy dưới đây.

nhập mô tả hình ảnh ở đây

Và vấn đề là UV bị zig-zagged khi kích thước thay đổi (nó hoạt động hoàn hảo khi kích thước của lưới giống nhau trong suốt đường cong).

nhập mô tả hình ảnh ở đây

 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();

Làm thế nào tôi có thể sửa lỗi này?


Là gì idcount? Không gì UVs.ToArray()làm gì? Làm thế nào bạn tải lên các đỉnh và tọa độ kết cấu vào thẻ?
dùng1118321

@ user1118321 từ ngữ cảnh, idlà chỉ mục của phân khúc hiện tại trong số tất cả các thanh ngang dọc theo dải, trong đó có counttổng số. List<T>.ToArray()trả về một mảng được gõ của tất cả các mục trong danh sách (vì vậy ở đây, a Vector2[]). Các bộ đệm dữ liệu này được cung cấp cho hệ thống kết xuất bằng cách gán chúng cho Meshthể hiện meshtrong một vài dòng cuối cùng. Nhưng không ai trong số này là phần đặc biệt thú vị của mã: làm thế nào các điểm đỉnh được chọn. Những chi tiết sẽ hữu ích hơn để xem. ;)
DMGregory

Đó là giả định của tôi, nhưng tôi đã yêu cầu làm rõ vì đôi khi các giả định là sai. Tôi đã nhìn vào một cái gì đó giống như vậy trong mã của riêng tôi trong quá khứ chỉ để nhận ra rằng countthực sự có nghĩa là các đỉnh thay vì đa giác, hoặc ngược lại. Chỉ cần chắc chắn rằng tất cả mọi thứ chúng ta nghĩ đang diễn ra là thực sự đang diễn ra.
dùng1118321

Câu trả lời:


13

Ánh xạ UV điển hình là cái được gọi là phép biến đổi affine . Điều đó có nghĩa là ánh xạ của mỗi tam giác giữa không gian 3D và không gian kết cấu có thể bao gồm xoay, dịch, chia tỷ lệ / squash và nghiêng (nghĩa là bất cứ điều gì chúng ta có thể làm với phép nhân ma trận đồng nhất)

Vấn đề của các phép biến đổi affine là chúng đồng nhất trên toàn bộ miền của chúng - phép quay, dịch, tỷ lệ và độ nghiêng mà chúng ta áp dụng cho kết cấu gần đỉnh A giống như những gì chúng ta áp dụng gần đỉnh B, trong bất kỳ một tam giác nào. Các đường song song trong một không gian sẽ được ánh xạ thành các đường song song trong không gian khác, không bao giờ hội tụ / phân kỳ.

Nhưng sự giảm dần dần mà bạn đang cố gắng áp dụng không đồng nhất - đó là ánh xạ các đường song song trong kết cấu để hội tụ các đường trên lưới. Điều đó có nghĩa là quy mô của kết cấu được đo trên dải đang thay đổi liên tục khi chúng ta di chuyển xuống dải. Điều đó còn hơn cả các phép biến đổi affine của ánh xạ UV 2D có thể biểu thị chính xác: nội suy tọa độ uv 2D giữa các đỉnh liền kề sẽ có một tỷ lệ nhất quán dọc theo toàn bộ cạnh, ngay cả cạnh chéo sẽ bị thu hẹp theo tỷ lệ khi nó di chuyển xuống dải. Sự không phù hợp đó là những gì tạo ra ngoằn ngoèo.

Vấn đề này xuất hiện bất cứ lúc nào chúng ta muốn ánh xạ một hình chữ nhật thành hình thang - các mặt song song với các mặt hội tụ: không có biến đổi affine nào thực hiện điều này, vì vậy chúng ta phải ước tính nó một cách rõ ràng, dẫn đến các đường nối có thể nhìn thấy.

Đối với hầu hết các mục đích, bạn có thể giảm thiểu hiệu ứng bằng cách thêm nhiều hình học. Việc tăng số lượng các phân vùng dọc theo chiều dài của dải và chia dải thành hai hoặc nhiều đoạn dọc theo chiều rộng của nó, với các đường chéo của các hình tam giác được sắp xếp theo mô hình xương cá, có thể làm cho hiệu ứng ít được chú ý hơn. Nó sẽ luôn luôn xuất hiện ở một mức độ nào đó miễn là chúng ta đang sử dụng các phép biến đổi affine.

Nhưng có một cách xung quanh nó. Chúng ta có thể sử dụng cùng một mẹo mà chúng ta sử dụng để kết xuất 3D để vẽ hình thang theo phối cảnh cho các bức tường và sàn hình chữ nhật: chúng ta sử dụng tọa độ chiếu !

Kết cấu affine: Ví dụ về kết cấu affine bình thường với các tạo tác zig-zag

Hoạ tiết chiếu: Ví dụ về nhắn tin dự án sửa chữa các tạo phẩm

Để làm điều này, chúng ta cần thêm tọa độ uv thứ ba (uvw) và sửa đổi các shader của chúng ta.

Đưa ra một yếu tố tỷ lệ tại mỗi điểm (giả sử, bằng với độ rộng của dải của bạn tại điểm đó), bạn có thể xây dựng tọa độ uvw chiếu 3D từ tọa độ uv 2D thông thường của mình theo cách này:

Vector3 uv3 = ((Vector3)uv2) * scale;
uv3.z = scale;

Để áp dụng các tọa độ uvw 3D này cho lưới của bạn, bạn sẽ cần sử dụng các lưới Grid.SetUV quá tải Vector3 (kênh int, Danh sách uv)

Và hãy chắc chắn thay đổi cấu trúc đầu vào của shader của bạn để mong đợi tọa độ kết cấu 3D (được hiển thị ở đây bằng cách sử dụng trình đổ bóng không bật mặc định):

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.

Bạn cũng cần phải cắt bỏ macro TRANSFORM_TEX trong trình tạo bóng đỉnh, vì nó mong đợi một 2D 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;

Cuối cùng, để quay lại tọa độ kết cấu 2D để lấy mẫu kết cấu, bạn chỉ cần chia cho tọa độ thứ ba trong trình đổ bóng mảnh :

float2 uv = i.uv.xy / i.uv.z;

Vì chúng tôi đã thực hiện tọa độ uvw 3D này từ tọa độ 2D mong muốn của mình bằng cách nhân với cùng một số, hai thao tác hủy bỏ và chúng tôi quay lại tọa độ 2D mong muốn ban đầu của mình, nhưng bây giờ với phép nội suy phi tuyến tính giữa các đỉnh. : D

Điều quan trọng là phải thực hiện phép chia này cho mỗi phân đoạn chứ không phải trong trình tạo bóng đỉnh. Nếu nó được thực hiện trên mỗi đỉnh, thì chúng ta sẽ quay lại nội suy các tọa độ kết quả theo tuyến tính dọc theo mỗi cạnh và chúng ta đã mất tính phi tuyến mà chúng ta đang cố gắng giới thiệu với tọa độ chiếu!


Xin chào, tôi đã đấu tranh với cùng một vấn đề trong một thời gian khá lâu và điều này có vẻ như chính xác những gì đang xảy ra với tôi. Sự khác biệt duy nhất là tôi đang làm việc trong bajs chứ không phải trong sự thống nhất. Chúng tôi quản lý để giải quyết vấn đề bằng cách tăng số lượng hình tam giác, nhưng vẫn muốn thử kết cấu chiếu. Bạn có biết làm thế nào để bắt đầu thực hiện điều này trong bajs không? Cảm ơn bạn!
Dživo Jelić

1
Khá nhiều cách tương tự. Bạn cần một tọa độ kết cấu thứ ba để lưu trữ số chia, sau đó bạn thực hiện phép chia trong shader mảnh. Nếu bạn gặp khó khăn khi áp dụng điều này cho trường hợp của mình, việc đặt câu hỏi mới sẽ cho phép bạn bao gồm một mẫu mã, cho thấy cách bạn vẽ lưới của bạn cho đến nay, câu trả lời có thể được xây dựng.
DMGregory

Tôi có cần lưu trữ số chia dưới dạng tọa độ thứ ba không (và do cấu trúc thay đổi đó và cắt macro TRANSFORM_TEX, mà tôi không biết cách thực hiện trong bajs) hoặc tôi có thể chuyển ước số làm thuộc tính cho trình tạo bóng đỉnh và sau đó là sự thay đổi của shader mảnh, nơi nó có thể được sử dụng để phân chia?
Dživo Jelić

TRANSFORM_TEX là một macro Unity. Bạn không có trong ba.js nên không có gì để cắt. Chừng nào các tọa độ uv và các ước số được nội suy tiếp cận với shader mảnh, thì việc bạn có chúng ở đó như thế nào không quan trọng. Bạn đã gặp phải bất kỳ rắc rối nào khi cung cấp nó như một thuộc tính / thay đổi cho đến nay?
DMGregory

Tôi đã không thử vì tôi không muốn lãng phí thời gian cho đến khi tôi xác minh rằng điều đó là có thể. Chỉ một câu hỏi cuối cùng, số chia cũng sẽ được nội suy một khi nó đạt đến shader mảnh, đúng không? Có nghĩa là trên pixel giữa hai đỉnh nó sẽ là một số giá trị nội suy và không phải là giá trị ban đầu? Tôi gặp khó khăn trong việc xoay quanh lý do tại sao nhân tia UV và sau đó phân chia nó sẽ giúp ích, nhưng tôi sẽ tin lời bạn và thử nó. : hơi_smiling_face: Cảm ơn bạn rất nhiều sự giúp đỡ của bạn!
Dživo Jelić
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.