Bagaimana cara membalik tekstur BC6 / BC7?

8

Saya memiliki beberapa kode untuk memuat file gambar DDS ke dalam tekstur OpenGL, dan saya ingin memperpanjangnya untuk mendukung format terkompresi BC6 dan BC7 yang diperkenalkan dalam D3D11. Karena DirectX dan OpenGL tidak setuju tentang apakah asal tekstur berada di sudut kiri atas atau kiri bawah, loader DDS saya membalik setiap piksel gambar di sepanjang sumbu Y sebelum meneruskan piksel ke OpenGL.

Membalik tekstur terkompresi menghadirkan kerutan tambahan: selain membalik setiap baris blok 4x4-piksel, Anda juga perlu membalik piksel dalam setiap blok. Saya menemukan kode di sini untuk membalik blok BC1 / BC2 / BC3, dan dari diagram blok pada MSDN , mudah untuk mengadaptasi kode flipping BC3 untuk menangani BC4 dan BC5. Format BC6 dan BC7 terlihat jauh lebih mengintimidasi. Apakah ada trik bit-twiddling serupa untuk membalik format ini, atau apakah saya harus sepenuhnya mendekompres dan mengkompres ulang setiap blok?

UPDATE: Ternyata flip tekstur hanya diperlukan karena koordinat tekstur saya salah terbalik pada waktu ekspor. Menghapus kedua flips membuat kode lebih sederhana dan lebih cepat (terima kasih Humus!). Membalik blok BC6 / BC7 mungkin masih menjadi tantangan yang menarik, tetapi itu tidak lagi relevan dengan skenario asli saya.

postgoodism
sumber
1
Perhatikan bahwa jika Anda membalik koordinat tekstur alih-alih gambar tekstur, Anda tidak dapat menggunakan FBO dengan jerat / pelindung yang sama.
msell
Itu benar. Membiarkan tekstur DDS tidak dibalik juga menyebabkannya muncul terbalik di alat seperti gDEBugger . Hrm
postgoodism

Jawaban:

6

Saya menduga memang mungkin untuk membalik blok BC6-7 dengan pekerjaan yang jauh lebih sedikit daripada dekompresi dan kompres penuh, tetapi masih ada piknik dan jauh lebih kompleks daripada membalik blok BC1-5.

Pertama-tama, BC6-7 memiliki berbagai mode yang dapat dipilih per blok. Mode memiliki tata letak biner yang sama sekali berbeda, jadi Anda harus menulis rutin flip yang berbeda untuk setiap mode (ada ~ 20 di antaranya, IIRC).

Kesulitan lain adalah mode dipartisi, di mana piksel dalam blok dipartisi menjadi 2 atau 3 himpunan bagian, masing-masing dengan segmen garis RGB sendiri. Partisi harus dipilih dari set yang telah ditentukan; yang untuk BC6 dapat dilihat di sini . Masalahnya adalah set partisi ini tidak simetris di bawah membalik vertikal. Namun, saya menduga itu adalah simetris di bawah beberapa kombinasi membalik vertikal dan mempertukarkan dua himpunan bagian. Sebagai contoh, melihat partisi # 22 (baris ke-6, kolom ke-3) pada tautan itu, tidak ada versi terbalik secara vertikal di tabel, tetapi jika Anda membalik secara vertikal daninterchange 0s dan 1s, Anda berakhir dengan partisi # 9 (baris ke-3, kolom ke-2). Saya belum memverifikasi bahwa setiap partisi dapat dibalik dengan cara ini, saya juga belum memeriksa yang untuk BC7 (yang juga termasuk partisi dengan 3 himpunan bagian).

Bahkan jika itu berhasil, Anda masih belum bebas dari rumah. Dalam BC1-5, urutan dua titik akhir dari segmen garis RGB digunakan untuk beralih mode, tetapi dalam BC6-7 urutan titik akhir dipilih untuk memperbaiki satu bit dari indeks per-pixel di setiap subset partisi. Karena itu jika Anda mengubah partisi di sekitar Anda mungkin juga harus menukar urutan titik akhir.

Dan last but not least, dalam BC6-7 titik akhir sering dikompresi-delta (yaitu satu titik akhir disimpan pada presisi penuh dan yang lain disimpan sebagai delta dengan presisi lebih rendah dari itu). Menukar subset partisi dan urutan titik akhir akan mengganti titik akhir mana yang merupakan titik presisi tinggi, sehingga Anda harus mengocok bit berpresisi rendah sekitar dan meniadakan beberapa delta.

Semua dalam semua, sepertinya tidak ada showstopper mendasar (meskipun saya belum benar-benar menulis kode), tetapi pasti akan banyak pekerjaan untuk membalik atau memutar format ini. Jika memungkinkan, saya sarankan membalik gambar dalam pipa seni Anda sebelum mereka dikompresi.

(BTW, spesifikasi BC6-7 terlengkap yang saya temukan adalah spesifikasi ARB_texture_compression_bptc ; Saya juga menulis posting blog tentang format BCn beberapa waktu lalu.)

Nathan Reed
sumber
Terima kasih; Saya cukup ketakutan. Saya benar-benar pergi mencari posting blog Anda, tetapi tidak dapat mengingat tautannya. Ini adalah sumber yang bagus untuk semua hal BCn; itu saja layak mendapat dukungan!
postgoodism
0

Pembalikan hanya masalah default pada dua format. Anda bisa melawan default.

Ini mungkin lebih baik untuk dilakukan di sisi OpenGL, karena OpenGL adalah tingkat yang lebih rendah, dan dengan demikian lebih kecil kemungkinannya kehilangan optimasi ketika melakukan hal-hal seperti ini.

Robert Wm Ruedisueli
sumber