В чем смысл независимого рендеринга обновлений в игровом цикле?

В игровых циклах есть десятки статей, книг и дискуссий. Тем не менее, я довольно часто сталкивался с чем-то вроде этого:

в то время как (бег)
{
    ProcessInput ();
    в то время как (isTimeForUpdate)
    {
        Обновить();
    }
    рендеринга ();
}

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

74 голоса | спросил Sam 10 42016vEurope/Moscow11bEurope/MoscowThu, 10 Nov 2016 01:04:52 +0300 2016, 01:04:52

5 ответов


110

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

1. Проблема: устройства работают с разной скоростью

Попробуйте сыграть старую игру DOS на современном ПК, и она работает неиграбельно быстро - просто размытие?

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

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

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

Решающее решение здесь - заблокировать скорость, с которой мы обновляем состояние геймплея. Таким образом, мы можем гарантировать, что результаты всегда будут одинаковыми.

2. Итак, почему бы не просто заблокировать частоту кадров (например, используя VSync) и все еще запускать обновления состояния геймплея & рендеринг в режиме блокировки?

Это может работать, но не всегда приемлемо для аудитории. Было долгое время, когда бег с твердым 30 fps считался золотым стандартом для игр. Теперь игроки обычно ожидают 60 кадров в секунду в качестве минимального бара, особенно в многопользовательских играх, а некоторые старые названия теперь выглядят заметно изменчивыми, поскольку наши ожидания изменились. В частности, есть вокальная группа игроков ПК, которые вообще возражают против блокировки кадров. Они много заплатили за свои аппаратные средства, испытывающие недостаток, и хотят иметь возможность использовать эту вычислительную мускул для наиболее плавного, наивысшего качества, на которое она способна.

В VR, в частности, частота кадров корона, и стандарт продолжает ползти вверх. В начале недавнего возрождения VR игры часто проходили около 60 кадров в секунду. Теперь 90 более стандартно, а harware, как PSVR, начинает поддерживать 120. Это может продолжать расти. Итак, если игра VR ограничивает частоту кадров до того, что можно сделать & принятый сегодня, он может быть оставлен как аппаратное обеспечение, и ожидания развиваются дальше.

(Как правило, будьте осторожны, когда говорят, что «игроки не могут воспринимать что-либо быстрее, чем XXX», поскольку оно обычно основано на определенном типе «восприятия», как распознавание кадра в последовательности. Восприятие непрерывности движения обычно гораздо более чувствительный.)

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

Это может быть особенно проблематично, если проблемы с производительностью появляются в конце разработки, когда все ваши существующие системы построены и amp; настроенный на предположение о том, что теперь вы не всегда можете ударить. Развязывание обновления & темпы рендеринга дают большую гибкость для решения проблемы изменчивости производительности.

3. Не обновляется ли с фиксированным timestep те же проблемы, что и (2)?

Я думаю, что это мясо оригинального вопроса: если мы отделим наши обновления и иногда будем рендерить два кадра без обновлений состояния игры между ними, то это не то же самое, что делать с стоп-стопом при более низкой частоте кадров, так как нет видимое изменение на экране?

На самом деле существует несколько разных способов использования игр с эффектом развязки этих обновлений:

a) Скорость обновления может быть быстрее , чем отображаемая частота кадров

Как отмечает Тейкенн в другом ответе, физика, в частности, часто переходит на более высокую частоту, чем рендеринг, что помогает свести к минимуму ошибки интеграции и дать более точные коллизии. Таким образом, вместо того, чтобы иметь 0 или 1 обновления между выделенными кадрами, у вас может быть 5 или 10 или 50.

Теперь рендеринг проигрывателя со скоростью 120 кадров в секунду может получить 2 обновления за кадр, в то время как проигрыватель на аппаратном рендеринге с более низким разрешением при 30 кадрах в секунду получает 8 обновлений на кадр, и обе их игры работают в одном и том же игровом режиме - тики в реальном времени - вторая скорость. Лучшее оборудование делает его более гладким, но не радикально изменяет работу игрового процесса.

