Làm thế nào để lật một kết cấu BC6 / BC7?


8

Tôi có một số mã để tải các tệp hình ảnh DDS vào kết cấu OpenGL và tôi muốn mở rộng nó để hỗ trợ các định dạng nén BC6 và BC7 được giới thiệu trong D3D11. Vì DirectX và OpenGL không đồng ý về việc nguồn gốc của kết cấu nằm ở góc trên bên trái hay góc dưới bên trái, trình tải DDS của tôi lật từng pixel của hình ảnh dọc theo trục Y trước khi chuyển pixel sang OpenGL.

Lật các kết cấu nén thể hiện một nếp nhăn bổ sung: ngoài việc lật từng hàng khối 4 pixel, bạn cũng cần lật các pixel trong mỗi khối. Tôi tìm thấy mã ở đây để lật các khối BC1 / BC2 / BC3 và từ sơ đồ khối trên MSDN , thật dễ dàng để điều chỉnh mã lật BC3 để xử lý BC4 và BC5. Các định dạng BC6BC7 trông đáng sợ hơn đáng kể, mặc dù. Có một mẹo xoay vòng bit tương tự để lật các định dạng này, hoặc tôi sẽ phải giải nén hoàn toàn và giải nén từng khối?

CẬP NHẬT: Hóa ra việc lật kết cấu chỉ cần thiết vì tọa độ kết cấu của tôi bị đảo ngược không chính xác tại thời điểm xuất. Loại bỏ cả hai lần lật làm cho mã đơn giản hơn nhanh hơn (cảm ơn Humus!). Lật các khối BC6 / BC7 có thể vẫn là một thử thách thú vị, nhưng nó không còn phù hợp với kịch bản ban đầu của tôi.


1
Lưu ý rằng nếu bạn lật tọa độ kết cấu thay vì hình ảnh kết cấu, bạn không thể sử dụng FBO với cùng một mắt lưới / bóng.
msell

Điều đó đúng. Việc bỏ kết cấu DDS không bị xóa cũng khiến chúng xuất hiện lộn ngược trong các công cụ như gDEBugger . Hrm.
nghĩa hậu hiện đại

Câu trả lời:


6

Tôi nghi ngờ nó thực sự có thể lật BC6-7 khối với công việc ít hơn nhiều so với một giải nén đầy đủ và nén lại, nhưng nó vẫn không có bữa ăn ngoài trời và nhiều phức tạp hơn lật BC1-5 khối.

Trước hết, BC6-7 có nhiều chế độ có thể được chọn cho mỗi khối. Các chế độ có bố cục nhị phân hoàn toàn khác nhau, do đó bạn sẽ phải viết một thói quen lật khác nhau cho mỗi chế độ (có ~ 20 trong số chúng hoàn toàn, IIRC).

Một khó khăn khác là các chế độ được phân vùng, trong đó các pixel trong khối được phân vùng thành 2 hoặc 3 tập hợp con, mỗi pixel có phân đoạn dòng RGB riêng. Phân vùng phải được chọn từ một bộ được xác định trước; những cái cho BC6 có thể được nhìn thấy ở đây . Vấn đề là bộ phân vùng này không đối xứng dưới các lật dọc. Tuy nhiên, tôi nghi ngờ nó đối xứng dưới sự kết hợp của một số lật dọc và hoán đổi hai tập con. Ví dụ: nhìn vào phân vùng # 22 (hàng thứ 6, cột thứ 3) tại liên kết đó, không có phiên bản lật theo chiều dọc của bảng trong bảng, nhưng nếu bạn lật theo chiều dọc trao đổi 0 và 1, bạn kết thúc với phân vùng # 9 (hàng thứ 3, cột thứ 2). Tôi chưa xác minh rằng mọi phân vùng có thể được lật theo cách này, tôi cũng chưa kiểm tra các phân vùng cho BC7 (cũng bao gồm các phân vùng có 3 tập con).

Ngay cả khi điều đó hoạt động, bạn vẫn không ở nhà miễn phí. Trong BC1-5, thứ tự của hai điểm cuối của phân đoạn dòng RGB đã được sử dụng để chuyển đổi chế độ, nhưng trong BC6-7, thứ tự các điểm cuối được chọn để sửa một bit của các chỉ số mỗi pixel trong mỗi tập hợp phân vùng. Do đó, nếu bạn thay đổi phân vùng xung quanh, bạn cũng có thể phải trao đổi thứ tự các điểm cuối.

Và cuối cùng nhưng không kém phần quan trọng, trong BC6-7, các điểm cuối thường được nén delta (tức là một điểm cuối được lưu trữ ở độ chính xác hoàn toàn và các điểm cuối khác được lưu trữ dưới dạng các vùng đồng bằng có độ chính xác thấp hơn từ nó). Hoán đổi các tập hợp phân vùng và thứ tự điểm cuối sẽ chuyển đổi điểm cuối nào là độ chính xác cao, do đó bạn sẽ phải xáo trộn các bit có độ chính xác thấp xung quanh và phủ nhận một số vùng đồng bằng.

Nói chung, có vẻ như không có bất kỳ showstopper cơ bản nào (mặc dù tôi chưa thực sự viết mã), nhưng chắc chắn sẽ có rất nhiều công việc để lật hoặc xoay các định dạng này. Nếu có thể, tôi khuyên bạn nên lật hình ảnh trong đường ống nghệ thuật của bạn trước khi chúng bị nén.

(BTW, thông số kỹ thuật đầy đủ nhất của BC6-7 tôi đã tìm thấy là thông số ARB lòngure_compression_bptc ; Tôi cũng đã viết một bài đăng blog về các định dạng BCn một thời gian trước.)


Cảm ơn; Tôi đủ kinh hoàng. Tôi thực sự đã tìm kiếm bài đăng trên blog của bạn, nhưng không thể nhớ liên kết. Đó là một nguồn tài nguyên tuyệt vời về tất cả mọi thứ BCn; điều đó một mình cũng có giá trị upvote!
postgoodism

0

Việc lật chỉ là vấn đề mặc định trên hai định dạng. Bạn có thể đi ngược lại mặc định.

Điều này có lẽ tốt hơn để làm ở phía OpenGL, vì OpenGL ở mức thấp hơn và do đó ít có khả năng mất tối ưu hóa khi làm những việc như thế này.

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.