Что такое frametime
Перейти к содержимому

Что такое frametime

Frame time в играх что это

Что такое фпс? Это английская аббревиатура (т.е. сокращение) от слов Frames Per Second, которые переводятся как «кадры в секунду». И все мы знаем, что если кадров 24 и более в секунду — то эти самые кадры воспринимаются человеческим глазом не как отдельные картинки, а как поток видео. Поэтому ФПС-еры считают, что чем выше ФПС, тем плавнее картинка у них в игре и тем комфортнее им играть. Иногда даже доходит до таких абсурдов, что для комфортнй игры в одну сетевую игру нужно как минимум 200 фпс (без учета герцовки монитора, разумеется…)

Логика здесь определенно есть, но сектанты фпс-еры забывают одну очень важную деталь. Определенное количество кадров воспринимается как непрерывный видеоряд с одним существенным условием — если эти кадры сменяются через одинаковый промежуток времени. Иными словами, количество времени, которое на мониторе находится каждый отдельный кадр должно быть одинаковым (или хотя бы стремиться к постоянному числу).

Разоблачение сектантов

В реальности время отображения отдельных кадров одинаково далеко не всегда

Если условие о стабильности времени каждого отдельного кадра нарушается, то возможна такая ситуация. Допустим, игра выдает 240 фпс (то есть 240 кадров в секунду). Однако в один прекрасный момент случается так называемый лаг (микрофриз, статтер) и один кадр, вместо того, чтобы «быть» на мониторе положенные ему 1 / 240 секунды пробыл на мониторе аж целых полсекунды. Что мы получаем в итоге? 120 кадров каждый по 1 / 240ую секунды — на первую половину секунды и один кадр-фриз на вторую. Что покажет нам мониторинг ФПС и график фремрейта? 121 ФПС! По логике сектантов ФПС-еров это дохрена большое значение и играть с ним очень комфортно.

Усугубим ситуацию. Допустим, такие фризы по полсекунды случаются один раз каждые 5-10 секунд. Что в таком случае нам покажет мониторинг ФПСа? 120-240 кадров, по мнению сектантов — плавная комфортная игра. Что получится в реальности? Полное отсутствие плавности и комфорта, то есть ебучий лагодром

ФПС-еры скажут, что «так не бывает». Возможно для большей наглядности я привел в пример не совсем реалистичные цифры, однако сама ситуация с такими микрофризами, не сильно влияющими на ФПС, но очень сильно влияющими на комфорт игры встречается сплошь и рядом.

И чем выше был изначальный ФПС — тем выше показатель мониторинга в случае лага/статтера. В такую ловушку попадают будущие покупатели популярных Pentium 4560 и i5 6400/7400, у которых относительно высокий фпс в играх, но случаются лаги. Подтверждаю, как владелец ай5

Что же делать? Есть решение!

Если ФПС ничего не значит, как же тогда определять в тестах, комфортно ли играть в данную игру на данном железе? Как ни странно, данная проблема решается, и решается как минимум двумя способами

Способ 1: График времени кадра (Frametime). Да, его тоже можно включить на мониторинге и он есть в нормальных тестах на ютубе. Если он ровный (ситуация на картинке справа) — значит играть комфортно. Если дёрганный (картинка слева) — играть не очень комфортно. Если ровный, но с «шипами» вверх, и таких шипов много (смотри картинку выше) — значит это ситуация из описанного мной примера, играть очень некомфортно.

Способ 2: Значения 1% low и 0,1% low. Не буду вдаваться в детали, что это за показатели, потому что не все учили в школе/универе матстат. Просто скажу, что если разница между значениями этих двух показателей составляет 5-10%, то играть комфортно. Если больше — то есть лаги/фризы/статтеры.

Но, естественно, первый способ более удобный и более наглядный. В нём даже часто с графиком времени кадра в пару ставят счетчик ФПС для тех, у кого от него ещё слишком сильная зависимость, избавиться от которой сразу не получается

Ах вот ещё что хотел бы добавить — самый минимальный стабильный показатель времени кадра для комфортной игры33,3 мс, который соответствует стабильным 30 ФПС с локом (консольный вариант). Для достаточно комфортной игры — минимум 16,7 мс, аналог 60 кадров в секунду по меркам ФПС.

Вместо заключения

Теперь вы знаете страшную правду и можете тыкать носом в говно всех сектантов в интернетах сами определять, на чём играть комфортно, а на чём нет. Всем доброго фреймтайма!

Материал подготовлен и опубликован группой Б.С.П.К.

На просторах интернета можно найти бессчетное множество статей про видеокарты, но большинство их созданы по одному и тому же принципу: все авторы меряют минимальный и средний FPS, а кто-то еще и максимальный. Насколько ценны эти замеры, насколько объективно они отражают уровень комфорта во время игры? Я пришел к выводу, что не очень, а всё потому, что такая методика совершенно не учитывает микрозадержки, они же микролаги или фризы.

