Sekali waktu, ketika> lebih cepat dari <... Tunggu, apa?

280

Saya membaca tutorial OpenGL yang luar biasa . Ini sangat bagus, percayalah. Topik saya saat ini adalah Z-buffer. Selain menjelaskan tentang apa semua ini, penulis menyebutkan bahwa kami dapat melakukan pengujian kedalaman khusus, seperti GL_LESS, GL_ALWAYS, dll. Ia juga menjelaskan bahwa makna sebenarnya dari nilai kedalaman (yang atas dan yang tidak) juga dapat menjadi disesuaikan. Saya mengerti sejauh ini. Dan kemudian penulis mengatakan sesuatu yang luar biasa:

Rentang zNear bisa lebih besar dari rentang zFar; jika ya, maka nilai ruang jendela akan dibalik, dalam hal apa yang merupakan terdekat atau terjauh dari pemirsa.

Sebelumnya, dikatakan bahwa nilai Z ruang-jendela 0 adalah yang terdekat dan 1 adalah yang terjauh. Namun, jika nilai Z ruang klip kami dinegasikan, kedalaman 1 akan paling dekat dengan tampilan dan kedalaman 0 akan menjadi yang terjauh. Namun, jika kita membalikkan arah uji kedalaman (GL_LESS ke GL_GREATER, dll), kita mendapatkan hasil yang sama persis. Jadi itu benar-benar hanya sebuah konvensi. Memang, membalik tanda Z dan uji kedalaman pernah menjadi optimasi kinerja yang vital untuk banyak game.

Jika saya mengerti benar, kinerja-bijaksana, membalik tanda Z dan tes kedalaman tidak lain hanyalah mengubah <perbandingan ke >perbandingan. Jadi, jika saya mengerti benar dan penulis tidak berbohong atau membuat sesuatu, kemudian mengubah <untuk >digunakan menjadi optimasi penting untuk banyak permainan.

Apakah penulis membuat segalanya, aku salah paham sesuatu, atau itu memang terjadi bahwa setelah <lebih lambat ( vital , sebagai penulis mengatakan) dari >?

Terima kasih telah menjelaskan masalah yang cukup aneh ini!

Penafian: Saya sepenuhnya menyadari bahwa kompleksitas algoritma adalah sumber utama untuk optimasi. Selain itu, saya menduga bahwa saat ini pasti tidak akan membuat perbedaan dan saya tidak meminta ini untuk mengoptimalkan apa pun. Saya hanya sangat, sangat menyakitkan, mungkin sangat ingin tahu.