Здесь существует риск, что если скорость обновления не соответствует частоте кадров, вы можете получить «частоту биений» между два . Например. у большинства кадров у нас достаточно времени для 4 обновлений состояния игры и немного осталось, тогда каждый так часто мы имеемдостаточно сэкономить до 5 обновлений в кадре, делая небольшой прыжок или заикание в движении. Это можно решить ...

b) Интерполяция (или экстраполяция) состояния игры между обновлениями

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

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

c) Добавление гладкости к изменениям без игрового процесса

Даже без интерполирования состояния геймплея мы все равно можем получить некоторую гладкость.

Чисто визуальные изменения, такие как анимация персонажей, системы частиц или VFX и элементы пользовательского интерфейса, такие как HUD, часто обновляются отдельно от фиксированного временного времени состояния игры. Это означает, что если мы будем отслеживать состояние игрового процесса несколько раз за кадр, мы не платим их стоимость с каждым тиком - только на финальном этапе рендеринга. Вместо этого мы масштабируем скорость воспроизведения этих эффектов в соответствии с длиной кадра, поэтому они играют так же плавно, как позволяет частота кадров рендеринга, не влияя на скорость игры или справедливость, как описано в (1).

Движение камеры тоже может сделать это - особенно в VR, мы будем иногда показывать один и тот же кадр более одного раза, но перепрограммировать он должен учитывать движение головы игрока в районе , поэтому мы можем улучшить воспринимаемую латентность и комфорт, даже если мы не можем изначально сделать все так быстро. Некоторые игровые потоковые системы (где игра работает на сервере, а проигрыватель работает только с тонким клиентом) также используют версию этого.

4. Почему бы просто не использовать стиль (c) для всего? Если это работает для анимации и пользовательского интерфейса, разве мы не можем просто масштабировать наши состояния состояния игрового процесса в соответствии с текущей частотой кадров?

Да * это возможно, но нет, это не просто.

Этот ответ уже немного длинный, поэтому я не буду вдаваться в все детали, просто краткое изложение:

  • Умножение на deltaTime работает, чтобы настроить изменения переменной длины для изменения linear (например, движение с постоянной скоростью, обратный отсчет таймера или прогресс вдоль временной шкале анимации)

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

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

Таким образом, в общем случае для игры средней сложности, поддержания согласованного поведения & справедливость полностью с помощью deltaTime масштабирования находится где-то между очень сложными & поддержание интенсивного до совершенно неосуществимого.

Стандартизация скорости обновления позволяет гарантировать более согласованное поведение в различных условиях , часто с более простым кодом.

Сохранение этой скорости обновления отделяется от рендеринга дает нам гибкость , чтобы контролировать гладкость и производительность опыта без изменения логики игрового процесса .

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

ответил DMGregory 10 42016vEurope/Moscow11bEurope/MoscowThu, 10 Nov 2016 03:56:55 +0300 2016, 03:56:55
9

Другие ответы хороши и говорят о том, почему игровой цикл существует и должен быть отделен от цикла визуализации. Однако, что касается конкретного примера «Зачем делать кадр, если никаких изменений не было?» Это действительно сводится к аппаратным средствам и сложности.

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

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

Конструкция аппаратного обеспечения и т. д. в значительной степени оптимизирована для текущих соглашений, а конечный автомат - хорошая модель для начала.

ответил Waddles 10 42016vEurope/Moscow11bEurope/MoscowThu, 10 Nov 2016 07:28:57 +0300 2016, 07:28:57
6

