Hoạ tiết tấm Sprite chọn các cạnh của kết cấu liền kề


10

Tôi có một thói quen sprite tùy chỉnh (openGL 2.0) sử dụng một bảng sprite đơn giản (kết cấu của tôi được sắp xếp theo chiều ngang cạnh nhau).

Vì vậy, ví dụ, đây là một bảng sprite thử nghiệm với 2 kết cấu đơn giản:

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

Bây giờ, những gì tôi làm khi tạo đối tượng sprite openGL của mình là chỉ định tổng số khung trong tập bản đồ của nó và khi vẽ, chỉ định khung tôi muốn vẽ.

Sau đó, nó tìm ra nơi để lấy kết cấu từ:

Chia số khung cần thiết cho tổng số khung (để có tọa độ trái)

Và sau đó lặn 1 bằng tổng số khung và thêm kết quả vào tọa độ tay trái được tính ở trên.

Điều này dường như làm việc nhưng đôi khi tôi gặp vấn đề. Nói ví dụ, tôi muốn vẽ X bên dưới và tôi nhận được ...........

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

Tôi đã nghe nói về việc đặt 'phần đệm' 1 px giữa mỗi kết cấu nhưng ai đó có thể giải thích chính xác cách thức hoạt động của nó không? Tôi có nghĩa là nếu tôi làm điều này, nó chắc chắn sẽ bỏ qua các tính toán để có được kết cấu.

Nếu tôi đơn giản bao gồm phần đệm trong kết cấu nhặt được (vì vậy sprite được vẽ với một đường viền trống), thì chắc chắn điều này sẽ gây ra vấn đề với phát hiện va chạm? (tức là các sprite có thể va chạm khi sử dụng các hộp giới hạn khi các phần trong suốt va chạm vào nhau).

Sẽ đánh giá cao nếu ai đó có thể giải thích.


Bạn đang sử dụng GL_NEARESThoặc GL_LINEARđể kết xuất các kết cấu?
MichaelHouse

Tôi đang sử dụng GL_Linear @ Byte56
BungleBonce

Câu trả lời:


15

Vấn đề với việc sử dụng các bản đồ kết cấu và rò rỉ texels liền kề có liên quan đến cách thức lọc kết cấu tuyến tính hoạt động.

Đối với bất kỳ điểm nào trong kết cấu không được lấy mẫu chính xác ở trung tâm của texel, lấy mẫu tuyến tính sẽ lấy mẫu 4 tex liền kề và tính giá trị tại vị trí bạn đã hỏi theo trọng số (dựa trên khoảng cách từ điểm mẫu) trung bình của cả 4 mẫu.

Đây là một hình dung tốt đẹp của vấn đề:

  

Vì bạn không thể sử dụng một cái gì đó giống như GL_CLAMP_TO_EDGEtrong tập bản đồ kết cấu, bạn cần tạo các đường viền quanh viền của mỗi họa tiết. Các texels đường viền này sẽ ngăn các mẫu lân cận từ các kết cấu hoàn toàn khác nhau trong tập bản đồ thay đổi hình ảnh thông qua phép nội suy có trọng số được giải thích ở trên.

Lưu ý rằng khi bạn sử dụng lọc bất đẳng hướng, bạn có thể cần tăng chiều rộng của đường viền. Điều này là do lọc bất đẳng hướng sẽ làm tăng kích thước của vùng lân cận mẫu ở các góc cực.


Để minh họa ý tôi muốn nói bằng cách sử dụng đường viền xung quanh mép của mỗi họa tiết, hãy xem xét các chế độ bao bọc khác nhau có sẵn trong OpenGL. Đặc biệt chú ý đến CLAMP TO EDGE.

  http://lucera-project.com/blog/wp-content/uploads/2010/06/wrap.png

Mặc dù có một chế độ gọi là "Kẹp vào viền", nhưng đó thực sự không phải là điều chúng tôi quan tâm. Chế độ đó cho phép bạn xác định một màu duy nhất để sử dụng làm đường viền xung quanh kết cấu của bạn cho bất kỳ tọa độ kết cấu nào nằm ngoài chuẩn hóa [0,0 -1.0] phạm vi.

Những gì chúng tôi muốn là sao chép hành vi của CLAMP_TO_EDGE, trong đó bất kỳ kết cấu nào nằm ngoài phạm vi thích hợp cho kết cấu (phụ) nhận giá trị của trung tâm texel cuối cùng theo hướng nằm ngoài giới hạn. Vì bạn gần như hoàn toàn kiểm soát tọa độ kết cấu trong một hệ thống bản đồ, kịch bản duy nhất trong đó tọa độ kết cấu (hiệu quả) có thể đề cập đến một vị trí bên ngoài kết cấu của bạn trong bước lọc trung bình có trọng số.

Chúng tôi biết rằng GL_LINEARsẽ lấy mẫu 4 hàng xóm gần nhất như đã thấy trong sơ đồ trên, vì vậy chúng tôi chỉ cần đường viền 1-texel. Bạn có thể cần một đường viền texel rộng hơn nếu bạn sử dụng bộ lọc bất đẳng hướng, bởi vì nó làm tăng kích thước vùng lân cận mẫu trong các điều kiện nhất định.

Dưới đây là một ví dụ về kết cấu minh họa đường viền rõ ràng hơn, mặc dù với mục đích của bạn, bạn có thể làm cho đường viền rộng 1 texel hoặc 2 texels.

  

