Batasan tanpa bingkai

9

Yang paling sukses mesin permainan kompetitif seperti id Tech, GoldSrc, Sourcedan seperti memungkinkan untuk keterbatasan framerate.

Anda dapat bermain dengan 30, dengan 60, dengan 99, dengan 72, dengan 68 dll. Singkatnya, Anda dapat menutupnya dan mengontrol tutupnya.

Saya bertanya-tanya, bagaimana saya membatasi framerate?

Bukan tertarik pada kode, tapi teori.

joltmode
sumber
Hanya karena penasaran, apa gunanya ini selain membebaskan siklus untuk proses lain?
3Dave
1
@DavidLively, Pikirkan laptop, mereka terlalu panas pada frame rate yang sangat tinggi, sementara dengan tutup 60fps (lebih banyak tidak berguna, bahkan 60 sedikit banyak, 40 harus dilakukan) mereka dapat mengontrol suhu jauh lebih baik.
Untuk game kompetitif, yang terbaik adalah memiliki frame rate yang rata daripada paku antara 60 dan 100 fps karena kadang-kadang beberapa tindakan tergantung pada frame rate dan bukan tergantung waktu, frame rate yang sama memungkinkan Anda merasakan tindakan-tindakan ini. Btw perhatikan bahwa jika Anda mengaktifkan VSync, gim Anda selalu memiliki maks fps yang sama dengan laju penyegaran Anda karena (pengemudi menangani ini).
Roy T.
gafferongames.com/game-physics/fix-your-timestep
Kontrak Prof. Falken dilanggar

Jawaban:

7

Teorinya adalah: Periksa kapan terakhir kali Anda membuat bingkai, dan jika belum waktunya untuk menggambar bingkai lain, maka jangan, dan tunggu sampai tiba.

Kylotan
sumber
8

Katakanlah Anda ingin membatasi framerate Anda menjadi 60fps, itu berarti bahwa setiap frame memiliki waktu render 1 / 60s = 16,67ms (bulat)

Untuk membatasi frame rate Anda, Anda cukup mengecek waktu di awal loop game Anda, kemudian Anda dapat membandingkannya dengan waktu di akhir loop game: jika selisihnya kurang dari 16,67 ms Anda harus mengulur waktu itu.

Salah satu cara untuk melakukan ini adalah dengan menggunakan:

sleep(waittime)

Namun karena sleep(x)menghasilkan utas untuk minimum xmilidetik Anda tidak tahu pasti apakah Anda akan mendapatkan kontrol kembali dalam waktu.

Cara yang lebih baik adalah menggunakan:

while(timediff < 16.67ms){ sleep(0); }

Ini menghasilkan utas dan meminta kontrol kembali sesegera mungkin.

Solusi lain adalah dengan hanya memiliki loop menunggu sibuk, ini memberi Anda kontrol terbaik tetapi menggunakan CPU tidak perlu.

Ingat bahwa penjadwal OS selalu dapat mengambil kendali dari utas Anda jadi bersiaplah untuk beberapa fluktuasi.

Roy T.
sumber
"1/60-an" harus jelas. :)
Richard Marskell - Drackir
Solusi ini sangat buruk. Jika Anda telah mengaktifkan vsync atau OS memutuskan untuk melakukan hal-hal, framerate Anda akan sangat berfluktuasi.
Tara
@Dudeson Mengapa ini buruk? (ini adalah teknik yang digunakan dalam Quake3 btw). Jika FPS Anda lebih rendah dari 60, loop hanya akan dilewati. Jadi itu membuat FPS Anda setinggi mungkin tetapi tidak pernah di atas 60.
Roy T.
@ Roy. Menarik ... Dari mana Anda mendapatkan info itu? Dari kode sumber? Juga, saya katakan menunggu dalam satu lingkaran itu buruk karena itulah tepatnya saya melakukannya di mesin saya dan itu menyebabkan saya sangat kesakitan. Masalahnya adalah, ketika Anda menghidupkan vsync (dalam driver GPU) Anda mendapatkan banyak penurunan bingkai jika Anda juga mencoba membatasi laju bingkai dalam kode Anda, karena timinig Anda tidak akan sempurna setiap frame. Saya hanya berbicara tentang masalah vsync. Tanpa vsync ini bukan masalah. Dan saya tidak yakin apakah vsync adalah jenis kesepakatan yang sama dalam Gempa 3 hari seperti sekarang ini.
Tara
@Dudeson orang lain mengatakan hal itu kepada saya beberapa waktu lalu karena saya khawatir tentang kesibukan menunggu dan tidur. Saya melihat sekarang bahwa Anda dapat berfluktuasi antara 30fps dan 60fps ketika v-sync aktif jika Anda sedikit melewatkannya. Tapi saya kira itu terjadi dengan teknik apa pun (bukankah ini yang coba diringankan FreeSync). Framerate terbatas oleh kode, atau karena komputer Anda tidak dapat membuat 60fps akan selalu memiliki masalah ini saya pikir :)
Roy T.