Проблема микролагов известна давно, особенно остро она стояла лет пять назад у владельцев карт ATI. Суть в том, что на долю секунды FPS падает до неприлично низкого уровня, причем делает это с раздражающей регулярностью. В такой ситуации средний FPS будет в полном порядке, поскольку на пару «медленных» кадров приходится тысяча нормальных, а минимальный FPS покажет только худший лаг, он может быть не очень сильным, но проблема в том, что лаги частые!

реклама

Стоит упомянуть и лаги, возникающие при резком усложнении сцены, а именно при красочных взрывах и разрушениях с реалистичной физикой. С ними такая же проблема: минимальный FPS выявит последствия только самого большого взрыва, а средний FPS практически не будет зависеть от числа этих взрывов.

В такой ситуации не остается ничего другого, кроме как записывать время отрисовки каждого кадра. Тут может помочь популярнейшая программа FRAPS, а точнее ее способность записывать лог frametimes, хотя это еще полдела. Результаты нужно переработать так, чтобы их было удобно воспринимать, и чтобы получить возможность объективно сравнивать разные системы между собой. В данной статье описан мой способ это сделать.

Демонстрационные примеры снимались на следующем тестовом стенде:

  • Процессор: Intel Core i7 930, 4 ГГц (200 х 20, 1,35 В);
  • Система охлаждения: GlacialTech Siberia;
  • Термоинтерфейс: КПТ-8;
  • Материнская плата: Asus P6T SE (BIOS 0805);
  • Оперативная память: Corsair Dominator TR3X6G1600C8D DDR3 1600 МГц, 8-8-8-20, 3×2 Гбайт;
  • Жесткий диск: WD Velociraptor, WD6500HLHX-01JJPV0, 450 Гбайт;
  • Видеокарта: Sapphire Radeon HD 5670, 1 Гбайт GDDR5;
  • Блок питания: Enermax Modu 87+, 700 Вт.
реклама

Надеюсь, вы решили оценить предлагаемый метод, уже неоднократно испытав классический вариант, поэтому не стану объяснять, где скачать FRAPS, как его установить и как запускать, а перейду сразу к делу. Чтобы получать лог frametimes, достаточно поставить нужную галочку в настройках:

Если вы не меняли пути, то после замеров в каталоге C:FrapsBenchmarks будет появляться файл ***frametimes.csv. Это текстовый файл с запятыми-разделителями, в который еще зачем-то добавлены пробелы, с такими файлами проще всего работать в MS Excel. Открывать файл следует не как обычно, а через импорт данных. В Excel 2007 это вкладка «Данные», группа «Получить внешние данные», кнопка «Из текста».

После указания файла в появившемся мастере текстов на первом шаге оставляйте всё по умолчанию (формат данных: с разделителями), на втором выставите символом-разделителем запятую, третий шаг можете пропустить и сразу нажать «Готово». Импорт следует начать с ячейки A1 (настройка по умолчанию). В итоге должны получиться два столбца данных:

Теперь из этих данных нужно получить время отрисовки каждого кадра и мгновенный FPS. Время отрисовки это не что иное, как разница между временны́ми отметками соседних кадров, а мгновенный FPS – обратная величина времени отрисовки, умноженная на 1000 (поскольку время указано в миллисекундах).

На основе столбца с мгновенными FPS можно построить интересный график. Для примера я взял результаты из бенчмарка «S.T.A.L.K.E.R.: Зов Припяти» со следующими настройками:

  • Разрешение 1680×1050;
  • Установки: средние;
  • Рендер: Улучшенное полное освещение (DX10).

Вот так выглядят мгновенные FPS в первом тесте днем:

Замер по классической схеме выдал minFPS=26 и avgFPS=38,57. Со средним всё понятно (это общее количество кадров, деленное на длину демо сцены в секундах), а про минимальный есть большой вопрос. Какие 26, если кадр №3347 рисовался аж 110 мс, что дает менее 10 FPS. Это явный лаг, заметный на глаз, но значение minFPS говорит, что всё хорошо. И ведь есть полно кадров, с мгновенным FPS меньше 27!

Для наглядности стоит создать еще один столбец и еще один график, в котором посчитано число вхождений кадров в определенный диапазон. Для простоты расчетов я просто отбрасывал дробную часть значения FPS и считал, как часто встречается то или иное целое число. Получилась группировка по диапазонам шириной в 1 FPS.

реклама

График на основе этих столбцов выглядит так:

Самые быстрые кадры в этом замере выдавали мгновенные значения более 300 FPS, но в этом графике я решил их не учитывать и ограничиться значением 100 FPS. Кстати, FRAPS намерял maxFPS=50. Проверка показала, что это число отражает максимальное количество кадров, отрисованных в течение одной секунды.

Акцент данной статьи сделан на выявлении микролагов, так что предлагаю рассмотреть более подробно «медленные кадры», левее основного «колокола» нормального распределения, скорость которых менее 30 FPS.

реклама

Наверняка кто-то посчитает границу в 30 FPS недостаточной и захочет рассмотреть больший диапазон. Напоминаю: сейчас я описываю теоретический метод, а данная тестовая система просто пример. На компьютерах с более мощными видеокартами основная группа кадров будет располагаться гораздо правее, тогда в «медленную» группу можно включить и 40 FPS, и 50, хотя падение скорости до 50 FPS это вовсе не лаги.

