Нюансы разработки для Apple Vision Pro

Наша команда Unity занимается разработкой VR проектов. Недавно на этот рынок вышла Apple с новым устройством – Vision Pro. Про него расскажем в сегодняшней статье.

Как правило, основная платформа, для которой мы разрабатываем — это Oculus Quest (Meta* Quest). Больший объём работ мы делаем для шлемов Oculus Quest 2 и 3. Unity мы используем как основной движок для создания приложений. Он хорошо подходит для мобильной разработки, в том числе и для Oculus Quest.

А сейчас Apple зашли на рынок шлемов виртуальной реальности с Vision Pro — отдельным, уникальным устройством со своей операционной системой visionOS. Получается, что это совсем новая платформа, под которую нужно разрабатывать. Unity хотят идти в ногу со временем, поэтому совместно с Apple они подготовили инструменты, чтобы разработчики уже сейчас могли делать приложения. Но не без трудностей и нюансов, о которых мы вам расскажем далее.

Vision Pro и Oculus Quest

Изображение 1 – Vision Pro и Oculus Quest

Стоит отметить, что Apple Vision Pro достаточно дорогой девайс и вышел он совсем недавно. Малое количество специалистов имеют возможность разрабатывать для этого шлема — мы решили воспользоваться этой возможностью одними из первых.

О нюансах разработки для Apple Vision Pro расскажем на примере нашего приложения смешанной реальности Dog MR, изначально созданного под Meta* Quest. В конце статьи мы подробнее опишем требования Apple Vision Pro к основным программам и инструментам.

Dog MR

Изображение 2 – Dog MR

Об Apple Vision Pro

У Apple Vision Pro и в системе существует 3 типа приложений:

  1. Windowed (оконные) — приложения, которые запускаются в плоском окне. По сути, это обычные iOS приложения.
  2. Fully Immersive VR — полноценное приложение виртуальной реальности, в котором пользователь видит только виртуальный мир и взаимодействует исключительно с ним.
  3. PolySpatial MR — приложение дополненной реальности, в котором пользователь видит и реальный мир, и виртуальные объекты.

Важно отметить, что приложение может быть только одного типа — он задаётся в настройках проекта, и не может меняться в рантайме.

Нюансы разработки для Apple Vision Pro

Распознавание речи

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

На Apple Vision эта библиотека не работает. Её автор ещё не подготовил релиз под эту платформу. И альтернатив на данный момент нет. Чтобы реализовать данную фичу, мы решили использовать нативную библиотеку распознавания речи (она же используется для работы Siri).

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

Второй проблемой оказалось то, что Unity некорректно обрабатывает системные события сворачивания/закрытия приложения, из-за чего нативная библиотека распознавания ломается. Пока что решения этой проблемы мы не смогли найти, поэтому ждём обновлений от Unity и Apple.

Использование шейдеров

Для настройки визуальных свойств объектов в движках, таких как Unity, используются шейдеры — это микропрограммы, которые отвечают за то, как объект рисуется на экране. Можно разделить их на две группы: встроенные (поставляются в составе движка) и кастомные (написанные или модифицированные непосредственно нами). Кастомные шейдеры, в свою очередь, можно разделить на две группы по методу их создания: написанные кодом, и созданные с помощью инструмента визуального программирования Shader Graph.

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

В процессе разработки выяснилось, что некоторые фичи встроенных шейдеров компилируются некорректно. И объекты визуально значительно отличаются от того, что мы ожидаем увидеть. Например, есть проблемы с интерпретацией Metallic/Roughness текстуры, а также с прозрачными объектами типов Fade или Transparent. В нашем случае материал на собаке отображается не так красиво, как на других платформах. И, к сожалению, исправить эту, казалось бы, очевидную проблему достаточно трудно или невозможно вовсе.

Проблемы с прозрачными объектами

Изображение 3 – Проблемы с прозрачным шейдером

Для кастомных шейдеров есть обязательное требование. Они должны быть созданы с помощью вышеупомянутого инструмента Shader Graph. Поскольку мы перенесли существующий проект, в котором уже были кастомные шейдеры, нам пришлось переписывать их на эту систему. Если таковых в проекте много, то это может стать проблемой, так как переносить в формат Shader Graph не всегда просто.

Пользовательский ввод

Для управления системой ввода в Apple Vision используется трекинг направления взгляда и трекинг жестов рук. В частности, для клика используется кратковременный пинч. В Unity для управления вводом существует специальный Input Module, который является прослойкой между системным вводом OS и нашим приложением.

Сейчас поддержка visionOS в существующем Unity Input Module сильно лимитирована. Поэтому большинство стандартных вещей, которые обычно работают по умолчанию, приходится создавать с нуля. А отсутствие подробной документации и открытых исходных кодов сильно усложняет процесс.

