Hor+vert+ FOV, или адаптивное поле обзора

в 8:29, , рубрики: game development, Анимация и 3D графика, Мобильный веб, портрет, метки: ,

Hor+vert+ FOV, или адаптивное поле обзора

Привет всем!

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

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

И назвал я это Hor+vert+ FOV.

В чём была проблема

Так как у моего десктопа широкоэкранный монитор, я изначально решил использовать Hor+ FOV вместо Vert-, несмотря на то, что в Quake используется Vert-, поскольку казалось, что я смотрю на мир через увеличительное стекло.

Quake с Vert- FOV на широкоэкранном мониторе.
Hor+vert+ FOV, или адаптивное поле обзора

Hor+ работал нормально до тех пор, пока у меня не появился планшет. Всё выглядело отлично в пейзажной ориентации, но в портретной был уже не эффект лупы, а просто тесно.

Quake с Hor+ FOV в портретной ориентации.
Hor+vert+ 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+.
Hor+vert+ FOV, или адаптивное поле обзора
Портретная ориентация — используется Vert+.
Hor+vert+ FOV, или адаптивное поле обзора

Как вы видите, и эффекта лупы здесь нет, и обзор хороший.

Но есть одна маленькая проблема.

Ошибка и её решение

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

Данная проблема присутствует только в том случае, когда используется Vert+ — в Hor+ такой эффект не наблюдается.

Так как модель оружия в Quake рисуется отдельно от остальных моделей, ничто не мешает нам переключиться из Vert+ на Hor+ перед тем, как рисовать оружие, а после этого — обратно.

Мир рисуется в Vert+, а оружие — в Hor+.
Hor+vert+ FOV, или адаптивное поле обзора

Ошибка исправлена.

Итог и заключение

В итоге получилось так, как на первом скриншоте в этом посте.

Hor+vert+ FOV, или адаптивное поле обзора

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

Спасибо за прочтение.

Автор: SiPlus

Источник


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js