Вернемся к графику. Теперь видно, сколько кадров было медленными и насколько медленными. Но картина всё еще не оптимальна для восприятия.

Во-первых, нужно объяснять, что маленькая отметка в значении 9 FPS говорит о худших вещах, чем полоса, скажем, на значении 27 FPS. Один кадр с мгновенной скоростью 9 FPS это статическое изображение на протяжении 110 мс, а четыре кадра 27 FPS наверняка идут непоследовательно, плюс замирание картинки на 37 мс не настолько страшно.

Во-вторых, все привыкли, что в разных столбцах содержатся разные категории. А представьте, что будет, если на этом же графике отобразить такой же набор данных, сдвинутый на 1 FPS вбок – получится хаос из разноцветных лестниц! А если попытаться сравнить штук пять систем?

реклама

График по этому столбцу получается такой:

Теперь время, в течение которого FPS находится ниже определенного уровня, демонстрируется одной простой линией.

реклама

Нет ничего сложного, чтобы провести три замера и вычислить средние результаты.

Не могу похвастаться очень точным совпадением трех вариантов, но качественно все они одинаковы: кадров медленнее 14 FPS практически нет, кадры медленнее 21-25 FPS длятся в сумме 5 секунд.

Давайте посмотрим, как поведет себя эта система в сравнении с другой в том же бенчмарке на одинаковых настройках:

реклама
Основная платформа Платформа для сравнения
Процессор Core i7 930, 4 ГГц (200 х 20) Core i7 920, 3,6 ГГц (180 х 20)
Материнская плата Asus P6T SE Asus P6T Deluxe
Оперативная память 3×2 Гбайт, 1600 МГц, 8-8-8-20 3×2 Гбайт, 1440 МГц, 7-7-7-16
Жесткий диск WD Velociraptor, 450 ГБ 3x WD Raptor 74 ГБ, RAID-0
Видеокарта Radeon HD 5670, 1 Гбайт GDDR5 GeForce 8800 GT, 512 Мбайт DDR3
ОС Windows 7 Ultimate x64 rus Windows 7 Ultimate x64 rus
Особенность «Чистая», недавно установленная система Рабочий компьютер с множеством установленных программ

Если кратко, процессор на основной тестовой платформе разогнан сильнее, но Radeon HD 5670 явно слабее GeForce 8800 GT.

Для начала, вот графики с усредненными по трем замерам minFPS и avgFPS: minFPS | avgFPS

Включите JavaScript, чтобы видеть графики

GeForce 8800 GT легко разгромил соперника… или не легко? Надеюсь, вы уже поняли, что minFPS не показывает скорость самого медленного кадра сцены. Давайте посмотрим на другой график.

Фреймтайм — это время подготовки кадра, по сути график, сколько готовится каждый кадр.

Смотри фпс снимает счетчик кадров в секунду.
Это прямая.
Каждый кадр — точка на прямой.

У тебя может быть так, что за первые 0.5 секунды, было подготовлено 10 кадров, а за оставшиеся 50 — в итоге у тебя 60 фпс (60кадров в секунду).

Но график не равномерный, первая половина кадров готовилась очень долго и из-за этого когда монитор начнет выбирать данные.
Вырастет инпут лаг, а часть кадров вообще может оказаться пропущена.

Как мониторить FPS и другие параметры в играх

Знать, сколько кадров в секунду выдает игра важно сразу по нескольким причинам. Во-первых, так гораздо проще настраивать графику. Вы сразу видите прирост или падение производительности в зависимости от измененных настроек. Во-вторых, важно понимать, какое количество кадров в секунду будет оптимальным для вашей системы. Частота кадров — показатель динамический. Единого стандарта нет, но есть некоторые устоявшиеся форматы.

Минимально комфортным считается показатель в 30 кадров в секунду. Именно на этом уровне работают многие консольные игры. Стоит отметить, что до появления форматов высокой четкости (то есть до Xbox 360 и PlayStation 3) консольные игры работали в стандартных телевизионных системах PAL и NTSC. Частота кадров там различается: 25 и 30 кадров соответственно (или 50 и 60 кадров). То есть в то время играбельными считались и 25 кадров. Из-за этого игры в формате PAL кажутся более медленными.

Современные стандарты не лимитируют количество кадров в секунду. Оптимальное значение в первую очередь зависит от частоты дисплея. Так, если вы используете стандартный монитор с частотой развертки 60 Гц, то количество кадров в секунду, выдаваемое игрой, должно совпадать. Если оно будет выше, то визуально это заметить практически невозможно, только по мониторингу. Именно поэтому к монитору с частотой обновления 60 Гц нет смысла покупать топовую видеокарту: она будет либо работать не в полную силу, если выставить ограничение на 60 кадров, либо «молотить» впустую, выдавая лишние кадры.

Стоит также отметить, что современные мониторы и видеоадаптеры поддерживают переменную частоту кадров. То есть если ваше железо не может выдать 144 кадра для соответствующего монитора, вы не почувствуете рывков в изображении. Поддержка VRR (variable refresh rate) — одна из фишек нового интерфейса HDMI 2.1, которыми оснащены новые консоли.

