Saya memiliki rutin sprite khusus (openGL 2.0) yang menggunakan sprite sheet sederhana (tekstur saya disusun secara horizontal bersebelahan).
Jadi, misalnya, berikut adalah lembar sprite uji dengan 2 tekstur sederhana:
Sekarang, apa yang saya lakukan ketika membuat objek sprite openGL saya adalah menentukan jumlah total frame di atlasnya dan ketika menggambar, tentukan frame mana yang ingin saya gambar.
Kemudian berhasil menemukan tempat untuk mengambil tekstur dari dengan:
Membagi jumlah frame yang dibutuhkan dengan jumlah total frame (untuk mendapatkan koordinat kiri)
Dan kemudian menyelam 1 dengan jumlah total frame dan menambahkan hasilnya ke koordinat kiri yang dihitung di atas.
Ini sepertinya berhasil tetapi kadang-kadang saya mendapat masalah. Katakan misalnya, saya ingin menggambar X di bawah ini dan saya dapatkan ...........
Saya pernah mendengar tentang menempatkan 'padding' 1 px di antara setiap tekstur tetapi dapatkah seseorang menjelaskan dengan tepat bagaimana ini bekerja? Maksud saya jika saya melakukan ini pasti akan membuang perhitungan untuk mendapatkan tekstur.
Jika saya cukup memasukkan padding dalam tekstur yang diambil (jadi sprite digambar dengan batas kosong), maka tentunya ini akan menyebabkan masalah dengan deteksi tabrakan? (yaitu sprite mungkin tampak bertabrakan saat menggunakan kotak pembatas ketika bagian transparan bertabrakan).
Akan menghargai jika seseorang bisa menjelaskan.
sumber
GL_NEAREST
atauGL_LINEAR
untuk rendering tekstur?Jawaban:
Masalah dengan menggunakan atlas tekstur dan kebocoran texels yang berdekatan berkaitan dengan cara kerja penyaringan tekstur linier.
Untuk setiap titik dalam tekstur yang tidak disampel secara tepat di tengah texel, pengambilan sampel linier akan mengambil sampel 4 texel yang berdekatan dan menghitung nilai di lokasi yang Anda tanyakan sebagai bobot (berdasarkan jarak dari titik sampel) rata-rata semua 4 sampel.
Berikut visualisasi masalah yang bagus:
Karena Anda tidak dapat menggunakan sesuatu seperti
GL_CLAMP_TO_EDGE
pada atlas tekstur, Anda perlu membuat texels tepi di sekitar tepi setiap tekstur. Teks perbatasan ini akan mencegah sampel tetangga dari tekstur yang sangat berbeda di atlas mengubah gambar melalui interpolasi tertimbang yang dijelaskan di atas.Perhatikan bahwa ketika Anda menggunakan penyaringan anisotropik, Anda mungkin perlu menambah lebar perbatasan. Ini karena penyaringan anisotropik akan meningkatkan ukuran lingkungan sampel pada sudut ekstrem.
Untuk mengilustrasikan apa yang saya maksud dengan menggunakan batas di sekitar tepi setiap tekstur, pertimbangkan berbagai mode bungkus yang tersedia di OpenGL. Berikan perhatian khusus
CLAMP TO EDGE
.Meskipun ada mode yang disebut "Clamp to Border", itu sebenarnya bukan yang kami minati. Mode itu memungkinkan Anda menentukan satu warna untuk digunakan sebagai batas di sekitar tekstur Anda untuk setiap koordinat tekstur yang berada di luar batas normal [0,0] -1.0] jangkauan.
Yang kami inginkan adalah mereplikasi perilaku
CLAMP_TO_EDGE
, di mana setiap tekstur berkoordinasi di luar kisaran yang tepat untuk (sub-) tekstur menerima nilai dari pusat texel terakhir ke arah di luar batas. Karena Anda memiliki kontrol penuh atas koordinat tekstur dalam sistem atlas, satu-satunya skenario di mana koordinat tekstur (efektif) mungkin merujuk ke lokasi di luar tekstur Anda adalah selama langkah rata-rata tertimbang penyaringan tekstur.Kita tahu bahwa
GL_LINEAR
akan mengambil sampel 4 tetangga terdekat seperti yang terlihat pada diagram di atas, jadi kita hanya perlu perbatasan 1-texel. Anda mungkin memerlukan batas texel yang lebih luas jika Anda menggunakan pemfilteran anisotropik, karena ini meningkatkan ukuran lingkungan sampel dalam kondisi tertentu.Berikut adalah contoh tekstur yang menggambarkan batas lebih jelas, meskipun untuk tujuan Anda, Anda dapat membuat lebar 1 texel atau 2 texel lebar.
(CATATAN: Batas yang saya maksudkan bukan hitam di sekitar keempat tepi gambar, tetapi area tempat pola kotak-kotak berhenti berulang secara teratur)
Jika Anda bertanya-tanya, inilah mengapa saya terus memunculkan penyaringan anisotropik. Ini mengubah bentuk lingkungan sampel berdasarkan sudut dan dapat menyebabkan lebih dari 4 texels digunakan untuk memfilter:
http://www.arcsynthesis.org/gltut/Texturing/ParallelogramDiag.svg
Semakin besar tingkat anisotropi yang Anda gunakan, semakin besar kemungkinan Anda harus berurusan dengan lingkungan sampel yang mengandung lebih dari 4 texels. Batas 2 texel harus memadai untuk sebagian besar situasi penyaringan anisotropik.
Last but not least, di sini adalah bagaimana atlas tekstur dikemas akan dibangun yang akan mereplikasi
GL_CLAMP_TO_EDGE
perilaku di hadapanGL_LINEAR
filter tekstur:( Kurangi 1 dari X dan Y dalam koordinat hitam, saya tidak membuktikan membaca gambar sebelum memposting. )
Karena penyimpanan tepi, menyimpan 4 tekstur 256x256 di atlas ini membutuhkan tekstur dengan dimensi 516x516. Perbatasan diberi kode warna berdasarkan bagaimana Anda akan mengisinya dengan data texel selama pembuatan atlas:
Secara efektif dalam contoh yang dikemas ini, setiap tekstur di atlas menggunakan wilayah atlas 258x258, tetapi Anda akan menghasilkan koordinat tekstur yang memetakan ke wilayah 256x256 yang terlihat. Teks pembatas hanya pernah digunakan ketika penyaringan tekstur dilakukan di tepi tekstur di atlas, dan cara mereka dirancang meniru
GL_CLAMP_TO_EDGE
perilaku.Jika Anda bertanya-tanya, Anda dapat menerapkan jenis mode bungkus lainnya menggunakan pendekatan serupa -
GL_REPEAT
dapat diimplementasikan dengan menukar texels perbatasan kiri / kanan dan atas / bawah di atlas tekstur dan sedikit koordinat matematika dengan koordinat tekstur pandai dalam sebuah shader. Itu sedikit lebih rumit, jadi jangan khawatir tentang itu untuk saat ini. Karena Anda hanya berurusan dengan sprite sheet, batasi diri AndaGL_CLAMP_TO_EDGE
:)sumber