Ada sejarah panjang tentang bagaimana kami sampai di kebaktian bersama ini, dengan banyak tantangan yang menarik di sepanjang jalan, jadi saya akan mencoba memotivasinya secara bertahap:
1. Masalah: Perangkat berjalan dengan kecepatan berbeda
Pernah mencoba memainkan game DOS lama di PC modern, dan ini berjalan sangat cepat - hanya blur?
Banyak game lama memiliki loop pembaruan yang sangat naif - mereka mengumpulkan input, memperbarui status game, dan merender secepat yang dimungkinkan oleh hardware, tanpa memperhitungkan berapa lama waktu yang telah berlalu. Yang berarti begitu perangkat keras berubah, gameplay berubah.
Kami umumnya ingin para pemain kami memiliki pengalaman dan rasa permainan yang konsisten pada berbagai perangkat, (selama mereka memenuhi beberapa spesifikasi minimum) apakah mereka menggunakan ponsel tahun lalu atau model terbaru, desktop gaming top-end atau laptop tingkat menengah.
Khususnya, untuk permainan yang kompetitif (baik multipemain atau melalui papan peringkat) kami tidak ingin pemain yang berjalan di perangkat tertentu memiliki keunggulan dibandingkan yang lain karena mereka dapat berlari lebih cepat atau memiliki lebih banyak waktu untuk bereaksi.
Solusi jitu di sini adalah untuk mengunci tingkat di mana kami melakukan pembaruan keadaan gameplay. Dengan begitu kami bisa menjamin hasilnya akan selalu sama.
2. Jadi, mengapa tidak hanya mengunci framerate (mis. Menggunakan VSync) dan masih menjalankan pembaruan status gameplay & rendering di lockstep?
Ini bisa berhasil, tetapi tidak selalu cocok untuk audiens. Ada waktu yang lama ketika berlari dengan kecepatan 30 fps dianggap sebagai standar emas untuk gim. Sekarang, pemain secara rutin mengharapkan 60 fps sebagai bilah minimum, terutama di game aksi multipemain, dan beberapa judul yang lebih tua sekarang terlihat sangat berombak karena harapan kami telah berubah. Ada juga grup vokal pemain PC yang secara khusus menolak kunci framerate. Mereka membayar banyak untuk perangkat keras mereka yang berdarah, dan ingin dapat menggunakan otot komputasi itu untuk menghasilkan rendering, kesetiaan tertinggi, yang mampu dilakukannya.
Khususnya di VR, framerate adalah raja, dan standarnya terus merayap. Di awal kebangkitan VR baru-baru ini, game sering berlari sekitar 60 fps. Sekarang 90 lebih standar, dan harware seperti PSVR mulai mendukung 120. Ini mungkin terus meningkat. Jadi, jika sebuah game VR membatasi framerate-nya dengan apa yang bisa dilakukan & diterima hari ini, itu mungkin tertinggal karena hardware dan ekspektasi berkembang lebih jauh.
(Sebagai aturan, berhati-hatilah ketika diberi tahu "pemain tidak dapat melihat apa pun lebih cepat dari XXX" karena biasanya didasarkan pada jenis "persepsi" tertentu, seperti mengenali bingkai secara berurutan. Persepsi tentang kontinuitas gerak umumnya jauh lebih banyak. sensitif.)
Masalah terakhir di sini adalah bahwa permainan menggunakan framerate yang dikunci juga perlu konservatif - jika Anda pernah menemukan momen dalam permainan di mana Anda memperbarui & menampilkan jumlah objek yang luar biasa tinggi, Anda tidak ingin ketinggalan bingkai Anda tenggat waktu dan menyebabkan gagap atau halangan yang nyata. Jadi Anda perlu mengatur anggaran konten Anda cukup rendah untuk meninggalkan ruang kepala, atau berinvestasi dalam fitur penyesuaian kualitas dinamis yang lebih rumit untuk menghindari mengelompokkan seluruh pengalaman bermain dengan kinerja terburuk pada perangkat keras min-spec.
Ini bisa sangat bermasalah jika masalah kinerja muncul terlambat dalam pengembangan, ketika semua sistem Anda yang ada dibangun & disetel dengan asumsi framerate rendering berbaris yang sekarang Anda tidak selalu dapat menekan. Pembaruan decoupling & rendering rate memberi lebih banyak fleksibilitas untuk berurusan dengan variabilitas kinerja.
3. Tidak memperbarui pada catatan waktu yang tetap memiliki masalah yang sama seperti (2)?
Saya pikir ini adalah inti dari pertanyaan asli: jika kita memisahkan pembaruan kita dan kadang-kadang membuat dua frame tanpa pembaruan status permainan di antara keduanya, maka bukankah itu sama dengan rendering langkah-langkah di framerate yang lebih rendah, karena tidak ada perubahan yang terlihat pada layar?
Sebenarnya ada beberapa cara permainan menggunakan decoupling pembaruan ini untuk efek yang baik:
a) Tingkat pembaruan bisa lebih cepat daripada framerate yang diberikan
Sebagai catatan tyjkenn dalam jawaban lain, fisika khususnya sering kali melangkah pada frekuensi yang lebih tinggi daripada rendering, yang membantu meminimalkan kesalahan integrasi dan memberikan tabrakan yang lebih akurat. Jadi, daripada memiliki 0 atau 1 pembaruan antara frame yang diberikan Anda mungkin memiliki 5 atau 10 atau 50.
Sekarang rendering pemain pada 120 fps bisa mendapatkan 2 pembaruan per frame, sedangkan pemain pada rendering hardware spec yang lebih rendah pada 30 fps mendapat 8 pembaruan per frame, dan kedua game mereka berjalan pada kecepatan gameplay-ticks-per-realtime-second yang sama. Perangkat keras yang lebih baik membuatnya terlihat lebih halus, tetapi tidak secara radikal mengubah cara kerja gameplay.
Ada risiko di sini bahwa, jika laju pembaruan tidak cocok dengan framerate, Anda bisa mendapatkan "frekuensi ketukan" di antara keduanya . Misalnya. kebanyakan frame kita punya cukup waktu untuk 4 pembaruan keadaan permainan dan sedikit sisa, maka setiap kali kita cukup menyimpan hingga 5 pembaruan dalam satu frame, membuat sedikit lompatan atau gagap dalam gerakan. Ini dapat diatasi dengan ...
b) Menginterpolasi (atau mengekstrapolasi) status game di antara pembaruan
Di sini kita akan sering membiarkan status permainan menjalani satu stempel waktu tetap di masa mendatang, dan menyimpan informasi yang cukup dari 2 status terbaru yang dapat kita berikan titik arbitrer di antara mereka. Kemudian ketika kami siap untuk menampilkan bingkai baru di layar, kami berbaur dengan momen yang tepat hanya untuk tujuan tampilan (mis. Kami tidak mengubah keadaan gameplay yang mendasarinya di sini)
Ketika dilakukan dengan benar ini membuat gerakan terasa mentega halus, dan bahkan membantu untuk menutupi beberapa fluktuasi framerate, selama kita tidak jatuh terlalu rendah.
c) Menambahkan kehalusan pada perubahan non-gameplay-state
Bahkan tanpa interpolasi keadaan gameplay, kita masih bisa mendapatkan beberapa kemenangan mulus.
Perubahan visual murni seperti animasi karakter, sistem partikel atau VFX, dan elemen antarmuka pengguna seperti HUD, sering diperbarui secara terpisah dari catatan waktu tetap keadaan gameplay. Ini berarti jika kita mencentang status gameplay beberapa kali per frame, kami tidak membayar biaya dengan setiap centang - hanya pada render pass terakhir. Sebagai gantinya, kami menskalakan kecepatan pemutaran efek ini agar sesuai dengan panjang frame, sehingga mereka bermain semulus rendering framerate memungkinkan, tanpa memengaruhi kecepatan atau keadilan game seperti yang dibahas dalam (1).
Pergerakan kamera juga bisa melakukan ini - terutama di VR, kadang-kadang kami akan menunjukkan frame yang sama lebih dari satu kali, tetapi memproyeksikan ulang untuk memperhitungkan pergerakan kepala pemain di antaranya , sehingga kami dapat meningkatkan latensi dan kenyamanan yang dirasakan, bahkan jika kami bisa asli membuat semuanya secepat itu. Beberapa sistem streaming game (di mana game berjalan di server dan pemain hanya menjalankan thin client) menggunakan versi ini juga.
4. Mengapa tidak menggunakan gaya (c) itu untuk semuanya? Jika itu berfungsi untuk animasi dan UI, tidak bisakah kita cukup skala pembaruan keadaan gameplay kami agar sesuai dengan framerate saat ini?
Ya * ini mungkin, tapi tidak itu tidak sederhana.
Jawaban ini sudah agak lama jadi saya tidak akan membahas semua detail yang berdarah, hanya ringkasan singkat:
Mengalikan dengan deltaTime
karya untuk menyesuaikan dengan pembaruan panjang variabel untuk perubahan linier (mis. Gerakan dengan kecepatan konstan, hitungan mundur pengatur waktu, atau berkembang di sepanjang garis waktu animasi)
Sayangnya, banyak aspek permainan yang tidak linier . Bahkan sesuatu yang sesederhana gravitasi menuntut teknik integrasi yang lebih canggih atau resolusi yang lebih tinggi untuk menghindari hasil yang berbeda di bawah framerate yang berbeda-beda. Input dan kontrol pemain itu sendiri merupakan sumber besar non-linearitas.
Secara khusus, hasil deteksi dan resolusi tabrakan diskrit tergantung pada tingkat pembaruan, yang mengarah ke kesalahan tunneling dan jittering jika frame terlalu lama. Jadi framerate variabel memaksa kita untuk menggunakan metode pendeteksian tabrakan berkelanjutan yang lebih kompleks / mahal pada lebih banyak konten kita, atau mentolerir variabilitas dalam fisika kita. Bahkan deteksi tabrakan terus menerus menghadapi tantangan ketika benda bergerak dalam busur, membutuhkan waktu yang lebih singkat ...
Jadi, dalam kasus umum untuk permainan kompleksitas sedang, mempertahankan perilaku konsisten & keadilan sepenuhnya melalui deltaTime
penskalaan adalah di antara yang sangat sulit & pemeliharaan yang intensif hingga tidak mungkin.
Menstandarkan tingkat pembaruan memungkinkan kami menjamin perilaku yang lebih konsisten di berbagai kondisi , seringkali dengan kode yang lebih sederhana.
Menjaga agar laju pembaruan dipisahkan dari rendering memberi kami fleksibilitas untuk mengontrol kelancaran dan kinerja pengalaman tanpa mengubah logika gameplay .
Bahkan saat itu kita tidak pernah mendapatkan kemerdekaan framerate yang benar-benar "sempurna" tetapi seperti banyak pendekatan dalam game itu memberi kita metode yang terkendali untuk memanggil "cukup baik" untuk kebutuhan game tertentu. Itu sebabnya itu umumnya diajarkan sebagai titik awal yang bermanfaat.