Как я могу обработать рендеринг на нескольких мониторах с разной частотой обновления?

8

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

Это применимо, когда игра имеет фиксированный временной интервал и работает в оконном режиме: если один монитор имеет частоту кадров 60,056, а другой имеет частоту кадров 59,94, вертикальная синхронизация в конечном итоге не выполнит свою работу, если Игровое окно перемещается с основного экрана на другой.

Также будет иметь место временное алиасинг, поскольку временной шаг неправильно настроен на другую частоту синхронизации. Как игры обычно решают эту проблему?

NmdMystery
источник
Что именно вы пытаетесь сделать?
Панда Пижама
@PandaPajama Я пытаюсь позволить игроку плавно перемещать окно игры между экранами, чтобы A) не возникало разрывов в любой точке и B) не повторялись кадры в любой точке. Я предполагаю, что логика не зависит от этого, поэтому я уменьшу объем своего вопроса до простого рендеринга.
NmdMystery
Вы будете получать повторные кадры, только если ваша игровая логика работает медленнее, чем ваш код рендеринга. При 60 логических кадрах в секунду и 60,056 графических кадрах в секунду вы будете получать один повторяющийся кадр каждые 18 секунд. Это займет 0,017 секунды и, скорее всего, будет незаметно. Если вы ОПРЕДЕЛЕННО НЕ ДОЛЖНЫ иметь повторяющиеся кадры, ваша игровая логика может иметь гораздо более высокую частоту кадров. Скажи 200fps. Вы потратите много времени на обработку и получите много пропущенных кадров, но вы не будете получать повторяющиеся кадры, что кажется вашей целью.
Панда Пижама
Это, конечно, справедливо для мира с дискретными временными шагами, который охватывает подавляющее большинство игрового кода. Если вы можете последовательно рассчитать состояние вашего игрового мира за произвольное время nс минимальной O(n)сложностью (оптимально O(1)), то ни одно из сказанного мной не применимо. Интерактивные симуляции, как правило, не работают таким образом.
Панда Пижама

Ответы:

5

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

Рассмотрим геймплей как:

var time_per_step = 1 / 60 -- for 60 -logic- steps per second
var prev_time = get_time() -- in seconds

while true do
    var curr_time = get_time()
    while prev_time < curr_time do
        do_step()
        prev_time = prev_time + time_per_step
        // optional: curr_time = get_time()
    end
    draw()
end

Неважно, сколько времени draw()занимают ваши звонки. До тех пор, пока вы do_step()занимаете меньше time_per_step, ваша игровая логика не будет отставать.

Панда Пижама
источник
Как насчет разрыва? Является ли решение для разной частоты обновления до поставщика или есть эффективный способ рендеринга в правильное время на обоих экранах, не испытывая временное наложение на одном из них?
NmdMystery
Это решение совместимо с vSync. Я использовал 60 логических кадровых кадров в секунду, но вы можете увеличивать или уменьшать их столько, сколько хотите.
Панда Пижама
Я хочу сказать, что с этим игровым циклом ваша игровая логика всегда будет соответствовать современным часам. Таким образом, если ваша логика рисования не точно синхронизирована с игровой логикой, этот алгоритм будет повторять или отбрасывать кадры по мере необходимости, чтобы не отставать от часов реального времени. Является ли это приемлемым или нет, решать вам
Panda Pajama
Так что я должен выбирать между повторяющимися кадрами и разрывом, по сути? Других альтернатив нет?
NmdMystery
Ну, но это по определению. Если вам нужны Xлогические кадры в секунду для Yграфических кадров в секунду, X != Yто есть вам придется либо заставить логику придерживаться графики (повторяющиеся и пропущенные кадры), либо графику - логику (разрывая). Другая альтернатива - заставить логику работать на скорости графики, что приведет к временному наложению. Здесь нет ракетостроения.
Панда Пижама