Забавный факт: казалось бы, такие тривиальные задачи, как позиционирование UI панели и ее ориентация на юзера, требуют использования специальных API команд.

Анимации

В нашем проекте есть анимированный персонаж — собака. В современных движках, в частности, в Unity, существует система оптимизации таких объектов. Когда персонаж находится вне поля зрения камеры, анимации пересчитываются и обновляются только частично, чтобы высвободить ресурсы CPU и GPU. Когда же объект вновь попадает в область видимости, анимации начинают работать в полном объеме. Обычно эта оптимизация включена по умолчанию.

Из-за специфики рига камер в Apple Vision, Unity не может правильно определить, попадает объект в поле зрения или нет. Из-за этого анимированные персонажи выглядят некорректно. Выключение оптимизации решает проблему. В нашем случае был всего один анимированный персонаж, поэтому подобное решение приемлемо. Но возможны ситуации, когда таких объектов много и данная проблема может стать очень серьезной.

Звук

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

В Unity система, отвечающая за трёхмерный звук, называется Spatialized Sound System. Там также есть возможность использования сторонних систем, разработанных под конкретные платформы. У Meta* Quest, например, есть своя Spatialized Sound System.

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

Триггеры

Чтобы распознать пересечения некоторых объемов в игровых движках есть специальный инструмент — триггеры. В нашем проекте триггеры используются для того, чтобы собака закрывала рот, когда пользователь подносит руку. Это действует с помощью физических сфер вокруг головы животного. Когда рука входит в сферу, срабатывает триггер и собака закрывает рот, чтобы пользователь не чувствовал угрозы укуса.

Собака хочет съесть палец

Изображение 4 – Собака хочет съесть палец

В Apple Vision триггеры не поддерживаются, что создает проблему. Один из вариантов решения заключается в проверке расстояния от руки до головы в каждом кадре, но это неэффективно. В свою очередь, физический движок Unity оптимизирован для быстрого выполнения множества триггеров. В нашем случае они использовались в одном месте, поэтому мы убрали их и каждый раз проверяем расстояние от руки до собаки.

Получение данных о реальном мире

Чтобы опыт присутствия в дополненной реальности был эффективным, интересным и реалистичным, нам важно получать в приложении данные о реальном мире, чтобы виртуальные объекты могли корректно взаимодействовать с существующими. Например, мы планируем расположить виртуальный объект на реальном столе или хотим, чтобы он физически правильно сталкивался со стенами настоящей комнаты. Основной тип таких данных — это отсканированное окружение в виде треугольников («мешей»).

Дополнительной информацией может быть тип объекта: стол, стул и т.д.
Для сбора и обработки таких данных шлем использует камеры и лидар. Затем информация передается в Unity, и потом мы можем использовать их в нашем приложении.

Apple Vision Pro имеет ряд особенностей, которые касаются того, как и какие данные он передает в Unity. Первым и наиболее важным отличием является то, что генерация передачи данных происходит в реальном времени. Информация о «мешах» постоянно обновляется и они меняются. А для таких объектов в движке нельзя применять коллизии. Соответственно, мы не можем создать, например, виртуальный мяч, который будет отскакивать от реальных стен.

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

Окклюзии в смешанной реальности

Окклюзия в смешанной реальности — это процесс, при котором объекты, стоящие ближе к зрителю, перекрывают те, что находятся дальше. Это позволяет создать правдоподобное взаимодействие между виртуальными и реальными объектами. Например, если вы проведёте рукой перед камерой, то трехмерный объект, находящийся дальше, не будет отображаться поверх неё.

В MR-шлемах мы рендерим виртуальные объекты поверх изображения реального мира, полученного с камеры устройства. Если системы окклюзии не включены, то все цифровые предметы будут отображаться поверх существующих, независимо от их расположения. Например, собака не будет перекрываться столом.

В Meta* Quest используется плагин Depth API, который с помощью камеры глубины позволяет корректно отображать реальные объекты перед виртуальными. Технология от Apple Vision позволяет прекрасно перекрывать оконные приложения, но, к сожалению, совсем не работает в режиме полноразмерного MR.

В Unity для Apple Vision используется ARFoundation, который создает плоскости на основе данных с камеры (пол, стол, стена и т.д.). Мы можем навесить на них специальный материал, который делает предметы невидимыми, но не позволяет рендерить объекты за ними.

Однако из-за динамической генерации плоскостей может происходит перерасчёт. Из-за этого, например, когда мы прикрепляем флаг к плоскости и подходим ближе, его часть может пересекаться с реальной стеной.

Флаг утонул в стене

Изображение 5 – Флаг утонул в стене