Рендеринг обычно является самым медленным процессом в игровом цикле. Люди нередко замечают разницу в частоте кадров быстрее 60, поэтому часто менее важно тратить время на рендеринг быстрее, чем это. Тем не менее, есть и другие процессы, которые выиграют от более высоких скоростей. Физика - одна. Слишком большое изменение в одном цикле может привести к сбоям объектов в стенах. Могут быть способы обойти простые ошибки столкновений при больших приращениях, но для множества сложных физических взаимодействий вы просто не получите такую ​​же точность. Если цикл физики запускается чаще, хотя вероятность сбоев меньше, так как объекты могут перемещаться с меньшими приращениями, не будучи визуализированными каждый раз. Больше ресурсов идет к чувствительному физическому движку и меньше тратится на рисование большего количества кадров, которые пользователь не может видеть.

Это особенно важно в играх с более интенсивной графикой. Если в каждом игровом цикле был один рендер, а у игрока не было самой мощной машины, в игре могут быть очки, где fps падает до 30 или 40. Хотя это все равно будет не совсем ужасной частотой кадров, игра начнет становиться довольно медленной, если мы попытаемся сохранить каждую физическую изменчивость достаточно малой, чтобы избежать срывов. Игрок будет раздражен тем, что его персонаж идет только на половину нормальной скорости. Однако, если скорость рендеринга была независимой от остальной части цикла, игрок мог бы оставаться на фиксированной скорости ходьбы, несмотря на падение частоты кадров.

ответил tyjkenn 10 42016vEurope/Moscow11bEurope/MoscowThu, 10 Nov 2016 02:15:41 +0300 2016, 02:15:41
4

Конструкция, подобная той, которая есть в вашем вопросе, может иметь смысл, если подсистема рендеринга имеет некоторое понятие "прошедшее время с момента последнего рендеринга .

Рассмотрим, например, подход, в котором положение объекта в игровом мире представлено с помощью фиксированных координат (x, y, z) с подходом, который дополнительно сохраняет текущий вектор движения (дх, ду, дг). Теперь вы можете написать свой игровой цикл, чтобы изменение position должно происходить в методе update, но вы также могли бы его спроектировать так, чтобы смена < em> перемещение должно происходить во время update. При последнем подходе, хотя ваше игровое состояние фактически не изменится до следующего update, функция render, которая вызывается на более высокой частоте, уже может нарисовать объект в слегка обновленной позиции. Хотя это технически приводит к расхождению между тем, что вы видите, и тем, что представлено внутри, разница достаточно мала, чтобы не иметь значения для большинства практических аспектов, но при этом анимации выглядят намного более гладкими.

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

ответил Thomas 10 42016vEurope/Moscow11bEurope/MoscowThu, 10 Nov 2016 12:04:51 +0300 2016, 12:04:51
4

В дополнение к другим ответам ...

Проверка изменения состояния требует значительной обработки. Если для проверки изменений требуется аналогичное (или более!) Время обработки, по сравнению с фактической обработкой, вы действительно не улучшили ситуацию. В случае рендеринга изображения, как говорит @Waddles, видеокарта действительно действительно помогает повторять ту же самую тупую вещь снова и снова, и более дорого проверить каждый фрагмент данных для изменений, чем это просто передать его на видеокарту для обработки. Кроме того, если рендеринг - это игровой процесс, то действительно маловероятно, чтобы экран not изменился в последнем тике.

Вы также предполагаете, что рендеринг занимает значительное время процессора. Это очень зависит от вашего процессора и видеокарты. В течение многих лет основное внимание уделялось разгрузке постепенно более сложной работы по рендерингу на графическую карту и уменьшению ввода рендеринга, необходимого от процессора. В идеале вызов процессора render () должен просто настроить передачу DMA и все. Получение данных на графическую карту затем делегируется контроллеру памяти, и создание изображения передается на графическую карту. Они могут делать это в свое время, в то время как процессор параллельно продолжает работу с физикой, движком игрового процесса и всеми другими вещами, которые процессор делает лучше. Очевидно, что реальность намного сложнее, но возможность разгрузить работу в другие части системы также является значительным фактором.

ответил Graham 10 42016vEurope/Moscow11bEurope/MoscowThu, 10 Nov 2016 19:30:30 +0300 2016, 19:30:30

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132