Pada dasarnya, tujuan inti dalam rendering adalah untuk setiap frame yang ditampilkan pada monitor untuk menghadirkan gambar tunggal yang koheren. Ada beberapa strategi berbeda yang, atau dulu, digunakan untuk mencapai ini.
Berikut ini, saya menyebutkan "vsync". Vsync adalah saat di mana monitor mulai menggambar gambar layar baru; itu adalah titik di mana "vblank" dimulai pada layar CRT tradisional, di mana garis pemindaian berhenti menggambar dan bergerak kembali ke bagian atas monitor. Momen ini sangat penting bagi banyak pendekatan untuk membingkai koherensi.
"Merobek" adalah apa yang kita sebut ketika layar merender dari dua gambar yang berbeda, dalam satu bingkai. Jika, misalnya, saya telah menggambar dua gambar layar yang dimaksudkan untuk ditampilkan satu demi satu, tetapi monitor malah menampilkan bagian atas bingkai satu, dan bagian bawah bingkai dua, itu "merobek". Ini terjadi karena mengubah data yang dibaca monitor saat monitor menggambar, alih-alih selama vblank. (Dalam program modern, ini biasanya terjadi karena pengguna dinonaktifkan menunggu vsync dalam pengaturan driver mereka)
Zero-Buffer
Pada perangkat keras tertua, sering kali tidak ada cukup memori untuk menyimpan gambar layar penuh, dan alih-alih menggambar gambar layar, Anda perlu menentukan warna untuk setiap garis pemindaian secara individual, sementara monitor sedang dalam proses menggambar garis itu. Pada Atari 2600, misalnya, Anda hanya memiliki 76 siklus instruksi mesin untuk menentukan warna apa yang masuk ke setiap piksel garis pemindaian, sebelum televisi mulai benar-benar menggambar garis pemindaian itu. Dan kemudian Anda memiliki 76 siklus instruksi untuk menyediakan konten untuk pemindaian berikutnya , dan seterusnya.
Penyangga Tunggal
Saat menggambar dalam konteks "buffer tunggal", Anda menggambar langsung ke VRAM yang sedang dibaca dari monitor. Dalam pendekatan ini, Anda "berlomba memindai". Gagasan umum adalah bahwa ketika garis pemindaian mulai menggambar konten bingkai sebelumnya di bagian atas layar, Anda menggambar VRAM di belakangnya . Jadi saat scanline sedang menggambar gambar layar untuk frame terakhir, Anda menggambar frame berikutnya di belakang scanline.
Secara umum, Anda mencoba untuk menyelesaikan menggambar gambar frame-berikutnya sebelum scanline "lap" Anda dengan datang lagi dan menyalip piksel yang Anda gambar, dan juga untuk tidak pernah maju dari scanline, atau yang baru Anda bingkai mungkin menggambarkan apa yang seharusnya menjadi bingkai sebelumnya.
Karena alasan ini, rendering buffer tunggal biasanya bekerja sendiri dengan menggambar scanlines, dari atas ke bawah, dan dari kiri ke kanan. Jika Anda menggambar dengan urutan lain, ada kemungkinan bahwa garis pemindaian akan muncul lagi dan melihat bit dari gambar "selanjutnya" yang belum sempat Anda gambar.
Perhatikan bahwa dalam sistem operasi modern, Anda biasanya tidak pernah memiliki kesempatan untuk menggambar buffer tunggal, meskipun ini cukup umum tiga puluh tahun yang lalu. (Astaga, saya merasa tua sekarang - ini adalah apa yang saya lakukan ketika saya mulai dalam pengembangan game)
Penyangga Ganda
Ini jauh, jauh lebih sederhana daripada salah satu strategi yang datang sebelumnya.
Dalam sistem buffer ganda, kami memiliki cukup memori untuk menyimpan dua gambar layar yang berbeda, dan kami menunjuk salah satu dari mereka sebagai "buffer depan" dan yang lainnya, "buffer belakang". "Penyangga depan" adalah yang sedang ditampilkan, dan "penyangga belakang" adalah tempat kami saat ini menggambar.
Setelah kami selesai menggambar gambar layar ke buffer belakang, kami menunggu sampai vsync, dan kemudian menukar kedua buffer. Dengan cara ini, buffer belakang menjadi buffer depan, dan sebaliknya, dan seluruh swap terjadi saat monitor tidak menggambar apa pun.
Penyangga Tiga Kali Lipat
Satu masalah yang sering diangkat dengan pendekatan buffer ganda adalah bahwa setelah kita selesai menggambar ke buffer belakang, kita harus duduk diam menunggu vsync sebelum kita dapat menukar buffer dan terus bekerja; kita bisa melakukan perhitungan selama waktu itu! Terlebih lagi, setiap saat kami menunggu untuk bertukar di antara buffer, gambar di buffer belakang semakin lama dan semakin tua, sehingga meningkatkan latensi yang dirasakan pengguna.
Dalam sistem triple-buffer, kami membuat sendiri tiga buffer - satu buffer depan dan dua buffer belakang. Idenya adalah ini:
Monitor menampilkan buffer depan, dan kami sedang menggambar buffer belakang # 1. Jika kita selesai menggambar ke buffer belakang # 1 sebelum monitor selesai menggambar buffer depan, maka alih-alih menunggu vsync, kita malah segera mulai menggambar frame berikutnya ke buffer belakang # 2. Jika kita selesai dan vsync masih belum datang, kita mulai menggambar kembali ke buffer belakang # 1, dan seterusnya. Idenya adalah bahwa ketika vsync akhirnya terjadi, satu atau yang lain dari buffer belakang kita akan lengkap, dan yang satu dapat ditukar dengan buffer depan.
Manfaat dari triple-buffering adalah kita tidak kehilangan waktu yang kita habiskan untuk menunggu vsync dalam pendekatan double-buffering, dan gambar yang ditukar ke buffer depan mungkin "lebih segar" daripada yang telah menunggu vsync untuk 8ms. Kelemahan dari triple-buffering adalah kita membutuhkan memori ekstra untuk menyimpan gambar layar tambahan, dan penggunaan CPU / GPU kita akan lebih tinggi (sekali lagi, karena kita tidak memperlambat untuk menunggu vsync).
Biasanya, driver modern akan sering melakukan triple-buffering secara transparan, di belakang layar. Anda menulis kode Anda untuk melakukan buffering ganda, dan driver sebenarnya akan mengembalikan kontrol kepada Anda lebih awal, dan hanya secara internal menangani pertukaran antara berapa banyak buffer belakang yang ingin digunakan, tanpa kode Anda pernah menyadarinya.
Vendor GPU saat ini merekomendasikan Anda untuk tidak menerapkan triple-buffering sendiri - driver akan melakukannya untuk Anda secara otomatis.