Как отобразить FPS на экране

Некоторые игры содержат встроенный счетчик кадров, который можно включить в настройках. Например, такая опция есть в Doom Eternal. Также счетчик кадров есть в игровом клиенте Steam. Включить его можно следующим образом.

Откройте настройки и перейдите на вкладку «В игре», затем включите счетчик кадров. Можно выбрать отображение в любом углу экрана. Такие же функции есть и других лаунчеров. Так, можно включить счетчик кадров в Origin («Настройки» — «Дополнительно») и Ubisoft Connect («Настройки» — «Общие»). Также счетчик кадров можно настроить в приложениях от производителя видеокарты. Например, в GeForce Experience нужно зайти в «Настройки» — «Расположение HUD».

Гораздо больше возможностей дают сторонние программы. В нулевых для отображения FPS часто использовали программу FRAPS. Программа уже давно не развивается, последняя версия вышла в 2013 году. Однако при желании скачать ее можно и сейчас. Как минимум, потому что FRAPS поддерживает запись лога, который затем можно просмотреть в удобоваримом виде через программу FRAFS. Тем не менее лучше использовать более продвинутые инструменты вроде MSI Afterburner или FPS Monitor.

Как настроить мониторинг MSI Afterburner

Преимущество MSI Afterburner в том, что это бесплатная программа, в отличие от FPS Monitor, лицензия для которого стоит 350 рублей. Поэтому настраивать мониторинг мы будем именно на примере MSI Afterburner.

После установки MSI Afterburner и RivaTuner Statistics Server стоит зайти в «Настройки» (иконка с шестеренкой), далее во вкладку «Интерфейс» и поменять скин на более удобный Default MSI Afterburner v3 skin — big edition.

Почти все настройки RivaTuner Statistics Server можно оставить по умолчанию. Проследите, чтобы были активированы пункты автозагрузки отображения оверлея: Start with Windows и Show On-Screen Display. Также может пригодиться функции ограничения кадров в секунду (Framerate Limit), а также масштабирование (On-Screen Display Zoom).

Все основные настройки расположены на вкладке «Мониторинг». Здесь нужно выбрать необходимые параметры. Как минимум это должна быть частота кадров. Если же вы хотите получить полную картинку, то советуем выбрать следующее: температура ГП, загрузка ГП, загрузка памяти, частота ядра, температура ЦП, загрузка ЦП, частота ЦП, загрузка ОЗУ, частота кадра, время кадра.

Если в системе две видеокарты (встроенная и дискретная), то параметры будут дублироваться для ГП1 и ГП2. Посмотреть, какой именно графический адаптер первый, а какой второй можно на вкладке «Основные» в самом верху.

Чтобы параметр отображался в оверлее, нужно проставить галочку «Показывать в ОЭД». Также можно переименовать параметр, если отметить галочку «Переопределить имя группы». Также стоит задать горячие клавиши для скрытия мониторинга с экрана. На вкладке «ОЭД» назначьте клавишу для «Показать ОЭД» и «Скрыть ОЭД».

Что такое показатели 1% и 0,1%

Показатели 1% и 0,1% еще называют редкими и очень редкими событиями. В целом это описание довольно точное, так как эти показатели отражают среднее количество кадров в худший 1% или 0,1% времени.

Среднее количество кадров в секунду — хороший показатель для определения общей производительности. Но для более детального анализа такой параметр не подходит. Минимально зафиксированное количество кадров в секунду тоже может не отражать реальной картины. К примеру, во время мониторинга могла случиться одна кратковременная просадка до 10 кадров. В остальное время производительность не проседала ниже 25 кадров, но статистика уже будет подпорчена 10 кадрами.

В MSI Afterburner можно настроить отображение 1% и 0,1%. Но измерять их нужно на определенном отрезке времени, активируя вручную. Чтобы начать и завершить тест, назначьте клавиши в меню «Глобальные горячие клавиши бенчмарка» на вкладке «Бенчмарк».

Что такое время кадра

Время кадра или Frametime показывает задержку между кадрами, которая измеряется в миллисекундах. Чем она меньше, тем лучше. Однако важна не только низкая задержка между кадрами (то есть высокий фреймрейт), но и плавность. Если график фреймтайма ровный без резких перепадов, то картинка будет плавной даже при не самой высокой частоте кадров. Если график неровный, то будут ощущаться статтеры, то есть рывки в картинке.

То есть стабильные 30 кадров в секунду гораздо лучше плавающей частоты от 20 до 40 кадров. Именно поэтому в некоторых случаях стоит «залочить» FPS на определенном значении. Если система не вытягивает стабильные 60 кадров, то поставить, например, 40 или 50.

Что еще можно узнать из мониторинга

MSI Afterburner, кроме FPS, позволяет вывести еще и другие параметры: температуру и загрузку комплектующих, частоту работы, загрузку отдельных ядер и т. п.

Неуловимая проблема тайминга кадров

Наконец-то появилось объяснение того, почему некоторые игры тормозят на вашем PC (и луч надежды на то, что в ближайшем будущем они тормозить перестанут).

Т-т-тормоза

