Di luar batas dalam game AAA

21

Dalam banyak gelar AAA umum (khususnya Sumber mesin game), ketika pemain mencapai area 'un-catered' untuk, seperti di luar batas, atau noclipping di bawah peta; efek aneh terjadi di layar (buffer tearing?).

Ini dapat digambarkan sebagai mirip dengan jejak windows bahwa Windows XP dapat meninggalkan jendela diseret sementara ada sistem hang.

Saya hanya dapat mendalilkan bahwa pengembang tidak menghapus buffer warna saat menyegarkan layar?

Apakah itu benar? Jika demikian, mengapa?

kaviar melambat
sumber
8
BTW, ini sering disebut efek "Hall of Mirrors" atau HOM.
Nathan Reed

Jawaban:

35

Sekali waktu, membersihkan buffer warna dan kedalaman sebenarnya membutuhkan waktu. Melakukan yang jelas berarti bahwa kartu grafis harus berjalan setiap pixel dari framebuffer dan menulis nilai untuk itu.

Karena itu, pengembang game menemukan bahwa akan lebih efisien untuk hanya berasumsi bahwa setiap piksel akan dirender kembali. Mereka mengembangkan banyak teknik untuk melakukan ini.

Buffer warna adalah yang paling mudah untuk diabaikan. Yang tidak mudah adalah kedalaman buffer, karena akan tercemar dengan data lama. Jadi apa yang mereka lakukan itu sederhana.

Pada frame 0, mereka akan dirender dengan glDepthRange(atau setara D3D) dari (0, 0,5), dan mereka akan menggunakan a glDepthFuncdari GL_LESS(atau GL_LEQUAL). Ini berarti bahwa nilai kedalaman terjauh yang pernah Anda dapatkan di buffer kedalaman adalah 0,5. Jadi nilai terbesar dalam buffer kedalaman pada akhir frame 0 adalah 0,5 (dengan asumsi Anda menulis ke setiap piksel).

Pada frame 1, mereka akan mengubah rentang kedalaman ke (1, 0,5). Perhatikan bahwa dalam kasus ini, nilai kedalaman dekat lebih besar dari kedalaman jauh. Tetapi mereka juga akan mengubah fungsi kedalaman ke GL_GREATER(atau GL_GEQUAL), yang membalikkan makna tes kedalaman. Karena nilai terbesar di buffer kedalaman adalah 0,5, semua yang Anda tulis akan memiliki nilai lebih besar dari ini. Karena tes kedalaman dibalik, ini secara efektif berarti bahwa apa pun yang ditulis pada frame 0 sekarang lebih jauh dari apa pun yang dapat ditulis pada frame 1. Pada akhir frame 1, nilai terkecil dalam buffer kedalaman sekarang 0,5.

Dan kemudian mereka mengulanginya.

Pada perangkat keras apa pun yang dibuat sejak sekitar tahun 2003, ini bukan lagi sebuah optimasi. Memang, ini adalah optimasi negatif . Membersihkan buffer kedalaman sebenarnya membuat perangkat keras lebih cepat . Tidak benar-benar.

Pada dasarnya, yang terjadi adalah membersihkan buffer tidak benar-benar menulis apa pun. Mereka menyimpan beberapa bit dalam cache GPU yang membuat sistem tahu warna / kedalaman apa yang telah dibersihkan. Ketika sistem mencoba menulis ke baris cache framebuffer, ia tidak perlu membaca apa yang ada di sana, karena ia sudah tahu bahwa itu adalah bidang kosong dengan nilai warna / kedalaman yang jelas. Jika Anda mencoba menyatu dengan apa yang ada atau melakukan tes mendalam, sekali lagi, tidak perlu membaca: ia tahu nilai apa yang harus disatukan / diuji dengan / terhadap.

Jadi setiap membaca / memodifikasi / menulis yang Anda lakukan pada setiap baris cache setelah yang jelas pada dasarnya adalah menulis Ini gratis .

Plus, memiliki buffer kedalaman bergerigi dapat bekerja melawan Hyper-Z / Hierarchial-Z / optimisasi culling Z dalam perangkat keras. Ya, adegan Anda akan bekerja pada akhirnya saat Anda menambahkan detail. Tetapi jika buffer kedalaman Anda bergerigi dari rendering sebelumnya, bahkan jika objek latar belakang berada di latar belakang, itu dapat mempengaruhi efisiensi teknik Z-culling. Dan itu tidak akan membantu kinerja.

Jadi Anda seharusnya tidak pernah melakukan teknik pembalikan kedalaman ini dalam game modern.

Catatan: Jari membuat poin bagus pada arsitektur rendering berbasis ubin (seperti yang ditemukan di sebagian besar platform seluler). Tidak membersihkan kedalaman bisa membuat hal-hal yang tidak menyenangkan juga ada.

Nicol Bolas
sumber
Apakah pernyataan terakhir Anda menyiratkan untuk tidak pernah melakukan buffer kedalaman bergantian atau? Jawaban yang bagus
decaviatedcaviar
1
@ Daniel Ya. Saya mengklarifikasi posting saya.
Nicol Bolas
3
Selain itu, lompatan yang jelas pada arsitektur binning (seperti kebanyakan chip OpenGL ES) menyebabkan kehilangan kinerja yang sangat besar , karena chip grafis tidak dapat membuat asumsi pada keadaan buffer warna.
Jari Komppa
5

Ya, Anda benar bahwa buffer belakang tidak dihapus.

Mengapa karena (kebanyakan) lebih cepat menggunakan custom shader yang melakukan ping-pong nilai kedalaman dalam arah yang berlawanan pada setiap frame dan bergantung pada kenyataan bahwa game Anda selalu menampilkan setiap piksel pada layar.

Jadi untuk biaya nol Anda menghemat satu buffer clear per frame.

Patrick Hughes
sumber
1
Saya tidak tahu tentang kedalaman ping-ponging; setiap mesin yang saya kenal dengan membersihkan penyangga kedalaman / stensil setiap frame. Tapi selain itu, ya, jika game membuat semua piksel (sebagaimana mestinya), Anda tidak perlu menghapus buffer warna.
Nathan Reed
Bisakah Anda memberi contoh untuk shader, jawaban yang baik sebaliknya.
deceleratedcaviar
1
Saya menyadari bahwa Anda bertanya tentang mesin baru, membaca komentar @ NathanReed adalah berapa banyak mesin PC-satunya yang bekerja sekarang. Sentuhan buffer Z adalah teknik yang lebih tua, saya akan melihat apakah saya dapat menemukan referensi. Mesin konsol sebagian besar akan menghapus semua buffer warna juga, bahkan satu piksel yang menunjukkan efek HOM bernama Nathan akan gagal judul dan memaksanya untuk pergi melalui pengiriman lagi.
Patrick Hughes