А для рук мы воспользовались лайфхаком: мы использовали пакет от Unity, позволяющий отслеживать изменения жестов рук, настроили перемещения для 3D модели руки и использовали на ней те же материалы, что применяли к плоскостям.

Работа с состоянием приложения

В Apple Vision наблюдается баг: при нажатии на крестик в статус-баре для закрытия приложения полной смешанной реальности (unbounded), окна меню остаются на экране, превращаясь в серые и неактивные, а приложение просто сворачивается. В это же время bounded приложения закрываются полностью. Это создает неудобства для пользователей: при повторном запуске приложения вместо старта «с нуля», мы видим то же самое состояние, что было и до выхода.

Интерфейс взаимодействия

На Oculus Quest 3 мы изначально внедрили возможность давать команды собаке с помощью голоса и жестов. Реализация не подразумевала переход на новые платформы и поэтому использовала жесты, предоставляемые Meta* в SDK.

Взаимодействие жестами

Изображение 6 – Взаимодействие жестами

Когда появился Apple Vision, нам пришлось переделать систему управления. Мы переключились на решение, предоставляемое Unity, которое позволяет интегрировать алгоритм управления руками, предложенный Apple, в тот, что мы видим в Unity. Это позволило создать более универсальную и гибкую систему, способную работать на разных устройствах. Таким образом, мы обеспечили совместимость нашего приложения с новыми технологиями и устройствами, сохраняя удобство управления для пользователя.

Контроллеры

В другом нашем проекте, разработанном для Oculus Quest, мы использовали контроллеры. Они позволяли пользователю взаимодействовать с виртуальными объектами: дёргать рычаги, вращать предметы и выполнять другие действия. Контроллеры обеспечивали удобный и точный способ взаимодействия с виртуальной средой.

Однако в Apple Vision Pro контроллеры отсутствуют. Это создаёт вызов: необходимо разработать способ, при котором рука пользователя сможет виртуально «схватить» объект. Для решения этой задачи нам предстоит создать собственную систему интеракций. Она должна учитывать особенности Apple Vision и использовать возможности Unity для интеграции управления руками.

Это требует разработки новых методов для обработки жестов, которые будут интерпретировать и превращать их в действия в виртуальной среде. Таким образом, переход от контроллеров Oculus Quest к бесконтактному взаимодействию в Apple Vision Pro требует значительных изменений в нашей системе интеракций, но открывает новые возможности для создания более естественного пользовательского опыта.

Документация

Так как платформа visionOS достаточно молодая, документация как по самой системе, так и по инструментам разработки, связанными с ней, не всегда содержит всю необходимую информацию. Многие вещи приходится изучать и понимать на основе доступных, в том числе сторонних, примеров и зачастую заниматься реверс-инжинирингом.

Требования шлема Apple Vision Pro и его особенности

Для компиляции и сборки проекта требуется Mac с процессором M1, M2, M3 (Apple silicon).
Как и с обычными iOS приложениями, XCode-проект можно собрать в Unity даже на Windows, но необходимо иметь MacOS на процессоре Apple Silicon, чтобы собрать само приложение и запустить его на устройстве. Unity Cloud Build — сервис от Unity по автоматизации сборки и деплоя приложений. На данный момент они используют компьютеры Mac на процессорах Intel. Поэтому UCB пока не поддерживает сборку проектов под visionOS.

Для разработки требуется лицензия Unity Pro.
Для работы Unity с visionOS используется плагин PolySpatial, доступный только в Pro версии. Если на компьютере стоит Personal версия — плагин самоудаляется и проект невозможно запустить. К тому же, visionOS не поддерживает Splash Screen, который в Personal версии отключить нельзя.

Версия Unity от 2022.3.19f1 и новая версия Xcode, поддерживающая visionOS SDK.

Плюсы Apple Vision Pro

  • Для дистрибуции используется TestFlight, как и для любого iOS приложения
  • Можно использовать нативный Swift UI

Это UI, который предоставляет непосредственно Apple. Он пишется на языке Swift. По сути, у нас есть возможность открывать нативные окна напрямую из Unity, перемещать, менять их размер и закрывать с помощью стандартных системных элементов управления.

Но для поддержки работы с этими окнами нам пришлось написать свой небольшой модуль-обертку, который позволяет получать и обрабатывать события с UI элементов окна. В нашем приложении есть меню настроек и подсказки, реализованные при помощи Swift UI.

Разработка этого UI ведется с помощью нативных средств Apple, собирается в Xcode, а в Unity помещается как плагин.

Нативные окна выглядят как матовое стекло. Все объекты за ними размываются, даже если они виртуальные, созданные в нашем Unity приложении.

* Суд признал экстремистской и запретил в России деятельность корпорации по реализации социальных сетей.

Читайте также

Наверх