Di lingkungan "modern", ekstensi "NV Occlusion Query" menyediakan metode untuk mendapatkan jumlah fragmen yang lulus uji kedalaman. Namun, pada iPad / iPhone menggunakan OpenGL ES, ekstensi tidak tersedia.
Apa pendekatan yang paling berkinerja untuk menerapkan perilaku serupa di fragmen shader?
Beberapa ide saya:
Render objek sepenuhnya putih, kemudian hitung semua warna bersama-sama menggunakan shader dua-pass di mana pertama garis vertikal diberikan dan untuk setiap fragmen shader menghitung jumlah di seluruh baris. Kemudian, sebuah simpul tunggal diberikan yang fragmennya menjumlahkan semua jumlah parsial dari pass pertama. Sepertinya tidak terlalu efisien.
Jadikan objek sepenuhnya putih di atas latar belakang hitam. Turunkan sampel secara rekursif, menyalahgunakan interpolasi linier perangkat keras di antara tekstur hingga mencapai resolusi yang cukup kecil. Ini mengarah ke fragmen yang memiliki tingkat skala abu-abu tergantung pada jumlah piksel putih di mana di wilayah yang sesuai. Apakah ini cukup akurat?
Gunakan mipmaps dan cukup baca piksel pada level 1x1. Lagi-lagi pertanyaan tentang keakuratan dan apakah mungkin menggunakan tekstur non-kekuatan-dua.
Masalahnya dengan pendekatan ini adalah, bahwa pipa akan macet yang menghasilkan masalah kinerja utama. Karena itu, saya mencari cara yang lebih baik untuk mencapai tujuan saya.
Menggunakan ekstensi EXT_OCCLUSION_QUERY_BOOLEAN
Apple memperkenalkan EXT_OCCLUSION_QUERY_BOOLEAN di iOS 5.0 untuk iPad 2.
"4.1.6 Occlusion Queries Occlusion queries use query objects to track the number of fragments or samples that pass the depth test. An occlusion query can be started and finished by calling BeginQueryEXT and EndQueryEXT, respectively, with a target of ANY_SAMPLES_PASSED_EXT or ANY_SAMPLES_PASSED_CONSERVATIVE_EXT. When an occlusion query is started with the target ANY_SAMPLES_PASSED_EXT, the samples-boolean state maintained by the GL is set to FALSE. While that occlusion query is active, the samples-boolean state is set to TRUE if any fragment or sample passes the depth test. When the occlusion query finishes, the samples-boolean state of FALSE or TRUE is written to the corresponding query object as the query result value, and the query result for that object is marked as available. If the target of the query is ANY_SAMPLES_PASSED_CONSERVATIVE_EXT, an implementation may choose to use a less precise version of the test which can additionally set the samples-boolean state to TRUE in some other implementation dependent cases."
Kalimat pertama mengisyaratkan perilaku yang persis seperti yang saya cari: mendapatkan jumlah piksel yang lulus uji kedalaman secara asinkron tanpa kehilangan banyak kinerja. Namun, sisa dokumen hanya menjelaskan cara mendapatkan hasil boolean.
Apakah mungkin untuk mengeksploitasi ekstensi ini untuk mendapatkan jumlah piksel? Apakah perangkat keras mendukungnya sehingga mungkin ada API tersembunyi untuk mendapatkan akses ke jumlah piksel?
Ekstensi lain yang dapat dieksploitasi adalah fitur debugging seperti berapa kali shader fragmen dipanggil (PSInvocations di DirectX - tidak yakin apakah sesuatu simila tersedia di OpenGL ES). Namun, ini juga akan menghasilkan warung pipa.
sumber
Jawaban:
Tidak, dan tidak. Yah, saya kira jika Anda menggambar serangkaian segitiga berukuran satu piksel di ruang jendela, Anda bisa menghitung berapa banyak nilai boolean yang Anda dapatkan. Tetapi itu akan membutuhkan permintaan terpisah untuk masing-masing satu piksel. Mungkin bukan yang tercepat di dunia.
Jika ada "API tersembunyi", Anda tidak akan memiliki akses ke sana (karena disembunyikan), jadi itu tidak masalah. Selain itu, sifat ekstensi sudah menunjukkan bahwa tidak ada. Lagi pula, jika perangkat keras memiliki jumlah fragmen yang sebenarnya, mengapa tidak langsung mengeksposnya, seperti yang dilakukan desktop OpenGL? Jika perangkat keras mendukungnya, mereka bisa saja mengambil ARB_occlusion_query dan menggunakannya.
Tetapi mereka tidak melakukannya. Yang sangat menyarankan bahwa mereka tidak bisa.
sumber
Hasilnya dikembalikan dalam GLuint, (juga bisa GLint untuk panggilan yang berbeda) sayangnya, hasilnya selalu 0 atau 1, mungkin mereka akan mengubahnya untuk mendaftarkan frag di masa depan.
juga sepertinya tidak ada satu orang pun di seluruh internet telah memposting tentang ekstensi baru ini ... jadi di sini mereka diatur dengan benar ... yang tidak didokumentasikan di mana pun sejauh yang saya tahu ... Anda dapat membayangkan bagaimana mereka akan masuk dalam kode Anda dari kode sudo kecil ini di sini:
sumber
GLint
tidak berarti itu adalah bilangan bulat dari jumlah fragmen yang lewat. Spesifikasinya cukup jelas bahwaQUERY_RESULT_EXT
negara adalah nilai boolean; Anda hanya menanyakannya sebagai bilangan bulat. ItuGL_FALSE
jika gagal dan tidakGL_FALSE
jika berlalu.