Існує довга історія того, як ми дійшли до цієї спільної конвенції, яка має багато захоплюючих викликів по дорозі, тому я спробую мотивувати це поетапно:
1. Проблема: пристрої працюють із різною швидкістю
Коли-небудь намагаєтеся грати в стару гру DOS на сучасному ПК, і вона працює нечувано швидко - просто розмиття?
Багато старих ігор мали дуже наївний цикл оновлення - вони збирали вхід, оновлювали стан ігор та рендерували так швидко, як це дозволило б обладнання, не враховуючи, скільки часу минуло. Це означає, що як тільки апаратне забезпечення змінюється, змінюється ігровий процес.
Ми, як правило, хочемо, щоб наші гравці мали постійний досвід та почуття гри на різних пристроях (якщо вони відповідають деяким мінімальним характеристикам), використовуючи вони торішній телефон чи новітню модель, ігровий робочий стіл вищого класу чи ноутбук середнього рівня.
Зокрема, для ігор, які є конкурентоспроможними (або для багатокористувацьких, або за допомогою лідерів), ми не хочемо, щоб гравці, які працюють на певному пристрої, мали перевагу перед іншими, оскільки вони можуть бігти швидше або мати більше часу на реакцію.
Тут надійним рішенням є блокування швидкості, з якою ми робимо оновлення стану гри. Таким чином, ми можемо гарантувати, що результати завжди будуть однаковими.
2. Отже, чому б просто не зафіксувати частоту кадрів (наприклад, за допомогою VSync) і все-таки запустити оновлення стану гри та рендерінг у режимі блокування?
Це може спрацювати, але не завжди приємно для аудиторії. Існував довгий час, коли біг на солідних 30 кадрів в секунду вважався золотим стандартом для ігор. Зараз гравці звичайно очікують, що мінімум 60 кадрів в секунду, як мінімум, особливо в багатокористувацьких бойових іграх, а деякі старі заголовки зараз виглядають помітно похмурими, оскільки наші очікування змінилися. Зокрема, є також вокальна група гравців на ПК, які взагалі заперечують проти кадрування замків. Вони заплатили чимало за своє найсучасніше обладнання та хочуть використовувати цю обчислювальну мускулатуру для найгладшого та найвищого рівня, на який вона здатна.
Зокрема у VR, частота кадрів є королем, а стандарт продовжує повзати. На початку недавнього відродження VR ігри часто тривали близько 60 кадрів в секунду. Зараз 90 є більш стандартним, і таке програмне забезпечення, як PSVR, починає підтримувати 120. Це може продовжувати зростати. Отже, якщо VR-гра обмежує рамки до того, що можна зробити і прийнято сьогодні, вона може залишитися позаду, оскільки обладнання та очікування розвиватимуться далі.
(Як правило, будьте обережні, коли їм сказано, що "гравці не можуть сприймати нічого швидше, ніж XXX", оскільки це зазвичай засноване на певному типі "сприйняття", як розпізнавання кадру послідовно. Сприйняття безперервності руху, як правило, набагато набагато більше чутливий.)
Останнє питання полягає в тому, що гра, що використовує заблокований кадр, також повинна бути консервативною - якщо ви коли-небудь потрапили на хвилину в грі, де ви оновлюєте та показуєте незвично велику кількість об'єктів, ви не хочете пропустити свій кадр термін і спричинити помітне заїкання або замикання. Таким чином, вам або потрібно встановити бюджети на вміст достатньо низькими, щоб залишити простір, або вкласти гроші в складніші функції динамічного налаштування якості, щоб уникнути прив’язки всього досвіду гри до найгіршого результату на міні-технічному обладнанні.
Це може бути особливо проблематичним, якщо проблеми з продуктивністю виявляються пізно в процесі розробки, коли всі існуючі ваші системи побудовані та налаштовані, припускаючи частоту кадрів візуалізації блокування, на яку тепер не завжди можна потрапити. Розв'язка швидкості оновлення та рендерингу дає більшу гнучкість для роботи зі змінною продуктивністю.
3. Чи не має оновлення за фіксованим часовим кроком такі самі проблеми, як (2)?
Я думаю, що це суть початкового запитання: якщо ми розв'язуємо свої оновлення та інколи виводимо два кадри без оновлень стану гри між собою, то хіба це не те саме, що ретрансляція на нижньому кадрі, оскільки видимих змін немає екран?
Насправді є кілька різних способів використання ігор для роз'єднання цих оновлень для хорошого ефекту:
a) Швидкість оновлення може бути швидшою, ніж виведений кадр
Як зазначає Тайкенн в іншій відповіді, зокрема, фізика часто наступає на більш високу частоту, ніж візуалізація, що допомагає мінімізувати помилки інтеграції та дати більш точні зіткнення. Отже, замість того, щоб оновлювати 0 або 1 оновлення між виведеними кадрами, у вас може бути 5 або 10 або 50.
Тепер рендерінг гравця зі 120 кадрів в секунду може отримати 2 оновлення на кадр, тоді як гравець на нижній специфікації апаратної рендеринга при 30 кадрів в секунду отримує 8 оновлень на кадр, і обидві їх ігри працюють з однаковою швидкістю гри-тики за реальну секунду. Краще апаратне забезпечення робить його більш гладким, але не радикально змінює, як працює ігровий процес.
Тут є ризик, що якщо швидкість оновлення не відповідає рамці кадрів, ви можете отримати "частоту биття" між двома . Напр. у більшості кадрів у нас достатньо часу для 4-х оновлень стану гри та невеликого залишку, то кожен так часто нам достатньо заощадити, щоб зробити 5 оновлень у кадрі, зробивши невеликий стрибок або заїкання в русі. З цим можна вирішити ...
б) Інтерполяція (або екстраполяція) ігрового стану між оновленнями
Тут ми часто дозволяємо ігровим станам жити один фіксований часовий крок у майбутньому, і зберігатимемо достатньо інформації з двох останніх станів, що ми можемо надати довільну точку між ними. Тоді, коли ми готові показати новий кадр на екрані, ми підходимо до відповідного моменту лише для цілей відображення (тобто ми не змінюємо базовий ігровий стан тут)
Якщо зробити це правильно, це робить рух відчутним, але руйнівний і навіть допомагає замаскувати коливання частоти кадрів, поки ми не опустимось занадто низько.
в) Додавання гладкості до змін неігрового стану
Навіть не маючи інтерполяції ігрового стану, ми все одно можемо отримати певні виграші.
Чисто візуальні зміни, такі як анімація персонажів, системи частинок або VFX, а також елементи інтерфейсу користувача, такі як HUD, часто оновлюються окремо від встановленого часового кроку стану гри. Це означає, що якщо ми відбиваємо свій ігровий стан кілька разів за кадр, ми не сплачуємо їх вартість кожним галочкою - лише за остаточний пропуск рендеру. Натомість ми масштабуємо швидкість відтворення цих ефектів відповідно до довжини кадру, щоб вони грали так само плавно, як дозволяє кадр візуалізації, не впливаючи на швидкість гри або справедливість, як обговорювалося в (1).
Рух камери може зробити це теж - особливо у VR, ми іноді показувати один і той же кадр не один раз, але відкидаємо його, щоб врахувати рух голови гравця між ними , щоб ми могли покращити сприйману затримку та комфорт, навіть якщо зможемо Виродньо не робите все так швидко. Деякі потокові системи гри (де гра працює на сервері, а гравець працює лише на тонкому клієнті) також використовують версію цього.
4. Чому б просто не використовувати цей (c) стиль для всього? Якщо це працює для анімації та інтерфейсу користувача, чи не можемо ми просто змінити масштаби оновлень стану геймплея, щоб вони відповідали поточному кадрам?
Так * це можливо, але ні це не просто.
Ця відповідь вже трохи довга, тому я не буду вникати в усі деталі, лише короткий підсумок:
Помноження на deltaTime
роботи для налаштування на оновлення змінної довжини для лінійних змін (наприклад, рух з постійною швидкістю, зворотний відлік таймера або просування по часовій шкалі анімації)
На жаль, багато аспектів ігор нелінійні . Навіть щось таке просте, як гравітація, вимагає більш досконалих методів інтеграції або підвищеної роздільної здатності, щоб уникнути розбіжностей результатів у різних рамках. Введення та контроль гравця саме по собі є величезним джерелом нелінійності.
Зокрема, результати виявлення та вирішення дискретних зіткнень залежать від швидкості оновлення, що призводить до помилок тунелювання та тремтіння, якщо кадри надто довгі. Таким чином, змінна частота кадрів змушує нас використовувати більш складні / дорогі методи безперервного виявлення зіткнень на більшій частині нашого вмісту або допускати мінливість у нашій фізиці. Навіть безперервне виявлення зіткнень стикається з проблемами, коли об’єкти рухаються по дугах, вимагаючи коротших часових кроків ...
Так, у загальному випадку для гри середньої складності, підтримка послідовного поведінки та справедливості цілком за допомогою deltaTime
масштабування знаходиться десь між дуже складними та інтенсивними в обслуговуванні до прямо нездійсненними.
Стандартизація швидкості оновлення дозволяє гарантувати більш послідовну поведінку в різних умовах , часто з більш простим кодом.
Збереження цієї швидкості оновлення, відмежованої від рендерінгу, дає нам можливість контролювати плавність та ефективність роботи, не змінюючи логіку гри .
Навіть тоді ми ніколи не отримуємо справді «ідеальну» рамкову незалежність, але, як і так багато підходів в іграх, це дає нам керований метод набрати «достатньо хороший» для потреб даної гри. Ось чому його зазвичай вчать як корисну вихідну точку.