Apa itu "Scanline Racing"

13

Saya telah mendengar banyak orang yang bekerja di VR berbicara tentang balap garis pemindaian dan itu seharusnya membantu meningkatkan latensi untuk gerakan-ke-foton. Namun, tidak jelas bagi saya bagaimana ini bisa dilakukan dengan OpenGL. Adakah yang bisa menjelaskan bagaimana cara kerja balap scanline, dan bagaimana hal itu dapat diterapkan pada GPU modern.

Mokosha
sumber

Jawaban:

14

Ketika GPU Anda menampilkan bingkai baru di layar, itu mentransfer gambar melalui kabel HDMI (atau apa pun) dalam proses yang disebut "scanout". Pixel dikirim dalam urutan linier, biasanya dari kiri ke kanan dan dari atas ke bawah. Proses ini diatur waktunya sehingga dibutuhkan sebagian besar durasi interval penyegaran untuk melakukan ini. Misalnya, pada 60Hz, satu frame adalah ~ 17 ms. Setiap pemindaian akan memakan waktu sekitar 15-16 ms, dengan 1-2 ms vblank di antaranya (nilai yang tepat bervariasi sesuai dengan mode tampilan dan video).

Secara tradisional, rendering adalah buffer ganda, yang berarti ada dua buffer yang tersimpan dalam memori GPU: satu yang saat ini sedang dipindai ("buffer depan"), dan yang sedang diterjemahkan ke ("buffer belakang"). Setiap frame, keduanya ditukar. GPU tidak pernah merender ke buffer yang sama yang sedang dipindai, yang mencegah artefak karena berpotensi melihat bagian-bagian dari frame yang tidak lengkap. Namun, efek samping dari ini adalah peningkatan latensi, karena setiap frame dapat duduk di dalam buffer selama beberapa ms sebelum mulai dipindai.

VR sangat sensitif terhadap latensi, jadi ini tidak diinginkan. Pendekatan alternatif adalah merender langsung ke buffer depan, tetapi mengatur waktu dengan sangat hati-hati sehingga Anda telah memberikan setiap baris gambar sesaat sebelum pemindaian tiba di sana. Itu disebut "scanline racing" atau "racing the beam" ("balok" yang mengingatkan kembali ke masa CRT dahulu kala). Ini lebih atau kurang mengharuskan Anda membuat gambar dalam urutan scanline, yaitu urutan yang sama bahwa piksel dipindai. Secara harfiah tidak harus di-render satu baris pada satu waktu — itu dapat di-render dalam strip-strip tipis beberapa piksel, tetapi itu harus dilakukan secara berurutan, karena Anda tidak dapat kembali dan mengedit piksel yang sudah telah dipindai.

Ada banyak kelemahan dari pendekatan ini; ia memiliki persyaratan kinerja yang sangat ketat, harus diatur dengan sangat hati-hati terhadap vsync, dan sangat mempersulit proses rendering. Tetapi pada prinsipnya itu dapat mencukur milidetik dari latensi Anda, yang mengapa orang-orang VR tertarik padanya.

Nathan Reed
sumber
1
Jadi pertanyaan saya adalah bagaimana kita melakukan ini pada GPU modern? Saya tidak berpikir ada cara untuk meminta scanout, dan menurut saya Anda tidak bisa benar-benar mengirimkan panggilan draw per-scanline. Bahkan jika Anda bisa - jaminan apa yang Anda miliki bahwa undian Anda akan sampai di sana sebelum scanout?
Mokosha
1
@Mokosha Benar, tidak ada cara untuk menanyakan pemindaian secara langsung AFAIK. Paling-paling, Anda dapat mengetahui kapan vsync berada (melalui beberapa sinyal OS) dan memperkirakan di mana pemindaian berdasarkan waktu yang relatif terhadap itu (mengetahui rincian mode video). Untuk rendering, Anda dapat bereksperimen untuk mencari tahu berapa lama waktu yang biasanya diperlukan antara glFlush dan ketika rendering selesai, dan membuat beberapa tebakan berdasarkan itu. Pada akhirnya, Anda harus membangun beberapa kelonggaran dalam waktu Anda jika terjadi kesalahan (mis. Tetap 2-3 ms di depan pemindaian), dan terima bahwa mungkin akan ada artefak sesekali.
Nathan Reed
Efek peningkatan latensi disebabkan oleh vsync, yang menyebabkan swap depan dan backbuffer disinkronkan dengan vblank monitor. Penyangga ganda sendiri tidak menyebabkan masalah ini dengan sendirinya dan berguna untuk meminimalkan berkedip karena sebuah piksel hanya dapat berubah satu kali di buffer depan.
Maurice Laveaux
Saya telah menemukan cara yang akurat untuk memprediksi raster tanpa permintaan garis pindai, lihat jawaban di bawah.
Mark Rejhon
0

Yang hebat adalah kita akhirnya bisa memprediksi akurasi raster tepat garis pemindaian tanpa akses ke kueri per-pemindaian:

https://www.youtube.com/watch?v=OZ7Loh830Ec

Saya telah datang dengan formula mikrodetik-akurat sebagai offset VSYNC, untuk memprediksi posisi garis air mata. Tearline selama VSYNC OFF selalu tepat raster, sehingga Anda dapat menjauhkan mereka dari visibilitas selama strip-level "rendering buffer depan simulasi" melalui pertukaran buffer VSYNC OFF yang berulang.

Perhatikan utas forum - ada beberapa kode sumber terbuka yang terus ditambahkan - https://forums.blurbusters.com/viewtopic.php?f=10&p=32002

Mark Rejhon
sumber
0

Jika itu menarik, Dreamcast memiliki mode rendering "racing the beam", di mana ia dapat mendedikasikan sebagian kecil dari memori untuk framebuffer pixel (misalnya 64 garis pemindaian) dan itu akan membuat baris 32 pada gilirannya, disinkronkan untuk pembaruan tampilan. Namun ini, hanya digunakan untuk menghemat memori. Saya ragu ada yang membuat "dimodifikasi" geometri untuk bagian terakhir dari tampilan.

Simon F
sumber