Вы с нетерпением ждали следующей части вашей любимой серии видеоигр для PC и она наконец вышла. На этот раз вы хотите насладиться ею во всей полноте, поэтому потратили деньги и время на тщательную подготовку. Вы заменили процессор, поставили сверхсовременную видеокарту, добавили ещё ОЗУ — чёрт возьми, даже купили RAID на SSD. Игра должна быть плавной с самой заставки.

Предзаказ наконец разблокирован и вы только что завершили установку. В нервном предвкушении вы впервые запускаете игру. Пока всё хорошо — она работает с частотой 60 кадров в секунду. Или, по крайней мере, так сообщает счётчик кадров тюнера GPU. Но что-то не так. Вы делаете мышью резкие, хаотичные движения. Стрейфитесь влево-вправо, и тут игра… начинает тормозить! Блин, да как такое возможно? Как она может тормозить при 60 кадрах в секунду?

Если такое с вами никогда не случалось, то это может показаться смешным. Но если вы их испытали, то, скорее всего, ненавидите тормоза всей душой. Тормоза в играх. Это не старый добрый «лаг». Не низкая частота кадров. Это просто «тормоза», происходящие при высоких частотах кадров на идеальных, супербыстрых машинах. Что это, откуда они взялись и как от них избавиться? Позвольте мне рассказать вам историю…

Тормоза, плавность, скорость… это ведь одно и то же?

Видеоигры работали с частотой 60 fps ещё со времён первых аркадных автоматов в 70-х годах. Обычно ожидается, что игра работает с той же частотой, которая используется дисплеем. Так было до популяризации 3D-игр, в которых впервые стала допустимой пониженная частота кадров. В 90-х, когда «3D-карты» (так мы называли их до того, как они стали «GPU«) начали заменять программный рендеринг, люди играли в игры при 20 fps, а 35 fps считались приличным значением для серьёзных сетевых боёв. Я не шучу.

Сегодня у нас есть супербыстрые машины и «разумеется, они могут работать при 60 fps«. Однако количество разочарованных скоростью игр пользователей как никогда велико. Как такое возможно? Проблема оказывается не в том, что игры не могут работать достаточно быстро, а в том, что они тормозят, даже когда могут работать быстро!

Если почитаете разные игровые форумы, то наверняка найдёте подобные сообщения:

image

Можно подумать, что это единичные проблемы, но посмотрите на статистику поисковых запросов Google:

image

За последние пять лет тормоза (stutter) стали (относительно) более серьёзной проблемой, чем скорость!

(Учтите, что это относительные значения. Они не значат, что в целом люди спрашивают о торможениях больше, чем о частоте кадров. Они значат, что запросы о частоте кадров (frame rate) остаются на том же уровне, а количество запросов о тормозах растёт, особенно в последнее время.)

Десяток лет в поисках причины необъяснимых тормозов

Пациент скорее жив, чем мёртв, просто тормозит чуть больше, чем нужно.

Впервые я столкнулся с этой проблемой ещё примерно в 2003 году. Мы работали над Serious Sam 2, и пользователи начали отправлять нам отчёты о том, что они тестировали что-то на пустом уровне, и при перемещениях мыши движения не были плавными. Это сопровождалось очень характерным паттерном на графике частоты кадров, который мы прозвали «кардиограммой».

Мы думали, что где-то в коде есть баг, но не могли его найти. Казалось, что проблема появляется и исчезает случайным образом — после перезапуска приложения, перезагрузки машины… а потом игрок менял какую-нибудь опцию скорости и она исчезала. Потом игрок снова включал эту опцию, но проблема не возвращалась. Она была похожа на призрака.

Очевидно, что эта проблема возникала не только у нас. Наблюдая за теми же проблемами в других играх, мы начали думать, что виноваты драйверы. Но это происходило на видеокартах разных производителей. Даже на разных API (OpenGL, DirectX 9, DirectX 11…) — единственным общим у них было то, что они появлялись на разных машинах, в некоторых сценах… иногда.

image

Несси, бигфут… почти столь же неуловимые, как и проблема с «кардиограммой».

Мы выпустили ещё несколько игр, но это странное поведение по-прежнему появлялось и исчезало. Некоторых пользователей оно раздражало, и мы рекомендовали им изменить опции скорости — иногда это помогало, иногда нет. Такова жизнь, не правда ли?

Но однажды, в отличный зимний день в начале 2013 года мой коллега Дин позвал меня, чтобы я увидел ещё один пример этой проблемы, который он на тот момент мог относительно стабильно воспроизводить. На этот раз проблема возникала на уровне из Serious Sam 3. Мы экспериментировали с опциями в этой сцене, пока до меня внезапно не дошло. Я понял, в чём была причина! И она была очень проста — неудивительно, что она ускользала от всех в течение десятка лет.

Изменив всего одну очень простую опцию игрового движка, мы смогли заставить эту проблему появляться и исчезать в этой конкретной сцене. Но нам стало сразу же очевидно, что на её качественное решение потребуется гораздо больше усилий. Усилий не только с нашей стороны, но и всей игровой экосистемы PC — программистов драйверов GPU, разработчиков API, поставщиков ОС — каждого.

