Saya sedang mengerjakan renderer depan-ke-belakang untuk mesin 2D menggunakan proyeksi ortografis. Saya ingin menggunakan buffer kedalaman untuk menghindari penarikan berlebih. Saya memiliki buffer kedalaman 16-bit, kamera pada Z = 100 melihat Z = 0, zNear adalah 1, dan zFar adalah 1000. Setiap sprite yang diberikan mengatur koordinat Z-nya ke nilai yang semakin jauh, yang memungkinkan uji kedalaman untuk melewatkan rendering apa pun yang ada di bawahnya.
Namun saya sadar cara posisi Z berakhir dengan nilai buffer Z adalah non-linear. Saya ingin memanfaatkan resolusi penuh buffer kedalaman 16-bit, yaitu memungkinkan 65536 nilai unik. Jadi untuk setiap sprite yang diberikan, saya ingin menambah posisi Z ke posisi berikutnya untuk berkorelasi dengan nilai buffer kedalaman unik berikutnya.
Dengan kata lain saya ingin mengubah indeks kenaikan (0, 1, 2, 3 ...) dari sprite yang ditarik ke posisi Z yang tepat untuk setiap sprite untuk memiliki nilai buffer kedalaman yang unik. Saya tidak yakin dengan matematika di balik ini. Apa perhitungan untuk melakukan ini?
Catatan Saya bekerja di WebGL (pada dasarnya OpenGL ES 2), dan saya perlu mendukung berbagai perangkat keras, jadi sementara ekstensi seperti gl_FragDepth mungkin membuat ini lebih mudah, saya tidak dapat menggunakannya untuk alasan kompatibilitas.
sumber
Jawaban:
Memang, nilai-nilai yang disimpan dalam buffer-z tidak linier dengan koordinat z sebenarnya dari objek Anda, tetapi pada kebalikannya, untuk memberikan lebih banyak resolusi pada apa yang dekat mata daripada pada apa yang lebih dekat dengan bidang belakang.
Yang Anda lakukan adalah memetakan
zNear
ke0
danzFar
ke1
. UntukzNear=1
danzFar=2
, seharusnya terlihat seperti iniCara menghitung ini ditentukan oleh:
Dimana
... dan z_buffer_value adalah bilangan bulat.
Persamaan di atas diberikan kepada Anda berdasarkan halaman yang luar biasa ini , yang menjelaskan z-buffer dengan cara yang sangat baik.
Jadi, untuk menemukan yang diperlukan
z
untuk diberikanz_buffer_value
, kami hanya menghapusz
:sumber
z_buffer_value = k * (a + (b / z))
dan mengatur ulang untuk menyelesaikannyaz
, maka saya mendapatkan:z = b / ((z_buffer_value / k) - a)
- bagaimana Anda sampai pada formula terakhir yang berbeda?(v / k) - a => (v - k * a) / k
, dan runtuh ke(k * b) / (v - (k * a))
. Itu hasil yang sama.Mungkin Anda harus mengubah pendekatan Anda ke sesuatu yang lebih sederhana. Apa yang akan saya lakukan; Jaga hal kedalaman Z Anda, tetapi simpan daftar apa yang Anda render. Pesanlah daftar itu berdasarkan pada nilai Kedalaman z, dan render objek dalam urutan daftar.
Semoga ini bisa membantu. Orang-orang selalu mengatakan kepada saya untuk menjaga hal-hal sederhana.
sumber
Karena Anda sudah memiliki daftar hal-hal yang harus diurutkan (depan ke belakang) apakah Anda benar-benar perlu meningkatkan indeks Z? Tidak bisakah Anda menggunakan "kurang atau sama" untuk "fungsi memeriksa"? Dengan cara ini ia akan benar-benar memeriksa apakah piksel tertentu sudah ditarik atau tidak.
sumber