Отрисованные GPU кадры по несколько штук ждут в очереди и выводятся в такт монитору, поэтому ввод доходит до экрана с опозданием.
Почему Графический драйвер заранее держит в очереди 1–3 кадра → Следствие Ввод доходит до экрана на столько же позже → На экране Пинг низкий, а управление ватное и запаздывает
Основной ответственный Команда разработки · Разработка клиента · Совместно Внешние стороны · Внешние стороны
Команда разработки: задачи
Поддержать режим низкой задержки, сократить очередь кадров, дать опцию ограничения FPS чуть ниже частоты обновления, на телефонах включить frame pacing.
Внешние стороны: задачи
Посоветовать игрокам с монитором с переменной частотой обновления ставить ограничение FPS чуть ниже частоты обновления и включить режим низкой задержки в графическом драйвере.
Цифры для ориентира
При 60 Hz каждый кадр в очереди добавляет 16,7 ms. Если CPU работает быстрее GPU или частоты экрана и очередь из трёх кадров (по умолчанию в DirectX 11) заполнена, добавляется 50 ms. При V-Sync с двойной буферизацией кадр, на который ушло 17 ms, ждёт следующего обновления экрана (33,3 ms), а пока на экране ещё раз показывается предыдущий кадр.
На графике
Высоко с самого начала · задержка от ввода до экрана
Где смотреть
Сравнивать в PresentMon MsClickToPhotonLatency и MsAllInputToPhotonLatency (от ввода мышью или клавиатурой до вывода на экран) и DisplayLatency, переключая V-Sync, режим низкой задержки и ограничение FPS. MsPCLatency (от получения ввода ПК до отправки на экран) записывается, только если игра отправляет события PC Latency
Подтверждает
С включённым V-Sync или без ограничения FPS эта задержка растёт на один-два кадра (десятки ms), а в режиме низкой задержки или с ограничением чуть ниже частоты обновления уменьшается. Пинг не меняется
Опровергает
Если задержка внутри ПК низкая, а управление всё равно запаздывает, это «Задержка дисплея, устройств ввода и генерации кадров». Если высокий пинг, дело в сети
Чем проверить
Проверка на стороне игрока
Подробнее
V-Sync (вертикальная синхронизация) выводит новый кадр только в момент, когда монитор обновляет изображение. Разрывы картинки пропадают, но ввод запаздывает на время ожидания этого момента, а если FPS опускается ниже 60, частота скачет между 60 и 30 и появляются микрофризы. Монитор с переменной частотой обновления подстраивает обновление под готовность кадра и сокращает это ожидание. На телефонах происходит то же самое. Если игра на 30 FPS не может равномерно выводить кадры на экран 60 Hz, в среднем выходит 30 FPS, но кадры держатся на экране неравномерно, например 49, 16 и 33 ms, и появляются микрофризы (пример из документации Android для разработчиков). Помогает библиотека Frame Pacing для Android (выравнивание интервалов вывода кадров) или такая же опция движка.
Reduce latency with DXGI 1.3 swap chainsMicrosoft Present блокируется, пока очередь не освободится, и от отрисовки до показа проходит почти на кадр больше. Сократить это помогает swap chain с ожиданием (waitable swap chain)
Frame Pacing libraryAndroid (Google) На экране 60 Hz при отсутствии нового кадра снова показывается предыдущий. Пример игры на 30 FPS, у которой время кадра скачет: 49, 16, 33 ms
PresentMon Capture Application (README-CaptureApplication.md)Intel MsPCLatency (от получения ввода ПК до отправки на экран), MsClickToPhotonLatency (от клика мышью до экрана), MsAllInputToPhotonLatency (от ввода с клавиатуры или мыши до экрана), DisplayLatency (от отправки кадра до вывода на монитор)