В чём же была причина всё это время

Хотел бы я показать вам её на примере сцены из Serious Sam 3, которую мы с Дином исследовали пять лет назад. Или даже ещё лучше — на примере тестовой сцены из Serious Sam 2, в которой мы впервые её увидели. Но, к сожалению, после замены «железа» этот ускользающий зверь может переместиться в другую сцену. У меня есть сцена из The Talos Principle, в которой мне недавно удалось воспроизвести эту проблему, и я заснял несколько видео, позволившие проанализировать её более подробно.

Но прежде чем мы начнём, убедитесь, что вы на самом деле смотрите видео в 60 fps. Для просмотра представленных ниже примеров переключитесь в 1080p60, как показано на картинке:

image

Чтобы смотреть видео в 60 fps, переключитесь в YouTube на 1080p60.

Если вы всё сделаете правильно, а ваш компьютер и веб-браузер способны показывать видео с частотой 60 fps, то представленное ниже видео должно воспроизводиться плавно и без всяких тормозов. Если это не так, то именно поэтому мы и говорим об этом — многие другие приложения тоже демонстрируют такое поведение, не только игры. Пока я могу только рекомендовать вам попробовать посмотреть видео на какой-нибудь другой машине, или просто читать текст.

Проверка, проверка, раз, два, три… Вы должны видеть это видео в плавных 60 fps.

А теперь перейдём к делу. Если вы сталкиваетесь с тормозами, то вероятнее всего это выглядит примерно так:

Вот как выглядят «тормоза при 60 fps». Мы называем этот симптом «кардиограммой».

Да, именно так выглядят «тормоза», даже когда игра работает с 60 fps. Вы могли сталкиваться с чем-то подобным в любой современной игре, и вероятно думали, что «игра не оптимизирована». Так вот, вам стоит пересмотреть свою теорию (о том, что такие тормоза возникают из-за «медленного» рендеринга игры). Если игра «слишком медленная», то это значит, что в какие-то моменты она не сможет достаточно быстро отрендерить один кадр, а монитору придётся заново показывать предыдущий кадр. Поэтому когда мы записываем видео такой игры в 60 fps, то видим «пропущенные кадры». (Это такие кадры, при которых следующий кадр не был отрендерен вовремя, поэтому текущий кадр показывается дважды.)

Теперь снова запустите предыдущее видео с тормозами («кардиограммой»), поставьте его на паузу и нажимайте в проигрывателе YouTube клавишу . (точка), чтобы перемещаться от кадра к кадру. Попробуйте заметить, когда один и тот же кадр показывается дважды. Давайте, попробуйте, я подожду…

Ну как, нашли? Нет? Странно, не правда ли.

Как такое может быть?

Позвольте мне объяснить более подробно. Вот сравнение идеально плавного видео и видео с тормозами в виде «кардиограммы», воспроизводимые на 1/20 от исходной скорости, чтобы мы могли видеть отдельные кадры:

Сверху правильное видео с 60 fps, снизу «кардиограмма». Воспроизведение замедлено в 20 раз.

Можно заметить две вещи: во-первых, они действительно воспроизводятся с одинаковой частотой — когда сверху есть новый кадр, снизу тоже есть новый кадр. Во-вторых, они по какой-то причине движутся немного по-разному — есть заметный «разрыв» в середине изображения, который становится то более, то менее заметным.

Внимательный зритель может заметить и ещё одну любопытную деталь: нижнее — тормозящее — изображение — которое считается «медленным»… на самом деле «опережает» правильное. Странно, правда?