(LƯU Ý: Đường viền tôi đang đề cập không phải là màu đen xung quanh tất cả bốn cạnh của hình ảnh, mà là khu vực nơi mẫu hình bàn cờ dừng lặp lại thường xuyên)

Trong trường hợp bạn đang tự hỏi, đây là lý do tại sao tôi tiếp tục đưa ra bộ lọc bất đẳng hướng. Nó thay đổi hình dạng của vùng lân cận mẫu dựa trên góc và có thể khiến hơn 4 texels được sử dụng để lọc:

  http: //www.arcsyntribution.org/gltut/Texturing/ParallelogramDiag.svg

Mức độ bất đẳng hướng bạn sử dụng càng lớn, bạn càng có nhiều khả năng phải đối phó với các vùng lân cận mẫu có chứa hơn 4 texels. Đường viền 2 texel phải phù hợp với hầu hết các tình huống lọc bất đẳng hướng.


Cuối cùng nhưng không kém phần quan trọng, đây là cách một tập bản đồ kết cấu được đóng gói sẽ tái tạo GL_CLAMP_TO_EDGEhành vi với sự có mặt của GL_LINEARbộ lọc kết cấu:

( Trừ 1 từ X và Y ở tọa độ màu đen, tôi không chứng minh đã đọc hình ảnh trước khi đăng. )   

Do lưu trữ đường viền, lưu trữ 4 kết cấu 256x256 trong tập bản đồ này yêu cầu kết cấu có kích thước 516x516. Các đường viền được mã hóa màu dựa trên cách bạn sẽ điền chúng với dữ liệu texel trong quá trình tạo bản đồ:

  • Đỏ = Thay thế bằng texel ngay bên dưới
  • Vàng = Thay thế bằng texel trực tiếp ở trên
  • Màu xanh lá cây = Thay thế bằng texel trực tiếp bên trái
  • Blue = Thay thế bằng texel trực tiếp bên phải

Thực tế trong ví dụ được đóng gói này, mỗi kết cấu trong tập bản đồ sử dụng vùng 258x258 của tập bản đồ, nhưng bạn sẽ tạo tọa độ kết cấu ánh xạ tới vùng 256x256 có thể nhìn thấy. Các texels giáp chỉ được sử dụng khi lọc kết cấu được thực hiện ở các cạnh của kết cấu trong tập bản đồ, và cách chúng được thiết kế bắt chước GL_CLAMP_TO_EDGEhành vi.

Trong trường hợp bạn đang tự hỏi, bạn có thể thực hiện các loại chế độ quấn khác bằng cách sử dụng một cách tiếp cận tương tự - GL_REPEATcó thể được thực hiện bằng cách trao đổi các texels biên trái / phải và trên / dưới trong tập bản đồ kết cấu và một chút toán học phối hợp kết cấu thông minh trong một đổ bóng. Điều đó phức tạp hơn một chút, vì vậy bây giờ đừng lo lắng về điều đó. Vì bạn chỉ làm việc với các tấm sprite giới hạn bản thân mình GL_CLAMP_TO_EDGE:)


Cảm ơn @AndonMColeman, bạn có thể hiển thị đường viền trong sơ đồ vì tôi vẫn không chắc tôi hiểu cách thức hoạt động của nó - một lần nữa có nghĩa là khi kết cấu được áp dụng cho đối tượng của tôi, nó sẽ bao gồm đường viền? Tôi muốn kết cấu thực tế đi thẳng vào các cạnh của bộ tứ của tôi - xin lỗi nếu tôi không hiểu chính xác điều này - sẽ đánh giá cao một số chi tiết khác - cảm ơn
BungleBonce

@ user22241 Chắc chắn, cách thức hoạt động của đường viền này là bằng cách sao chép texel ở cạnh của kết cấu.
Andon M. Coleman

@ user22241: Không, đường viền này sẽ không hiển thị trong các trường hợp thông thường. Bạn sẽ coi kết cấu được đóng gói của mình là có cùng kích thước để tính toán tọa độ kết cấu, bạn chỉ cần áp dụng một phần bù cho chúng để bỏ qua đường viền. Toàn bộ điểm của đường viền là để ngăn việc lấy mẫu kết cấu tuyến tính quá mức và lấy mẫu texels thuộc về các hình ảnh riêng biệt trong bảng sprite của bạn. Nếu bạn sử dụng lấy mẫu hàng xóm gần nhất thì không cần thiết, nhưng sau đó bạn sẽ nhận được các sprite bí danh khó chịu.
Andon M. Coleman

Câu trả lời rất chi tiết - cảm ơn! Chỉ một điều cuối cùng nếu tôi có thể. Làm thế nào tôi có thể tìm ra 'offset' để thêm vào tọa độ kết cấu của mình? Tôi có đúng không khi nói nó chỉ đơn giản là 1 / widthOfTexture?
BungleBonce

@ user22241: Có, bắt đầu của hình ảnh kết cấu sẽ là + 1 / widthOfTexture theo hướng X và + 1 / heightOfTexture theo hướng Y. Bạn sẽ có một đường viền bao quanh tất cả các kết cấu. Vào thời điểm bạn muốn tính toán tọa độ kết cấu cho kết cấu ngang thứ 3, vị trí đóng gói cho kết cấu này thực sự là +5 texels (+2 texels cho đường viền của họa tiết thứ nhất, +2 cho đường viền của kết cấu thứ hai và +1 cho bắt đầu của kết cấu này) ngoài chiều rộng của 2 kết cấu khác. Có vẻ phức tạp chỉ viết nó; Tôi có thể vẽ cho bạn một sơ đồ nếu cần :)
Andon M. Coleman
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.