Ограничение частоты кадров

9

Самые успешные конкурентные движки любят id Tech, GoldSrc, Sourceи такие , позволяют ограничения кадровых частоты.

Вы можете играть с 30, с 60, с 99, с 72, с 68 и т. Д. Короче говоря, вы можете ограничить это и контролировать ограничение.

Мне было интересно, как я могу ограничить частоту кадров?

Не интересует код, но теория.

joltmode
источник
Просто из любопытства, какой смысл в этом, кроме освобождения циклов для других процессов?
3Dave
1
@DavidLively, подумайте о ноутбуках, которые очень легко перегреваются при очень высокой частоте кадров, в то время как с пределом 60 кадров в секунду (больше бесполезно в любом случае, даже 60 немного больше, 40 должно делать), они могут контролировать температуру намного лучше.
Для соревновательных игр лучше иметь равномерную частоту кадров вместо пиков от 60 до 100 кадров в секунду, поскольку иногда некоторые действия зависят от частоты кадров и не зависят от времени, равная частота кадров позволяет вам почувствовать эти действия. Кстати, обратите внимание, что если вы включаете VSync, ваша игра всегда имеет максимальный fps, равный вашей частоте обновления, потому что (драйвер позаботится об этом).
Рой Т.
gafferongames.com/game-physics/fix-your-timestep
контракт профессора Фалькена нарушен

Ответы:

7

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

Kylotan
источник
8

Скажем, вы хотите ограничить частоту кадров до 60 кадров в секунду, это означает, что каждый кадр имеет время рендеринга 1/60 с = 16,67 мс (округлено)

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

Один из способов сделать это - использовать:

sleep(waittime)

Однако, поскольку sleep(x)выдает поток за минимальные xмиллисекунды, вы точно не знаете, вернетесь ли вы назад во времени.

Лучшим способом было бы использовать:

while(timediff < 16.67ms){ sleep(0); }

Это возвращает поток и запрашивает контроль как можно скорее.

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

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

Рой Т.
источник
«1/60-е», чтобы быть ясным. :)
Ричард Марскелл - Дракир
Это решение действительно плохо. Если у вас включен vsync или ОС решает что-то сделать, частота кадров будет сильно колебаться.
Тара
@Dudeson Почему это плохо? (это техника, используемая в Quake3 кстати). Если ваш FPS ниже 60, цикл просто пропускается. Таким образом, он поддерживает ваш FPS как можно выше, но не выше 60.
Рой Т.
@RoyT. Интересно ... Откуда вы взяли эту информацию? Из исходного кода? Кроме того, я говорю, что ожидание в цикле - это плохо, потому что именно так я и сделал в своем двигателе, и это причиняет мне много боли. Проблема в том, что когда вы включаете vsync (в драйвере GPU), вы получаете много пропущенных кадров, если вы дополнительно пытаетесь ограничить частоту кадров в вашем коде, потому что ваше уменьшение не будет идеальным для каждого кадра. Я просто говорю о проблемах vsync. Без vsync это не проблема. И я не уверен, что vsync была такой же сделкой в ​​Quake 3 дня, как сегодня.
Тара
@Dudeson, кто-то еще указал мне на это некоторое время назад, потому что я беспокоился о том, чтобы ждать и спать. Теперь я вижу, что вы можете колебаться между 30 кадрами в секунду и 60 кадрами в секунду, когда v-sync включен, если вы слегка его пропускаете. Но я думаю, что это происходит с любой техникой (разве это не то, что FreeSync пытается облегчить). Я думаю, что ограниченная частота кадров по коду или из-за того, что ваш компьютер не может отображать со скоростью 60 кадров в секунду, всегда будет иметь эту проблему :)
Рой Т.