Di sini Anda mengunduh prapesanan berbayar sebelumnya. Instalasi berakhir, Anda memulai permainan. Semuanya berjalan dengan baik: game ini terbang dengan kecepatan bingkai 60 FPS. Atau setidaknya itulah yang dikatakan oleh penghitung bingkai di overlay GPU Anda. Tapi ada yang tidak beres. Anda menggerakkan mouse ke depan dan belakang dan melihat bahwa game ... membeku.
Bagaimana ini mungkin? Apa lagi yang membeku pada 60 FPS?
Ini mungkin tampak konyol sampai Anda menemukannya sendiri. Jika Anda pernah bertemu dengan frieze seperti itu, maka Anda mungkin sudah berhasil membencinya.
Ini bukan lag. Bukan frekuensi gambar yang rendah. Ini stattering. Dengan FPS tinggi dan konfigurasi ultra-cepat yang ideal.
Apa itu, dari mana asalnya dan adakah cara untuk menyingkirkannya? Mari kita cari tahu sekarang.
Sejak diperkenalkannya mesin arcade pertama di tahun 70-an, video game telah berjalan pada 60 FPS. Biasanya diasumsikan bahwa permainan harus berjalan pada kecepatan yang sama dengan kecepatan tampilan. Hanya setelah mempopulerkan game 3D, kami harus menghadapi dan mengadopsi frekuensi gambar yang lebih rendah. Kembali ke tahun 90-an, ketika "kartu 3D" (sekarang disebut "GPU") mulai menggantikan rendering perangkat lunak, orang-orang bermain dengan 20 frame per detik, dan 35 FPS sudah dianggap sebagai frekuensi untuk persaingan jaringan yang serius.
Sekarang kami memiliki mobil super cepat yang tentunya dapat terbang dengan kecepatan 60 FPS. Namun ... sepertinya ada lebih banyak kinerja yang tidak memuaskan dari sebelumnya. Bagaimana ini mungkin?
Bukannya game tidak cukup cepat. Dan fakta bahwa mereka membekukan bahkan dengan kinerja tinggi.
Jika Anda menelusuri forum game, Anda mungkin akan melihat hal seperti ini di berita utama:
Pemain game PC sering mengeluh bahwa game mengalami stattering meskipun tidak ada masalah frame rate.
Dapat diasumsikan bahwa ini adalah kasus yang terisolasi, tetapi asumsi tersebut dihilangkan oleh statistik pencarian Google:
Selama 5 tahun terakhir, stattering telah menjadi (relatif) lebih menjadi masalah daripada kinerja.
(Perhatikan bahwa ini adalah nilai relatif. Bukan berarti orang mencari informasi tentang stattering lebih sering daripada tentang frekuensi gambar secara umum. Meskipun jumlah penelusuran untuk frekuensi gambar tetap sama, penelusuran untuk menyatakan menjadi lebih umum, terutama belakangan ini. )
Dasawarsa pencarian alasan stattering
Pasien pasti masih hidup. Dia hanya sering resah.
Penulis pertama kali mengalami masalah ini sekitar tahun 2003 saat mengerjakan Serious Sam 2. Orang-orang mulai melaporkan kasus di mana gerakan layar dan mouse tidak mulus selama pengujian pada level kosong. Ini disertai dengan pola yang sangat spesifik dalam grafik frekuensi gambar, yang oleh tim pengembangan disebut "detak jantung".
Pikiran pertama adalah bahwa di suatu tempat dalam kode ada bug yang masuk, tetapi tidak ada yang bisa menemukannya. Tampaknya masalah muncul dan menghilang secara acak - saat memulai ulang game, memulai ulang komputer ... tetapi ada baiknya mengubah parameter kinerja apa pun dan itu menghilang. Kemudian Anda dapat mengubah parameter kembali, dan semuanya terus bekerja dengan sempurna. Masalah hantu.
Jelas, Sam bukanlah satu-satunya masalah. Saat meluncurkan game lain, game itu muncul dengan cara yang sama, menunjukkan bahwa ada yang salah dengan drivernya. Tetapi stattering tidak bergantung pada pabrikan GPU Anda. Itu terjadi bahkan dengan API yang berbeda (OpenGL, DirectX 9, DirectX 11 ...). Satu-satunya kesamaan yang tersisa adalah stattering muncul di sana-sini pada beberapa mesin dan adegan permainan.
Dengan dirilisnya game-game baru, masalah ini terus bermunculan dan menghilang. Sebelumnya, ini hanya memengaruhi beberapa pengguna, dan semuanya terbatas pada permintaan dari dukungan teknis untuk mengubah beberapa parameter kinerja - yang terkadang membantu, dan terkadang tidak, Anda tidak pernah tahu.
Kemudian, tiba-tiba, pada suatu hari musim dingin yang indah di awal tahun 2013, orang-orang di Croteam menemukan contoh lain dari masalah ini yang dapat direproduksi secara relatif secara konsisten pada saat itu - kali ini di salah satu level di Serious Sam 3. Mereka mengotak-atik adegan itu untuk waktu yang lama, sampai tiba-tiba tersadar. Itu sangat sederhana - tidak heran itu luput dari perhatian publik selama satu dekade.
Dengan mengubah hanya satu opsi sederhana di mesin permainan, mereka dapat menyelesaikan masalah ini. Namun, segera menjadi jelas bahwa solusi tersebut sebenarnya membutuhkan lebih banyak waktu dan usaha. Dan tidak hanya dari tim tertentu, tetapi dari seluruh ekosistem game: pengembang driver GPU, spesialis pemeliharaan API, vendor OS - semuanya.
Apa yang terjadi selama ini
Beginilah tampilannya saat game melambat bahkan pada 60 FPS. Anda mungkin pernah mengalami hal serupa saat memainkan game modern apa pun, dan mungkin hal pertama yang Anda pikirkan adalah bahwa game tersebut tidak dioptimalkan. Baiklah, mari kita lihat kembali teori ini.
Jika permainan "terlalu lambat", itu berarti bahwa pada beberapa titik ia tidak akan dapat membuat satu frame cukup cepat dan monitor harus menampilkan frame sebelumnya lagi. Oleh karena itu, ketika kami merekam video pada 60 bingkai per detik, itu akan menunjukkan "bingkai jatuh" - ketika bingkai berikutnya tidak ditampilkan pada waktunya, itulah sebabnya bingkai yang sama ditampilkan dua kali.
Namun, ini hanya terjadi saat Anda memainkan seluruh animasi. Jika Anda melewatinya bingkai demi bingkai, Anda tidak akan menemukan celah apa pun.
Bagaimana ini mungkin?
Mari kita lihat lebih dekat. Di bawah ini adalah perbandingan berdampingan antara video mulus yang ideal dan video bertahap:
Enam bingkai berurutan dengan pengaturan waktu yang akurat. Di atas - bingkai diposisikan dengan benar, di bawah - bingkai dengan stattering.
Anda dapat melihat dua hal di sini: pertama, mereka benar-benar bekerja pada kecepatan yang sama: setiap kali bingkai baru muncul di atas (benar), kemudian bingkai baru muncul di bawah (stattering). Kedua, karena alasan tertentu mereka tampak bergerak sedikit berbeda - ada "celah" yang terlihat di tengah gambar yang berfluktuasi antara pembagian waktu yang lebih besar dan lebih kecil.
Orang yang paling perhatian mungkin memperhatikan detail aneh lainnya: gambar bawah seharusnya "lebih lambat" ... sebenarnya gambar "di depan" dari gambar yang benar. Aneh, bukan?
Jika kita melihat pada beberapa frame yang berurutan dan waktunya, kita dapat melihat hal lain yang menarik: dua frame pertama tersinkronisasi dengan sempurna, tetapi pada frame ketiga, pohon dalam video "lebih lambat" secara signifikan berada di depan pasangannya dalam "benar" video (dilingkari merah) ... Anda juga dapat melihat bahwa frame ini jelas membutuhkan waktu lebih lama (dilingkari kuning).
Tunggu, tunggu ... tetapi jika video "lebih lambat" dan frame "membutuhkan waktu lebih lama", bagaimana cara melanjutkan?
Untuk memahami penjelasan lebih lanjut, Anda harus terlebih dahulu memahami bagaimana game modern dan aplikasi 3D lainnya umumnya melakukan animasi dan rendering.
Sejarah singkat sinkronisasi bingkai
Dahulu kala, di galaksi yang sangat jauh ... ketika pengembang membuat video game pertama, mereka biasanya melakukannya berdasarkan frekuensi gambar yang tepat saat tampilan berjalan. Di wilayah NTSC, di mana TV beroperasi pada 60 Hz, ini berarti 60 bingkai per detik, dan di wilayah PAL / SECAM, di mana TV beroperasi pada 50 Hz, 50 bingkai per detik.
Sebagian besar game adalah konsep yang sangat sederhana yang berjalan pada perangkat keras tetap - biasanya konsol arcade atau "komputer mikro rumahan" yang terkenal seperti ZX Spectrum, C64, Atari ST, Amstrad CPC 464, Amiga, dll. Jadi, membuat dan Dengan pengujian game untuk mesin tertentu dan frekuensi gambar tertentu, pengembang selalu yakin 100% bahwa frekuensi gambar tidak akan pernah turun di mana pun.
Kecepatan objek juga disimpan di unit "personel". Jadi, Anda tidak perlu mengetahui berapa banyak piksel per detik karakter akan bergerak, tetapi berapa piksel dalam bingkai. Misalnya, dalam Sonic The Hedgehog untuk Sega Genesis, kecepatan ini adalah 16 piksel per bingkai. Banyak game bahkan memiliki versi terpisah untuk wilayah PAL dan NTSC, di mana animasi digambar tangan khusus untuk 50 dan 60 FPS, masing-masing. Faktanya, bekerja pada frekuensi gambar lain sama sekali tidak mungkin.
Dan karena game mulai berjalan di perangkat yang lebih bervariasi dari waktu ke waktu, termasuk PC dengan perangkat keras yang terus berkembang dan ditingkatkan, tidak mungkin untuk mengetahui secara pasti frekuensi gambar apa yang akan dijalankan game tersebut. Fakta ini diperparah oleh fakta bahwa gim itu sendiri menjadi lebih kompleks dan tidak dapat diprediksi - ini terutama terlihat dalam gim 3D, di mana bisa ada perbedaan besar dalam kompleksitas adegan, terkadang bahkan ditentukan oleh pemain itu sendiri. Misalnya, semua orang suka menembak tumpukan barel bahan bakar, menyebabkan serangkaian ledakan warna-warni ... dan penurunan frekuensi gambar yang tak terhindarkan. Tapi karena itu menyenangkan, tidak ada yang keberatan.
Oleh karena itu, sulit untuk memprediksi berapa lama waktu yang dibutuhkan untuk membuat model dan merender satu frame. (Harap dicatat bahwa pada konsol modern kami dapat mengasumsikan bahwa perangkat keras sudah diperbaiki, tetapi gim itu sendiri masih cukup tidak dapat diprediksi dan rumit.)
Jika Anda tidak dapat memastikan pada frekuensi gambar apa gim tersebut akan berfungsi, Anda perlu mengukur bingkai frekuensi saat ini dan terus-menerus menyesuaikan fisika game dan kecepatan animasinya. Jika satu bingkai membutuhkan waktu 1/60 detik (16,67 md) dan karakter Anda berjalan pada kecepatan 10 m / d, maka ia bergerak 1/6 meter di setiap bingkai. Tetapi jika bingkai tiba-tiba mulai mengambil 1/30 detik (33,33 ms), maka Anda harus memindahkan karakter sudah 1/3 meter per bingkai (dua kali "lebih cepat") sehingga dia terus bergerak pada saat yang sama. kecepatan.
Bagaimana cara mengaturnya? Biasanya, game mengukur waktu di awal bingkai yang berdekatan dan menghitung perbedaannya. Ini adalah metode yang cukup sederhana, tetapi bekerja dengan sangat baik.
Sebaliknya, itu bekerja dengan sangat baik sebelumnya. Kembali ke tahun 90-an, ketika 35 FPS dianggap sebagai kecepatan, orang-orang sangat senang dengan itu. Tetapi pada saat itu, kartu video bukanlah bagian penting dari PC, dan prosesor pusat memiliki kendali atas semua yang terjadi di layar. Jika Anda tidak memiliki akselerator 3D, alat ini bahkan menggambar objek dengan sendirinya. Karena itu, dia tahu persis kapan mereka akan menyentuh layar.
Situasi hari ini
Seiring waktu, GPU yang lebih dan lebih canggih mulai bermunculan, dan mereka pasti menjadi lebih dan lebih "asinkron". Ini berarti bahwa ketika CPU memberi tahu GPU untuk menggambar sesuatu ke layar, GPU hanya menyimpan perintah itu dalam buffer sehingga CPU dapat terus berjalan saat GPU sedang melakukan rendering. Pada akhirnya ini mengarah pada situasi di mana CPU memberi tahu GPU ketika akhir frame akan datang, dan GPU, saat menyimpan ini di antara datanya, tidak benar-benar menganggapnya sebagai sesuatu yang menjadi prioritas - bagaimanapun juga, itu masih memproses beberapa perintah yang dikeluarkan sebelumnya ... Ini akan menampilkan bingkai di layar hanya jika telah melakukan semua yang dimuat sebelumnya.
Jadi, saat game mencoba menghitung waktu dengan mengurangi cap waktu di awal dua frame berturut-turut, relevansinya, terus terang ... sangat dipertanyakan. Jadi mari kembali ke contoh kita. Di sana kami memiliki bingkai berikut:
Enam bingkai berurutan dengan waktu yang tepat. Baris atas benar, baris bawah memiliki efek stattering.
Dalam dua bingkai pertama, waktu bingkai adalah 16,67 milidetik (atau 1/60 detik) dan kamera bergerak dalam jumlah yang sama di kasing atas dan bawah, sehingga pepohonan selaras. Pada frame ketiga (di bawah, dengan stattering), permainan melihat bahwa frame time adalah 24,8 ms (yaitu, lebih dari 1/60 detik) dan oleh karena itu berpikir bahwa frame rate telah turun dan bergegas untuk mengejar ketinggalan hilang ... hanya untuk menemukan bahwa di frame berikutnya waktunya hanya 10,7 ms, yang membuat kamera melambat, dan sekarang pepohonan lebih kurang tersinkronisasi lagi.
Apa yang sedang terjadi? Waktu bingkai yang diukur oleh gim berfluktuasi karena berbagai faktor - terutama pada sistem multitasking yang sibuk seperti PC. Oleh karena itu, di beberapa titik waktu, game mengasumsikan bahwa frekuensi telah turun dari 60 FPS, dan menghasilkan bingkai animasi yang dirancang untuk frekuensi gambar yang lebih rendah. Tetapi karena sifat asinkron dari GPU, entah bagaimana itu selalu kembali ke 60 frame per detik yang sama.
Ini stattering - animasi yang dihasilkan untuk frekuensi gambar variabel (detak jantung) yang ditampilkan pada frekuensi gambar tetap yang benar.
Jadi, pada dasarnya, kita dapat berasumsi bahwa tidak ada masalah - semuanya berjalan lancar, game tidak mengetahuinya.
Ini membawa kita pada apa yang kita bicarakan di awal artikel. Ketika kita akhirnya menemukan penyebab masalahnya (meskipun kita tahu bahwa ini adalah ilusi dari sebuah masalah - benar-benar tidak ada masalah, bukan?), Kita dapat menerapkan pil ajaib berikut ini.
Apa pil ini? Di Serious Engine, ini dilambangkan sebagai sim_fSyncRate = 60. Secara sederhana, ini berarti: " abaikan sepenuhnya semua kejahatan ini dan anggaplah bahwa kami selalu mengukur stabil 60 frame per detik ." Dan itu membuat semuanya berjalan lancar - hanya karena semuanya berjalan lancar sejak awal! Satu-satunya alasan pernyataan muncul adalah karena waktu yang salah untuk animasi.
Dan apakah itu semua?
Jadi solusinya sesederhana itu?
Sayangnya tidak ada. Itu hanya tes saja. Jika kami berhenti mengukur laju bingkai dalam kondisi nyata dan hanya berasumsi bahwa itu selalu sama dengan 60 FPS, maka ketika turun di bawah 60 - dan pada PC, cepat atau lambat akan turun karena alasan apa pun: program yang berjalan di latar belakang, energi konservasi atau perlindungan overheating, siapa tahu - maka semuanya akan melambat.
Jadi, jika kita mengukur waktu frame, stattering terjadi, dan jika tidak, pada titik tertentu semuanya bisa melambat. Lalu apa?
Solusi sebenarnya adalah mengukur bukan waktu mulai / akhir rendering bingkai, tetapi waktu saat gambar ditampilkan di layar.
Tapi bagaimana game bisa tahu kapan sebuah bingkai benar-benar ditampilkan di layar?
Tidak mungkin: saat ini hal ini tidak mungkin.
Aneh tapi Nyata. Orang akan berharap ini menjadi fitur inti dari setiap API grafik. Tapi tidak: mereka telah mengalami perubahan di semua aspek lain selain ini. Tidak ada cara untuk mengetahui dengan pasti kapan frame tersebut benar-benar akan muncul di layar. Anda bisa mengetahui kapan rendering selesai. Tapi ini tidak sama dengan waktu tampilan.
Sekarang apa?
Yah, tidak seburuk itu. Banyak orang secara aktif bekerja untuk mengimplementasikan dukungan untuk sinkronisasi frame yang benar untuk API yang berbeda. Vulkan API sudah memiliki ekstensi bernama VK_GOOGLE_display_timing yang memiliki rekam jejak yang terbukti dalam menerapkan konsep ini, tetapi hanya tersedia untuk sejumlah perangkat terbatas.
Pekerjaan sedang dilakukan untuk memberikan solusi yang serupa dan lebih baik, saya ingin percaya bahwa sudah ada di semua API grafis utama. Kapan? Sulit untuk mengatakannya, karena masalahnya sangat memengaruhi berbagai subsistem OS.
Namun, kami berharap ini segera tersedia untuk masyarakat luas.
Berbagai peringatan dan detail lainnya
Kami akan menganggap bahwa ini adalah akhir dari teks utama. Bagian di bawah ini adalah "fitur bonus" yang sebagian besar tidak bergantung satu sama lain dan di atas.
"Komposer"
Apakah itu efek kaca buram? Ya, itulah mengapa kita harus memiliki seorang komposer. Cukup penting, bukan?
Sebuah konsep yang disebut Compositing Window Manager , juga dikenal sebagai komposer, terlibat di balik layar . Ini adalah sistem yang sekarang ada di setiap OS dan memungkinkan jendela menjadi transparan, memiliki latar belakang kabur, bayangan, dll. Komposer dapat melangkah lebih jauh dan menampilkan jendela program Anda dalam 3D. Untuk melakukan ini, komposer mengambil kendali dari bagian paling akhir dari frame dan memutuskan apa yang harus dilakukan dengannya, tepat sebelum menyentuh monitor.
Di beberapa sistem operasi, komposer dapat dinonaktifkan dalam mode layar penuh. Tapi ini tidak selalu memungkinkan, dan bahkan dalam kasus seperti itu - tidak bisakah kita menjalankan game dalam mode berjendela?
Manajemen Daya & Termal VS Kompleksitas Rendering
Kita juga harus memperhitungkan fakta bahwa CPU dan GPU modern tidak beroperasi pada frekuensi tetap, tetapi keduanya memiliki sistem yang menyesuaikan kecepatannya naik dan turun tergantung pada beban dan suhu saat ini. Dengan demikian, game tidak bisa begitu saja berasumsi bahwa mereka akan memiliki kecepatan yang sama dari frame ke frame. Di sisi lain, sistem operasi dan driver tidak dapat mengharapkan game melakukan jumlah pekerjaan yang sama di setiap frame. Sistem komunikasi yang kompleks antara dua pihak harus dirancang sedemikian rupa sehingga semua ini dapat diperhitungkan.
Tidak bisakah kita ...
Tidak bisa. :) Biasanya, pengukuran waktu GPU ditawarkan sebagai alternatif untuk menampilkan waktu. Tetapi ini tidak memperhitungkan keberadaan seorang komposer dan fakta bahwa tidak ada pengatur waktu rendering GPU yang benar-benar disinkronkan secara langsung dengan pembaruan tampilan. Untuk animasi yang sempurna, kita pasti perlu tahu persis kapan gambar itu ditampilkan, bukan kapan selesai rendering.