Если мы посмотрим на два соседних кадра и их тайминги (заметьте, что во всех показанных мной видео были точные таймеры (с точностью 1/10 000 секунды), то можем заметить нечто очень интересное: первые два кадра идеально синхронизированы, но третий…

image

Шесть идущих друг за другом кадров из видео с точными таймингами. Верхние — правильные, нижние — с «кардиограммой».

…на третьем кадре мы видим, что дерево в «тормозящем» видео значительно опережает свою копию из правильного видео (обведено красным). Также можно заметить, что на этот кадр, похоже, ушло больше времени (обведено жёлтым).

Постойте… если видео «медленнее», и на кадр «ушло больше времени», то как он может опережать правильный?

Чтобы разобраться в этом, вам нужно понять, как в наше время игры и другие трёхмерные интерактивные приложения реализуют анимации и рендеринг. (Опытные разработчики должны простить меня за то, что я надоедаю им с очевидными вещами, но мне нужно быть уверенным, что текст смогут понять все читающие этот текст игроки.)

Краткая история таймингов кадра

Давным-давно, в далёкой-далёкой галактике… Когда разработчики создавали первые видеоигры, они обычно подстраивались под точную частоту кадров, с которой работает дисплей. В регионах NTSC, где телевизоры работали при 60 Гц, это означало 60 fps, в регионах PAL/SECAM, где телевизоры работали при 50 Гц, это означало 50 fps. Они даже и думать не могли о какой-то возможности «пропуска кадра».

Большинство игр было очень вылизанными и упрощёнными концептами, работавшими на конкретном оборудовании — обычно на аркадном компьютере, или на «домашнем микрокомпьютере», наподобие ZX Spectrum, C64, Atari ST, Amstrad CPC 464, Amiga и т.д. По сути, разработчик создавал дизайн, реализовывал и тестировал игру под конкретную машину и конкретную частоту кадров, и был на 100% уверен, что она никогда не пропустит ни кадра.

Скорости объектов тоже хранились в единицах «кадров». Поэтому говорили, не на сколько пикселей в секунду должен двигаться персонаж, а на сколько пикселей за кадр. Известно, что в Sonic The Hedgehog для Sega Genesis скорость вращения, например, была равна 16 пикселям за кадр. У многих игр даже были отдельные версии для регионов PAL и NTSC, в которых анимации вручную рисовались специально под 50 fps и 60 fps. По сути, запуск при любой другой частоте кадров даже не рассматривался.

Когда игры начали работать на более разнообразных машинах — в частности, на PC с расширяемым и заменяемым «железом» — разработчики больше не могли знать, с какой частотой кадров теперь будет работать игра. Дополните это тем фактом, что игры стали более сложными и непредсказуемыми. Самыми выдающимися в этом плане стали 3D-игры, отличавшиеся разнообразием сложности сцен, иногда даже зависящей от игрока. Например, всем нравится стрелять в бочки с топливом — при этом происходит огромный взрыв, красивые эффекты… и неизбежная просадка кадров. Но здесь никто не против пропуска кадров, потому что это так интересно.

Поэтому было очень сложно предсказать, сколько займёт симуляция и рендеринг одного кадра. (Стоит заметить, что на современных консолях «железо» по-прежнему неизменно, но сами игры всё равно часто непредсказуемы и сложны.)

Если мы не можем быть уверенными, при какой частоте кадров будет работать игра, нам приходится измерять текущую частоту кадров и постоянно адаптировать физику и скорость анимаций игры. Если один кадр занимает 1/60 секунды (16,67 мс), а персонаж бежит со скоростью 10 м/с, то в каждом кадре он перемещается на 1/6 метра. Но если кадр перестаёт занимать 1/60 секунды, а вместо этого внезапно начал занимать 1/30 секунды (33,33 мс), то надо начать перемещать персонажа на 1/3 метра (в два раза «быстрее») за кадр, чтобы на экране он продолжал двигаться с кажущейся постоянной скоростью.

Как же игра это делает? По сути она измеряет время в начале одного кадра, а затем в начале следующего и вычисляет разность. Это довольно простой способ, но он очень хорошо работает. То есть простите, он работал хорошо. В 90-х (вспомните фразу «35 fps считались приличным значением для серьёзных сетевых боёв» из начала статьи), людей более чем устраивал этот способ. Но в то время графическая карта (не забывайте, их даже ещё не называли GPU) была очень «тонким» элементом «железа», и попаданием объектов на экран непосредственно управлял основной ЦП. Если в компьютере не было 3D-ускорителя, процессор даже сам отрисовывал эти объекты. Поэтому он точно знал, когда они появятся на экране.

Что происходит сегодня

Со временем у нас появились более сложные GPU, и они становились всё более и более «асинхронными». Это значит, что когда ЦП отдаёт GPU команду отрисовать что-то на экране, то GPU просто сохраняет эту команду в буфер, чтобы ЦП занимался своими делами, пока GPU выполняет рендеринг. В результате это привело к тому, что когда ЦП сообщает GPU, что «это конец кадра», GPU просто сохраняет сообщение как ещё один фрагмент данных. Но он не относится к нему как чему-то особо срочному. Да и как он может — ведь ему по-прежнему нужно обрабатывать часть из ранее переданных команд. Он покажет кадр на экране, когда закончит всю работу, которую ему дали раньше.

Поэтому когда игра пытается вычислить тайминги, вычитая метки времени начала двух кадров, то актуальность этого, грубо говоря… весьма сомнительна. Давайте вернёмся к нашему примеру из коротких видео. У нас есть эти кадры, где камера перемещается вдоль деревьев:

image

Шесть идущих друг за другом кадров из видео с точными таймингами. Верхние — правильные, нижние — с «кардиограммой».

Теперь вспомните то, что я говорил о таймингах и перемещениях. В первых двух кадрах тайминг кадра равен 16,67 мс (то есть 1/60 секунды), и камера движется на одну и ту же величину и сверху, и снизу, поэтому деревья синхронизированы. На третьем кадре (внизу) игра увидела, что время кадра равно 24,8 мс (что больше 1/60 секунды), поэтому она думает, что частота кадров снизилась и торопится переместить камеру чуть дальше… только для того, чтобы обнаружить, что тайминг четвёртого кадра составляет всего 10,7 мс, поэтому камера движется здесь чуть медленнее, и деревья снова более-менее синхронизируются. (Синхронизация восстановится полностью только спустя два кадра.)

Здесь происходит следующее: игра измеряет то, что она считает началом каждого кадра, а эти тайминги кадров иногда по разным причинам колеблются, особенно на такой высоконагруженной многозадачной системе, как PC. Поэтому в некоторые моменты игра думает, что не успевает обеспечить 60 fps, и в какие-то моменты генерирует кадры анимации, рассчитанные на меньшую частоту кадров. Но из-за асинхронной природы работы GPU он на самом деле успевает обеспечить 60 fps для каждого отдельного кадра этой последовательности.

То есть, по сути, здесь нет никакой проблемы — всё действительно работает плавно, просто игра об этом не знает.

При этом мы возвращаемся к началу статьи. Наконец обнаружив причину проблемы (на самом деле, это иллюзия проблемы — ведь её на самом деле нет, так?), вот что мы сделали для проверки:

Сначала мы наблюдаем «кардиограмму», а затем используем небольшой трюк, чтобы избавиться от неё.

В первой части видео вы с самого начала можете увидеть проблему с «кардиограммой». Затем мы изменяем «магическую» опцию, после чего всё становится идеально плавным!

Что же это за волшебная опция? В Serious Engine мы называем её sim_fSyncRate=60 . Если говорить простыми словами, то это значит «полностью игнорировать все эти заморочки с таймингами и притвориться, что мы всегда замеряем стабильные 60 fps». И благодаря этому всё работает плавно — просто потому, что всё и так работало плавно! Единственная причина, по которой всё выглядело тормозящим — это ошибочные тайминги, используемые для анимации.

И на этом всё? Достаточно сделать так и всё станет замечательно?

Неужели решение настолько простое?

К сожалению — нет. Это всего лишь тест разработчиков. Если мы перестанем замерять частоту кадров в реальных ситуациях и просто будем предполагать, что она всегда равна 60, то когда она упадёт ниже 60 — а на PC она рано или поздно обязательно упадёт по тем или иным причинам: ОС запустит какой-нибудь фоновый процесс, включится экономия энергии или защита от перегрева GPU/ЦП… кто знает — то всё замедлится.

Итак, если мы изменяем частоту кадров, то возникают торможения, если нет — то всё в какие-то моменты может замедляться. Что же нам делать?

Реальное решение заключается в том, чтобы измерять не начало/завершение рендеринга кадра, а время отображения картинки на экране.

Это шокирует, я понимаю. Можно было ожидать, что это базовая функция каждого графического API. Но оказывается, в процессе постепенных улучшений тут и там все, в сущности, упустили сам смысл проблемы. Мы все забыли о тонких деталях своей работы, продолжая повторять одно и то же, а графические API эволюционировали во всех других аспектах, кроме этого: приложение никаким образом не может точно узнать, что кадр на самом деле отображается на экране. Мы можем узнать, когда закончится его рендеринг, но не когда он будет показан.

Что дальше?

Но не волнуйтесь, всё не так мрачно. Многие люди в графической экосистеме активно работают над реализацией поддержки правильного тайминга кадров для разных API. Для Vulkan API уже есть расширение под названием VK_GOOGLE_display_timing , которое продемонстрировало свою полезность в реализации proof of concept. Однако оно доступно только для ограниченного ассортимента оборудования, в основном на Android и Linux.

Уже ведётся работа по созданию аналогичных и более качественных систем для всех основных графических API. Когда она закончится? Сложно сказать, потому что проблема лежит довольно глубоко внутри различных подсистем ОС.

Однако я заверяю вас, что Croteam безустанно работает над тем, чтобы эта проблема была решена как можно скорее, и все участники экосистемы интерактивной графики понимают и поддерживают наши усилия.

Мы стремимся сделать это решение доступным для более широкой аудитории, и когда это случится, мы подготовим апдейт The Talos Principle с реализацией этой функции.

Различные помехи и другие подробности

Последнюю фразу можно считать концом основного текста. Ниже представлены «бонусные разделы», практически не связанные друг с другом и основным текстом. Вероятно, я буду обновлять их, когда ситуация станет меняться, или в случае возникновения более сложных вопросов, требующих решения в ближайшем будущем.

«Композитор»

image

Эффект матового стекла? Да, для него нам определённо нужен композитор. Он просто-таки необходим, правда?

За кулисами со всем этим связан концепт под названием «композитный менеджер окон», или композитор. Это система, существующая теперь во всех ОС, которая позволяет окнам быть прозрачными, иметь размытый фон, тени, всплывающие поверх окна Skype и т.д. Композиторы даже могут отображать окна в 3D. Для этого композитор перехватывает управление над последним этапом создания картинки кадра и решает, что ему сделать с ней, прежде чем она попадёт на экран монитора. Это ещё больше всё усложняет.

В некоторых ОС композитор можно отключить в полноэкранном режиме. Но это не всегда возможно, а даже если и возможно — то разве можно запретить запускать игру в оконном режиме?

Управление питанием и тепловыделением против сложности рендеринга

Мы также должны учитывать, что современные ЦП и GPU не работают с фиксированной частотой, а имеют системы, изменяющие их скорости в соответствии с нагрузкой и температурой. Поэтому игра не может просто предполагать, что GPU и ЦП будут иметь одинаковую скорость в каждом кадре. С другой стороны, ОС и драйверы не могут ожидать, что у игры в каждом кадре будет одинаковый объём работы. Чтобы учесть это, необходимо разработать сложные системы для общения этих двух сторон.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *