Di gim saya ada medan mirip Minecraft yang terbuat dari kubus. Saya menghasilkan buffer vertex dari data voxel dan menggunakan atlas tekstur untuk tampilan blok yang berbeda:
Masalahnya adalah bahwa tekstur kubus jauh interpolasi dengan ubin yang berdekatan di atlas tekstur. Itu menghasilkan garis-garis warna yang salah di antara kubus (Anda mungkin perlu melihat tangkapan layar di bawah dalam ukuran penuh untuk melihat kekurangan grafis):
Untuk saat ini saya menggunakan pengaturan interpolasi ini tetapi saya mencoba setiap kombinasi dan bahkan GL_NEAREST
tanpa memetakan tidak memberikan hasil yang lebih baik.
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
Saya juga mencoba menambahkan offset dalam koordinat tekstur untuk memilih area ubin yang sedikit lebih kecil tetapi karena efek yang tidak diinginkan tergantung pada jarak ke kamera ini tidak dapat menyelesaikan masalah sepenuhnya. Di kejauhan, garis-garis itu tetap terjadi.
Bagaimana saya bisa mengatasi pendarahan tekstur ini? Karena menggunakan atlas tekstur adalah teknik yang populer, mungkin ada pendekatan umum. Sayangnya, untuk beberapa alasan yang dijelaskan dalam komentar, saya tidak dapat mengubah tekstur atau array tekstur yang berbeda.
GL_LINEAR
yang memberikan hasil yang sama atau memilih piksel terdekatGL_NEAREST
yang bagaimanapun juga menghasilkan garis-garis di antara blok. Opsi yang disebutkan terakhir berkurang tetapi tidak menghilangkan cacat piksel.Jawaban:
Oke, saya pikir Anda memiliki dua masalah yang terjadi di sini.
Masalah pertama adalah dengan memetakan. Secara umum, Anda tidak ingin secara naif mencampur atlasing dengan pemetaan, karena kecuali semua subteks Anda berukuran tepat 1x1 piksel, Anda akan mengalami pendarahan tekstur. Menambahkan padding hanya akan memindahkan masalah ke level mip yang lebih rendah.
Sebagai aturan praktis, untuk 2D, yang biasanya Anda lakukan atlasing, Anda tidak mipmap; sedangkan untuk 3D, yang merupakan tempat Anda mipmap, Anda tidak atlas (sebenarnya, Anda menguliti sedemikian rupa sehingga perdarahan tidak akan menjadi masalah)
Namun, apa yang saya pikir sedang terjadi dengan program Anda saat ini adalah bahwa Anda mungkin tidak menggunakan koordinat tekstur yang benar, dan karena itu tekstur Anda berdarah.
Misalkan tekstur 8x8. Anda mungkin mendapatkan kuartal kiri atas dengan menggunakan koordinat uv dari (0,0) hingga (0,5, 0,5):
Dan masalahnya adalah bahwa pada koordinat -0 0,5, sampler akan menginterpolasi fragmen tujuan menggunakan setengah dari texel kiri dan setengah dari texel kanan. Hal yang sama akan terjadi pada koordinat u 0, dan sama untuk koordinat v. Ini karena Anda menangani batas antara teks, dan bukan pusat.
Yang harus Anda lakukan adalah mengatasi pusat setiap texel. Dalam contoh ini, ini adalah koordinat yang ingin Anda gunakan:
Dalam hal ini, Anda akan selalu mengambil sampel pusat dari setiap texel dan Anda tidak akan mendapatkan pendarahan ... Kecuali jika Anda menggunakan pemetaan, dalam hal ini Anda akan selalu mendapatkan pendarahan mulai dari tingkat mip di mana subtexture yang diskalakan tidak rapi. muat di dalam kotak pixel .
Untuk menggeneralisasi, jika Anda ingin mengakses texel tertentu, koordinat dihitung sebagai:
Ini disebut "koreksi setengah piksel". Ada penjelasan lebih rinci di sini jika Anda tertarik.
sumber
Salah satu opsi yang akan jauh lebih mudah daripada mengutak-atik mipmaps dan menambahkan faktor fuzz koordinat tekstur adalah dengan menggunakan array tekstur. Array tekstur mirip dengan tekstur 3d, tetapi tanpa pemetaan di dimensi ke-3, sehingga ideal untuk atlas tekstur di mana "subteksur" memiliki ukuran yang sama.
http://www.opengl.org/wiki/Array_Texture
sumber
Setelah banyak berjuang dengan masalah ini, saya akhirnya menemukan solusi.
Untuk menggunakan keduanya, atlas tekstur dan pemetaan, saya perlu melakukan downsampling sendiri, karena OpenGL jika tidak akan interpolasi atas batas-batas ubin di atlas. Selain itu saya perlu mengatur parameter tekstur yang tepat, karena interpolasi antara mipmaps juga akan menyebabkan pendarahan tekstur.
Dengan parameter ini, tidak ada perdarahan yang terjadi.
Ada satu hal yang harus Anda perhatikan ketika memberikan mipmaps khusus. Karena tidak masuk akal untuk mengecilkan atlas bahkan jika setiap ubin sudah ada
1x1
, level mipmap maksimal harus diatur sesuai dengan apa yang Anda berikan.Terima kasih atas semua jawaban lain dan komentar yang sangat membantu! Ngomong-ngomong, saya masih belum tahu cara menggunakan penskalaan linear, tapi saya kira tidak ada cara.
sumber
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_FILTER, GL_NEAREST_MIPMAP_LINEAR);
GL_TEXTURE_MAX_FILTER
untukGL_NEAREST_MIPMAP_LINEAR
menyebabkan pendarahan bukan karena alasan pemetaan, tetapi untuk alasan interpolasi. Jadi dalam kasus ini sama denganGL_LINEAR
karena level mipmap terendah digunakan pula.glTexImage2D()
. GPU secara otomatis memilih level yang benar berdasarkan ukuran objek di layar.Sepertinya masalah ini bisa disebabkan oleh MSAA. Lihat jawaban ini dan artikel yang ditautkan :
Solusinya adalah menggunakan sampling centroid. Jika Anda menghitung pembungkus koordinat tekstur dalam vertex shader, memindahkan logika itu ke shader fragmen juga bisa memperbaiki masalah.
sumber
Ini adalah topik lama, dan saya memiliki masalah yang sama dengan topik tersebut.
Saya memiliki koordinat tekstur saya dengan baik, tetapi dengan menempatkan posisi kamera (yang mengubah posisi elemen saya) seperti:
Seluruh masalah adalah Util.lerp () mengembalikan float atau double. Ini buruk karena kamera menerjemahkan off-grid dan menyebabkan beberapa masalah aneh dengan potongan tekstur di mana> 0 di X dan> 0 di Y.
TLDR: jangan tween atau apapun menggunakan floats
sumber