Реализация AR-портала (погружение в виртуальную сцену)
AR-портал — это рамка в реальном мире, через которую видна другая среда: виртуальный лес, исторический интерьер, другая планета. Внутри портала — 360° окружение или 3D-сцена. Снаружи — реальный мир. Пользователь может заглянуть, обойти вокруг, зайти внутрь.
Технически это задача управления стенсилом и culling-маской. Реализуется через Metal или SceneKit — RealityKit 1.x эту технику не поддерживает напрямую.
Принцип работы: stencil buffer
Портал — это геометрия с записью в stencil buffer, но без записи в color buffer. Содержимое виртуальной сцены рендерится только там, где stencil равен 1 (внутри рамки). Реальный мир рендерится везде, где stencil равен 0.
В SceneKit это реализуется через SCNMaterial с кастомным Metal-шейдером:
// Материал для рамки портала — пишет в stencil, не пишет цвет
portalFrameMaterial.writesToDepthBuffer = false
portalFrameMaterial.colorBufferWriteMask = []
// В Metal: stencilReference = 1, stencilWriteMask = 0xFF
// Материал для содержимого портала — рендерится только при stencil == 1
contentMaterial.readsFromDepthBuffer = true
// В Metal: stencilTestFunction = .equal, stencilRef = 1
В RealityKit 2 появился доступ к Metal render passes, но полноценный stencil portal проще делать через SceneKit или чистый Metal с ARSCNView / ARView с кастомным RenderCallbacks.
Что усложняет реализацию
Окклюзия изнутри. Когда пользователь заходит внутрь портала, нужно инвертировать логику: внешний мир скрывается, виртуальное окружение занимает весь экран. Детектируем пересечение: если ARCamera.transform находится внутри объёма портала — переключаем режим рендеринга. Простая проверка через AABB (axis-aligned bounding box) работает для большинства сценариев.
Потолок и пол портала. Рамка — это одна плоскость. Но виртуальная сцена должна быть ограничена с боков, сверху и снизу, иначе содержимое «вытекает» за рамку при боковом взгляде. Решение: дополнительные невидимые «стены» с отключённым color-write вокруг виртуального объёма — они закрывают stencil снаружи.
Освещение на границе. Реальная сцена освещена ARKit environment map. Виртуальная — своим skybox или IBL. На границе портала — жёсткий переход. Смягчаем через SCNScene.fogStartDistance внутри виртуального объёма и alpha-blending на краях рамки.
Производительность. Рендерим две сцены одновременно: реальный мир через AR-камеру и виртуальную сцену внутри. На старых устройствах (iPhone X, iPhone 8) FPS падает ниже 30 из-за двойного draw call. Оптимизация: упрощаем геометрию виртуальной сцены (LOD), используем baked освещение вместо realtime, ограничиваем draw distance внутри портала.
Кейс
Музейное приложение: AR-порталы в зал с реконструкцией Древнего Рима. Рамка — арка из мрамора, 2×3 метра в мировом пространстве. Внутри — photogrammetry-сканы реальных артефактов с IBL-освещением. Три AR-маркера на полу зала задавали позиции порталов через ARImageAnchor. При заходе пользователя внутрь — звуковое окружение переключалось с музея на атмосферу Рима через AVAudioEnvironmentNode с позиционным звуком.
Главная проблема на этапе тестирования: «протечка» виртуальной сцены через реальные стены. Пользователь смотрел на портал через стеклянную перегородку — стенсил не учитывал реальную геометрию. Решение: depth occlusion через ARMatteGenerator для маскирования реальных непрозрачных поверхностей.
Что входит в работу
- Metal-шейдер для stencil-based портала
- Детектирование входа/выхода пользователя через AABB
- Виртуальное окружение: skybox, IBL, LOD-оптимизация геометрии
- Depth occlusion для корректной окклюзии реальными объектами
- Позиционный звук при переходе через портал
- Тестирование на устройствах от iPhone SE до iPhone 15 Pro
Сроки
| Сложность | Сроки |
|---|---|
| Базовый портал с простым 360° skybox | 2–3 недели |
| Портал с 3D-сценой, окклюзией и звуком | 4–6 недель |
| Несколько порталов + детектирование входа + переключение сред | 7–10 недель |
Стоимость рассчитывается индивидуально.







