visionOS: immersive-рендеринг и трекинг
Режим приложения, Metal/Mobile, разрешения трекинга, near plane и ограничения экспорта.
visionOS: immersive-рендеринг и трекинг
В Reckfell есть нативный XR-модуль visionOS на Metal, Compositor Services и ARKit. Это платформенная интеграция, отдельная от OpenXR и браузерного WebXR. Зарегистрированное имя интерфейса — visionOS, именно с таким регистром.
Ограничение C# сейчас: exporter C# версии 1.0.0 не реализует цель visionOS. Справочник VisionOSXRInterface в установленном Windows SDK имеет статус source-only. Наличие нативного visionOS exporter/модуля в исходниках не подтверждает работающий C# export, подписанное приложение или сборку для устройства. До выбора этой цели проверьте шаблон, конфигурацию скриптов и Apple toolchain.
Сначала настройте режим приложения
В export preset есть application/app_role: Window=0 или Immersive=1. По умолчанию Window. Добавление XROrigin3D не превращает оконное приложение в Compositor Services application.
Для immersive-пути выберите Immersive и задайте application/immersion_style: Full=0, Mixed=1 или Progressive=2; по умолчанию в preset выбран Mixed. Swift-слой и метаданные экспорта должны соответствовать роли приложения. Full заменяет окружение, Mixed смешивает виртуальное содержимое с ним. Progressive — отдельный выбор погружения, а не dynamic render quality.
Текущий Compositor Services путь требует драйвер Metal. В этом режиме display-server меняет Forward+ на Mobile. Настраивайте и оценивайте сцену с Mobile, не рассчитывая на настольные Forward+ эффекты. Симулятор или desktop preview не подтверждает рендеринг устройства.
Swift compositor config выбирает color rgba16Float, depth depth32Float_stencil8 и layered layout. Foveation включается при поддержке capabilities устройства; отсутствие layered layout — фатальное условие конфигурации. Это решения платформы, а не инструкция самостоятельно создавать и освобождать её compositor textures.
Сцена и запуск
Для origin/camera и XR shaders используйте настройку XR-сцены. Минимальная иерархия:
XROrigin3D
└── XRCamera3DНа нативной visionOS-цели найдите зарегистрированный visionOS через XRServer. Один компонент должен управлять инициализацией и viewport; не запускайте рядом OpenXR. Сохраните исходную конфигурацию viewport для восстановления при ошибке или выходе.
Для immersive viewport осознанно задайте UseXR, UseHdr2D и XR VRS. Платформа предоставляет VRS в формате rasterization-rate-map, а не обычную shading-rate texture, нарисованную вручную. Для projection используйте активную XRCamera3D и убедитесь, что это текущая камера viewport.
true из Initialize не подтверждает разрешения трекинга, корректную pose или показанный stereo-кадр. Текущая инициализация запускает ARKit и асинхронно запрашивает hand/accessory authorization. Также она вызывает CompositorServicesData.initialize, не проверяя его bool-результат. Проверяйте native errors и реальную готовность кадров/трекинга; Initialize недостаточно для приёмки. Это наблюдение по исходникам, не исправление движка и не воспроизведённый на устройстве отказ.
Трекинг рук и контроллеров
Обе project settings по умолчанию false:
| Project setting | Текст разрешения в export |
|---|---|
| xr/visionos/enable_hand_tracking | privacy/hand_tracking_usage_description → NSHandsTrackingUsageDescription |
| xr/visionos/enable_controller_tracking | privacy/accessory_tracking_usage_description → NSAccessoryTrackingUsageDescription |
Включайте только используемый трекинг и объясните его назначение в соответствующем поле экспорта. Флажок и созданный tracker не подтверждают разрешение: provider активен только при enabled и allowed. Отказ отражается в native logs; предусмотрите fallback ввода, чтобы пользователь мог продолжить.
Hand trackers используют /user/hand_tracker/left и /user/hand_tracker/right. Привяжите XRHandModifier3D к нужной руке; перед игровой логикой проверяйте текущую валидность трекинга/суставов. Наличие modifier или видимой hand mesh не доказывает актуальные данные ARKit. Контроллеры идут отдельным accessory-tracking путём; не считайте любой подключённый gamepad пространственно отслеживаемым контроллером. Заимствованные provider trackers нельзя Free/Dispose из игровой логики.
Near plane и масштаб мира
Движок читает supportedMinimumNearPlaneDistance из layer capabilities. При построении projection проверяется:
camera Near / XRServer.WorldScale >= platform minimum
Используйте положительный world scale и небольшой численный запас. При минимуме платформы 0.1 м и WorldScale=2 значение Near=0.201 проходит условие, Near=0.1 — нет. 0.1 здесь пример, не универсальная константа capabilities. Проверьте реальную текущую камеру: изменение неиспользуемой камеры не исправит ошибку projection.
Mixed immersion: alpha и depth вместе
Compositor Services совмещает color и depth, используя premultiplied alpha и reverse-Z. Для прозрачного mixed background начните с чёрного RGB и alpha 0; цветной RGB при alpha 0 не является безопасным рецептом прозрачности. Видимым непрозрачным поверхностям нужна корректная глубина. См. объяснение Apple о Metal passthrough.
Не исправляйте пропадающее содержимое принудительной записью opaque depth у всех прозрачных частиц и невидимых поверхностей: это может испортить композицию и перекрытия. Изолируйте проблему на непрозрачном объекте, затем проверяйте color, alpha, запись depth и background вместе.
Прежний depth-only full-screen shader был неполным без настройки mesh, priority и culling и не проверялся на этой цели. Статья не выдаёт его за готовое исправление. Если нужен непрозрачный виртуальный sky, проверяйте depth-producing background на реальном устройстве; чёрный прозрачный фон и видимое виртуальное небо — разные требования.
Качество и диагностика
xr/visionos/dynamic_render_quality/enable по умолчанию false; maximum_quality — 0.38. Runtime CurrentRenderQuality требует включённого dynamic quality и не должен превышать настроенный максимум. Это не обещание FPS, сглаживания или приемлемого изображения. Повышайте качество после измерения device frame time и осмотра обоих глаз.
| Симптом | Что проверить первым |
|---|---|
| Нет visionOS interface на Windows | Платформенные условия модуля и source-only справочник; это не отсутствующая Entity проекта. |
| Отклонён C# export | Поддержку цели C# exporter: нативный export preset не добавляет managed runtime. |
| Приложение открылось окном | application/app_role и метаданные экспортированного приложения. |
| Ошибки старта или нет immersive-кадра | Metal driver, layer renderer/capabilities, native errors и реально текущую камеру. |
| Отклонена projection | Near, делённый на WorldScale, относительно сообщённого минимума. |
| Руки неподвижны или отсутствуют | Одновременно enable setting и authorization, текущие данные provider и привязку modifier. |
| Ореолы, пропавший sky или частицы | Premultiplied color/alpha, depth и реальный immersion style. |
| Ошибка runtime quality setter | Включение dynamic quality и значение в пределах настроенного максимума. |
| Зависание или завершение при загрузке | Device logs и frame stalls, подготовку ресурсов/шейдеров и запуск без debugger; не предполагайте один универсальный тайм-аут. |
Границы проверки
Статья сверена с текущими исходниками модуля, export, compositor, projection, authorization и C# exporter. Варианты platform build gate выполнены только как Python configuration logic. Нативный visionOS-код, Apple toolchain, simulator, signing, C# export, шлем, permissions, render output и frame performance здесь не запускались. Готовый device sample или иллюстрация рендера не заявлены. Source, Runtime и SDK движка не менялись.