Armen Tsirunyan
sumber
6
Tautan ke tutorial ini tampaknya (baru-baru ini) hilang. :(
TZHX
@TZHX: Karena jawaban yang diterima ditulis oleh penulis tutorial, kami berharap dapat menemukannya lagi. Lihat komentar terakhir saya untuk jawabannya :)
Armen Tsirunyan
3
Tutorial OpenGL yang dirujuk tersedia di sini .
Fons
(a <b) identik dengan (b> a) sehingga sama sekali tidak perlu untuk mengimplementasikan kedua operasi perbandingan dalam perangkat keras. Perbedaan dalam kinerja adalah hasil dari apa yang terjadi sebagai hasil dari operasi perbandingan. Ini adalah jalan panjang dan berliku untuk menjelaskan semua efek samping tetapi di sini ada beberapa petunjuk. Game yang digunakan untuk mengisi buffer kedalaman untuk menghindari pemrosesan fragmen yang lebih mahal untuk fragmen yang gagal tes kedalaman. Gempa digunakan untuk membagi rentang kedalaman menjadi dua bagian untuk menghindari membersihkan frame buffer karena permainan selalu mengisi setiap piksel di layar dan sebagainya.
t0rakka
2
@Fons terlihat seperti tautan mati, lagi :(
nalzok

Jawaban:

350

Jika saya mengerti dengan benar, kinerja-bijaksana, membalik tanda Z dan tes kedalaman tidak lain hanyalah mengubah perbandingan <perbandingan dengan>. Jadi, jika saya mengerti dengan benar dan penulis tidak berbohong atau mengada-ada, maka mengubah <menjadi> optimasi penting untuk banyak game.

Saya tidak menjelaskannya dengan sangat baik, karena itu tidak penting. Saya hanya merasa itu sedikit menarik untuk ditambahkan. Saya tidak bermaksud membahas algoritme secara khusus.

Namun, konteks adalah kuncinya. Saya tidak pernah mengatakan bahwa perbandingan <lebih cepat dari perbandingan>. Ingat: kita sedang berbicara tentang pengujian kedalaman perangkat keras grafis, bukan CPU Anda. Tidakoperator< .

Yang saya maksudkan adalah optimasi lama tertentu di mana satu frame yang akan Anda gunakan GL_LESSdengan kisaran [0, 0,5]. Bingkai berikutnya, Anda render denganGL_GREATER kisaran [1,0, 0,5]. Anda bolak-balik, secara harfiah "membalik tanda Z dan tes kedalaman" setiap frame.

Ini kehilangan sedikit presisi kedalaman, tetapi Anda tidak perlu menghapus buffer kedalaman, yang pada suatu waktu merupakan operasi yang agak lambat. Karena pembersihan mendalam tidak hanya gratis hari ini tetapi sebenarnya lebih cepat dari teknik ini, orang tidak melakukannya lagi.

Nicol Bolas
sumber
1
Alasan membersihkan buffer kedalaman lebih cepat hari ini memiliki dua alasan, keduanya berdasarkan fakta bahwa GPU menggunakan buffer kedalaman hierarkis. Oleh karena itu hanya perlu menghapus set negara ubin untuk menghapus (yang cepat), mengubah tanda perbandingan kedalaman, bagaimanapun, berarti seluruh buffer HiZ perlu memerah karena hanya menyimpan nilai min atau maks tergantung pada tanda perbandingan.
Jasper Bekkers
3
@NicolBolas: Komentar PerTZHX, tautan ke tutorial Anda di pertanyaan saya sudah mati. Bisakah Anda memberi tahu kami semua tempat tutorial bergerak dan mengedit pertanyaan, opsional?
Armen Tsirunyan
2
Tutorial tersedia di arsip web. Jika @NicolBolas mengizinkan, akan sangat membantu bagi komunitas jika kita dapat memindahkannya ke lokasi yang lebih mudah diakses. Mungkin GitHub atau sesuatu. web.archive.org/web/20150215073105/http://arcsynthesis.org/…
ApoorvaJ
3

Jawabannya hampir pasti bahwa untuk inkarnasi driver chip + apa pun yang digunakan, Hierarchical Z hanya bekerja dalam satu arah - ini adalah masalah yang cukup umum pada masa itu. Perakitan / percabangan tingkat rendah tidak ada hubungannya dengan itu - buffering Z dilakukan dalam perangkat keras fungsi tetap, dan disalurkan melalui pipa - tidak ada spekulasi dan karenanya, tidak ada prediksi cabang.

Crowley9
sumber
0

Optimalisasi seperti itu akan merusak kinerja pada banyak solusi grafis yang disematkan karena itu akan membuat penyelesaian framebuffer kurang efisien. Mengosongkan buffer adalah sinyal yang jelas ke pengemudi bahwa ia tidak perlu menyimpan dan mengembalikan buffer saat binning.

Informasi latar belakang kecil: rasterizer ubin / binning memproses layar dalam jumlah ubin sangat kecil yang masuk ke dalam memori on-chip. Ini mengurangi menulis dan membaca ke memori eksternal yang mengurangi lalu lintas di bus memori. Ketika sebuah frame selesai (swap disebut, atau FIFOs memerah karena mereka penuh, binding framebuffer berubah, dll.) Framebuffer harus diselesaikan; ini berarti setiap nampan diproses secara bergantian.

Pengemudi harus mengasumsikan bahwa konten sebelumnya harus dipertahankan. Pelestarian berarti bahwa nampan harus dituliskan ke memori eksternal dan kemudian dikembalikan dari memori eksternal ketika nampan diproses lagi. Operasi yang jelas memberi tahu pengemudi bahwa isi nampan didefinisikan dengan baik: warna yang jelas. Ini adalah situasi yang sepele untuk dioptimalkan. Ada juga ekstensi untuk "membuang" konten buffer.

t0rakka
sumber
-8

Ini ada hubungannya dengan bit bendera dalam perakitan yang sangat dicari.

x86 memiliki instruksi jl dan jg, tetapi sebagian besar prosesor RISC hanya memiliki jl dan jz (tanpa jg).

Joshua
sumber
2
Jika itu jawabannya, itu menimbulkan pertanyaan baru. Apakah "cabang diambil" lebih lambat dari "cabang diabaikan" pada prosesor RISC awal? Sejauh ini yang saya tahu tidak pasti seperti itu. Apakah Anda seharusnya menulis forloop dengan cabang tanpa syarat ke belakang dan cabang conditional, jarang dibawa ke depan untuk keluar dari loop itu? Kedengarannya aneh.
Pascal Cuoq
54
-1: Pertanyaan ini tidak ada hubungannya dengan CPU . GL_LESS dan GL_GREATER adalah operasi perbandingan mendalam, yang berjalan pada GPU.
Nicol Bolas
8
Lucu berapa banyak perwakilan yang bisa Anda dapatkan untuk jawaban yang benar untuk judul tetapi tidak ada hubungannya dengan pertanyaan yang sebenarnya.
Joshua
7
+1 Tidak, jawaban ini benar untuk setidaknya sebagian dari pertanyaan. Pertanyaannya adalah: "Apakah pengarangnya mengada-ada, apakah saya salah paham akan sesuatu, atau memang memang demikian bahwa dulunya <lebih lambat (seperti kata penulis)>?". Ada tiga opsi yang diberikan. Jawaban ini menanggapi kemungkinan opsi 3. Tidak ada dalam artikel ini adalah teknologi CPU / GPU yang diberikan, juga tidak harus berupa GPU (game 3D pertama yang menggunakan CPU). Ok ... Saya rasa tidak ada banyak Game 3d di RISC :-)
xanatos
3
(dan tag GPU ditambahkan pada 20:34. Revisi pertama hanya memiliki tag CPU. Respons ini ditulis pada 18:44)
xanatos