Оптимизация проектов для виртуальной реальности требует своего особенного подхода. Помимо общих вещей, на которые следует обращать внимание при разработке 3D-игр, VR накладывает ряд строгих ограничений. От любого приложения требуется не только практически мгновенный отклик на любое движение игрока (будь то поворот головы или взмах руки), но и обеспечение стабильной частоты кадров, намного превышающей стандартные требования к «классическим» играм любого жанра.
Современные шлемы, такие как Oculus Rift и HTC Vive, поддерживают ряд специальных технологий, которые призваны сглаживать падения производительности. Это должно позволить компенсировать проседания FPS, искусственно повышая частоту кадров; улучшить пользовательский опыт; предоставить немного дополнительной свободы разработчикам конечных продуктов и снизить минимальные системные требования. Но так ли прекрасно все оказывается на практике? Как работают эти технологии и в чем между ними разница? Об этом и пойдет речь в настоящей статье.
Если в обычных играх, зачастую, достаточно 30 FPS, а 60 считается уже прекрасным показателем, то для современных VR-устройств минимальным значением является 90 кадров в секунду (60 FPS для Sony VR на PS4, но официально рекомендуется также 90). Важно добавить, что для комфорта пользователя в шлеме частота кадров должна быть стабильной и не меняться на протяжении всей игры. Кратковременное падение FPS, скажем, до 30 в обычной игре на мониторе или телевизоре, скорее всего, останется вовсе незамеченным, но для человека в VR это будет означать полное разрушение эффекта погружения. Картинка тут же начнет дергаться, отставать от поворотов головы и неприятные ощущения вплоть до укачивания и тошноты игроку обеспечены. Так как же можно хотя бы частично устранить все эти негативные эффекты?
Чередующаяся Репроекция и Синхронный Timewarp
(Interleaved Reprojection and Synchronous Timewarp)
В начале пару слов стоит сказать о близкой к этой теме технологии вертикальной синхронизации кадров. В самом базовом режиме движок игры на каждую итерацию основного цикла выдает один кадр, выводящийся на экран. В зависимости от времени, необходимого для одной итерации, частота кадров будет меняться, т.к. сложность игровой сцены и логики также непостоянна. Если эта частота не совпадает с частотой обновления изображения монитора, это часто приводит к тому, что картинка начинает «сыпаться». Для борьбы с этим эффектом служит вертикальная синхронизация (V-Sync), которая разрешает движку отдавать новый кадр строго после синхроимпульса, частота которого пропорциональна частоте обновления изображения на мониторе (обычно, это 60 Гц).
Таким образом, максимальная частота кадров будет равна 60, но если время подготовки кадра превышает 1/60 секунды, следующий кадр начнет отрисовываться только на каждом втором синхроимпульсе и FPS упадет ровно в 2 раза до 30 кадров в секунду и так далее.
В VR проектах, как уже было сказано выше, такой подход к синхронизации неприменим, т.к. требуется поддерживать стабильно высокую частоту кадров. Но ведь движок точно также может не успевать выдавать 90 изображений в секунду, что же делать? И здесь вступает в дело прием, называемый чередующейся репроекцией. Как только система обнаруживает, что FPS снизился ниже 90, она принудительно снижает частоту кадров игры в 2 раза (до 45) и начинает «дорисовывать» промежуточные кадры самостоятельно, беря за основу предыдущее изображение и путем 2D трансформации поворачивая его на угол, на который за это время повернулась голова игрока.
Таким образом, при генерируемых игрой 45 кадрах в секунду на экран по прежнему выводится 90! Как только движок снова становится способен выдавать 90 кадров в секунду самостоятельно, репроекция автоматически отключается.
Важно отметить, что подобным образом компенсируется именно поворот головы, но не ее перемещение в пространстве. Результат перемещения подобными 2D-трансформациями не получить из-за возникающего эффекта параллакса. Но обычно вращение головой происходит намного чаще и быстрее, чем ее передвижение, так что этот метод достаточно эффективен.
Данный подход был реализован первым и для Oculus Rift и для HTC Vive. Для SteamVR он носит название Interleaved Reprojection, а для Oculus SDK — Synchronous Timewarp.
Наибольший минус заключается в том, что в момент включения/выключения репроекции пользователь замечает ощутимое «вздрагивание» и изменение плавности картинки. К тому же, даже при небольшом снижении производительности игры мы сразу получаем падение реальной частоты кадров в 2 раза, а как бы хорошо не был реализован алгоритм 2D трансформации, он не может обеспечить ту же точность и плавность картинки, как сам движок. Поэтому в дальнейшем в обоих SDK этот метод был усовершенствован.
Асинхронная Репроекция и Timewarp
(Asynchronous Reprojection and Timewarp)
Первыми этот подход реализовали в компании Oculus под названием Asynchronous Time Warp (ATW), и он же является основным для Oculus Rift с момента официального релиза. В целом, идея та же — дополнять последовательность кадров, чтобы поддерживать стабильные 90 FPS, но сам процесс дополнения выделяется в отдельный, независимый от основного рендера, поток. Непосредственно перед каждым синхроимпульсом ATW выдает на экран либо успешно сгенерированный движком кадр, либо результат репроекции предыдущего кадра, если новый кадр еще не готов. Таким образом, возможны два сценария:
- движок успел отрендерить кадр — этот кадр выдается на экран как есть и попадает в буфер ATW;
- движок не успел отрендерить кадр — незаконченный кадр «откладывается» до следующего тика VSync, а на экран выдается результат 2D-репроекции предыдущего кадра из буфера ATW.
Это дает возможность не ограничивать искусственно движок игры и позволяет ему генерировать кадры с той частотой, на которую он максимально способен. При этом ATW «подстраховывает» игру, компенсируя падения производительности репроекцией строго в те моменты, когда она нужна. В результате отсутствует заметное «вздрагивание» картинки при изменении режима репроекции, отбрасывается намного меньше «полезных» кадров движка, и в целом пользователь ощущает все намного более естественно.
Для разработчиков игр поддержка этой технологии не стоит ничего — она просто работает с любым VR-приложением. Но со стороны SDK, ОС и производителей видеокарт реализация подобного метода потребовала изрядных дополнительных совместных усилий. Современное железо и софт для GPU оптимизированы для очень высокой пропускной способности, но не для преемственности кадров, необходимой для работы ATW. Компании Oculus пришлось тесно сотрудничать с Microsoft, NVidia и AMD, чтобы адаптировать микрокод процессора и драйвер ядра GPU для лучшей поддержки ATW. Данные расширения получили название AMD’s Liquid VR и NVIDIA’s VRWorks.
В конце 2016 года Valve также представила свою версию данного метода, который назвали Asynchronous Reprojection. Однако, по словам самой компании, получилось все не так однозначно: согласно ее исследованиям, несмотря на уменьшение конкретных рывков и «вздрагиваний» при переключении репроекции, периодически хаотично возникающие «ложные» кадры, полученные в результате 2D-трансформаций, также ощущаются игроками как раздражающий фактор. Все достаточно индивидуально, поэтому эту функцию можно, при желании, отключить в настройках SteamVR, вернувшись к классической синхронной репроекции.
Асинхронный Spacewarp
(Asynchronous Spacewarp)
Как уже было сказано, все описанные методы способны дополнять последовательность кадров, компенсируя лишь повороты головы игрока. Но что если игрок еще и сдвинулся в сторону? Изменится позиция обзора и из-за эффекта параллакса обычных 2D-трансформаций будет попросту недостаточно для генерации более-менее достоверных промежуточных кадров. В результате, если игрок в момент проседания FPS будет активно двигать головой, целый «мир» вокруг по его ощущениям будет дергаться и дрожать, разрушая эффект погружения. Для решения этой проблемы в Oculus разработали еще одну технологию, работающую поверх асинхронного timewarp, и назвали ее Spacewarp (от англ. space — пространство) или ASW.
В отличии от timewarp, тут при генерации «промежуточных» кадров учитываются движения персонажа, камеры, VR-контроллеров и самого игрока. ASW обрабатывает эффект параллакса, создающийся при смещении точки обзора и, как результат, ближних объектов относительно дальних. Для этого используется дополнительный буфер глубины последнего отрендеренного кадра, по которому ASW понимает какие объекты находятся на ближнем плане, а какие на дальнем. В результате, на «промежуточном» кадре становится возможным не только сместить точку обзора, согласно движениям игрока, но и сымитировать перемещение одних предметов относительно других.
Разумеется, система не сможет узнать, что находится за той областью, которая была перекрыта ближними объектами, поэтому соответствующие зоны будут, по сути, сгенерированы из окружающей обстановки, путем ее «растяжения». Это наглядно иллюстрирует следующая картинка:
ASW неразрывно связан с ATW и каждый из них выполняет свою задачу. Timewarp идеален для статичных изображений окружающей обстановки, находящейся на некотором расстоянии от зрителя, а spacewarp, в свою очередь, отвечает за движущиеся объекты рядом с игроком.
Стоит также отметить, что поддержка ASW присутствует только в Windows 8 и более поздних версиях. А наилучшая реализация имеется только в Windows 10, т.к. именно в ней Microsoft была проведена дополнительная работа в данном направлении. Аналога данной технологии для HTC Vive пока заявлено не было.
Выводы по технологиям
Репроекция, ATW и ASW, безусловно, облегчают жизнь как разработчикам, так и конечным пользователям, позволяя сделать виртуальную реальность более похожей на реальную жизнь и сглаживая огрехи 3D-рендеринга, но не стоит рассматривать их как панацею. В теории может показаться, что эти методы позволяют снизить планку производительности до 45 кадров в секунду или даже ниже, но на практике это далеко не всегда так. В зависимости от того, в каком именно виртуальном мире находится игрок, какие события там происходят и как двигается он сам, все методы искусственного «дополнения» видеопотока могут вызывать различные артефакты, рывки и «дрожание» картинки, которое ощущается пользователем, зачастую, на подсознательном уровне.
Со стороны пользователя, если вы только начинаете использовать VR-шлем, будь то Oculus Rift или HTC Vive, — оставьте все системы помощи включенными по умолчанию. Это особенно важно, если ваша система не самая производительная. Наиболее вероятно, что именно в таком варианте ваш опыт погружения в виртуальную реальность будет самым лучшим, а круг поддерживаемого контента расширится. Однако, все люди индивидуальны, а когда мы говорим о VR, это верно вдвойне. То, что комфортно для одного, может вызывать стойкое отторжение у другого. Поэтому, если вы замечаете, что вроде бы все плавно, но иногда что-то смущает, что-то при движении не так, как должно быть, возникает ощущение укачивания — попробуйте отключить последовательно ASW, затем ATW и вернуться к классической репроекции. Возможно, это именно то, что вам нужно.
Со стороны разработчиков же главный совет один — не полагайтесь на то, что современные методы репроекции позволят вам уделять меньше внимания оптимизации и решат все проблемы со стабильной частотой кадров. 90 FPS — это по-прежнему «золотой стандарт», к которому вы должны стремиться, не забывая оставлять запас под более слабые системы и наиболее тяжелые моменты игры. Но все равно приятно осознавать, что в любой непредвиденный момент подобные технологии сгладят для вашего пользователя «острые углы», скроют какие-то огрехи и позволят полноценно насладиться погружением в виртуальные миры!
Автор: Roland_D