Привет всем!
Сегодня, когда я тестировал свой порт Quake на планшете, я заметил, что в портретной ориентации смотреть демки не очень приятно из-за узкого поля обзора.
Поэтому я решил придумать очень простой, но выглядящий хорошо (по моему мнению) как в портретной, так и в пейзажной ориентации, способ, как это исправить.
И назвал я это Hor+vert+ FOV.
В чём была проблема
Так как у моего десктопа широкоэкранный монитор, я изначально решил использовать Hor+ FOV вместо Vert-, несмотря на то, что в Quake используется Vert-, поскольку казалось, что я смотрю на мир через увеличительное стекло.
Quake с Vert- FOV на широкоэкранном мониторе.
Hor+ работал нормально до тех пор, пока у меня не появился планшет. Всё выглядело отлично в пейзажной ориентации, но в портретной был уже не эффект лупы, а просто тесно.
Quake с Hor+ FOV в портретной ориентации.
Решение
А решение оказалось простейшим.
Вместо того, чтобы использовать какой-либо из двух типов FOV, я решил совместить эти два типа.
Так как Quake был разработан для мониторов с соотношением сторон 4:3, я стал использовать это соотношение как базовое для переключения между двумя режимами.
Если соотношение сторон больше 4:3 (экран широкий) — используется Hor+.
Если соотношение сторон меньше или равно 4:3 (экран узкий или близок к квадратному) — используется Vert-.
Но так как задачей было подогнать FOV под узкие экраны, то это значит, что чем уже экран, тем больше должно быть видно. Поэтому для нас Vert- фактически превратился в Vert+.
Реализация такого способа занимает одну-единственную проверку на условие.
Приведу весь код реализации данного способа из WebQuake.
if ((vrect.width * 0.75) <= vrect.height)
{
R.refdef.fov_x = SCR.fov.value;
R.refdef.fov_y = Math.atan(vrect.height / (vrect.width / Math.tan(SCR.fov.value * Math.PI / 360.0))) * 360.0 / Math.PI;
}
else
{
R.refdef.fov_x = Math.atan(vrect.width / (vrect.height / Math.tan(SCR.fov.value * 0.82 * Math.PI / 360.0))) * 360.0 / Math.PI;
R.refdef.fov_y = SCR.fov.value * 0.82;
}
Объяснение:
- SCR.fov — консольная переменная, обозначающая горизонтальный FOV при соотношении сторон 4:3 (идеальном соотношении сторон для Quake).
- Если соотношение сторон меньше или равно 4:3, используем Vert+. Если нет, используем Vert-.
- В случае с Vert+, берем горизонтальный FOV из консольной переменной, а вертикальный — рассчитываем по известному алгоритму.
- В случае с Hor+, берем вертикальный FOV из консольной переменной, а горизонтальный — рассчитываем.
- 0.82 — отношение вертикального FOV к горизонтальному при соотношении 4:3. Чтобы получить вертикальный FOV из консольной переменной, умножаем значение переменной на эту константу.
Что из этого получилось:
Пейзажная ориентация — используется Hor+.
Портретная ориентация — используется Vert+.
Как вы видите, и эффекта лупы здесь нет, и обзор хороший.
Но есть одна маленькая проблема.
Ошибка и её решение
Как видно по предыдущему скриншоту, модель оружия находится слишком далеко от игрока.
Данная проблема присутствует только в том случае, когда используется Vert+ — в Hor+ такой эффект не наблюдается.
Так как модель оружия в Quake рисуется отдельно от остальных моделей, ничто не мешает нам переключиться из Vert+ на Hor+ перед тем, как рисовать оружие, а после этого — обратно.
Мир рисуется в Vert+, а оружие — в Hor+.
Ошибка исправлена.
Итог и заключение
В итоге получилось так, как на первом скриншоте в этом посте.
Может быть, данная техника и не нова (хотя я пока ещё не встречал ни одной игры, использующей что-то подобное), но она имеет большое значение. Использование адаптивного FOV очень важно в эпоху веб-приложений и мобильных устройств, так как окно браузера может иметь любую прямоугольную форму, а смартфоны и планшеты работают как в горизонтальной, так и в вертикальной ориентации.
Спасибо за прочтение.
Автор: SiPlus