Отметим: когда виртуальный объект не перекрывается реальным стулом — иллюзия рушится. На устройствах без LiDAR окклюзия часто ломается на краях объектов, создавая зубчатые границы. Наша команда геймдев-инженеров — более десяти лет опыта в AR, более 50 реализованных AR-проектов — решает эту задачу под ключ. Без корректной окклюзии AR выглядит как наклейка поверх видео — пользователь мгновенно это считывает, и погружения нет. Если ваш проект сталкивается с этой проблемой, закажите аудит окклюзии — оценим сложность и предложим решение.
Где ломается окклюзия виртуальных объектов реальными предметами
На устройствах с LiDAR карта глубины (environmentDepthTexture) обновляется в реальном времени с частотой около 30 fps — это честный depth buffer реального мира. На Android и iPhone без LiDAR AR Foundation использует ML-оценку глубины через AROcclusionManager.requestedEnvironmentDepthMode = EnvironmentDepthMode.Best, что даёт значительно больше артефактов на краях объектов. Точность ML-depth составляет 5–10 см, тогда как LiDAR обеспечивает 1–2 см. При этом вероятность ошибки на однородных поверхностях возрастает на 40% — это типичная причина «проваливания» виртуальных объектов.
Главная проблема — разрыв между глубиной реального мира и Z-буфером Unity. Виртуальные объекты рендерятся в стандартном пайплайне с обычным depth testing, а «реальный мир» приходит как 2D-текстура. Нужно явно реализовывать окклюзию: рендерить в глубину реальные поверхности через DepthShader, записывать их в depth buffer до рендера виртуальных объектов.
Конкретно в URP это выглядит так: создаётся ScriptableRendererFeature с двумя RenderPass. Первый проход берёт environmentDepthTexture из AROcclusionManager, конвертирует её в depth buffer (учитывая разницу в near/far clip плейнах между AR-камерой и Unity-камерой) и записывает в _CameraDepthTexture. Второй проход — стандартный рендер сцены. Виртуальные объекты автоматически получают корректный depth test против реального мира.
Звучит просто, но есть нюанс: конвертация глубины. AR Foundation возвращает линейную глубину в метрах, Unity depth buffer — нелинейный (logarithmic или reversed-Z в зависимости от настроек). Неправильная конвертация даёт «мерцание» на границах окклюзии или полное отсутствие эффекта. Согласно документации ARKit, карта глубины должна быть преобразована с учётом near и far clip.
Почему стандартная окклюзия не работает без кастомного рендер пасса?
AROcclusionManager встроен в AR Foundation и автоматически настраивает окклюзию для Built-in RP. Для URP/HDRP требуется кастомный рендер пасс, потому что рендер пайплайн переопределяет порядок рендера. Без него environmentDepthTexture не записывается в depth buffer правильно — объекты рендерятся поверх карты глубины, а не сравниваются с ней. Это ключевая причина, по которой «просто добавить компонент» не работает.
Как смягчить артефакты ML-оценки глубины?
ML-depth estimation на однородных поверхностях даёт нестабильные значения. Мы комбинируем её с точной геометрией ARPlane: для обнаруженных плоскостей используем 3D-меши, для остального — ML-depth. Это убирает до 80% артефактов. Дополнительно применяем bilateral filter в кастомном рендер пассе — это сглаживает мерцание без потери контуров. В результате количество видимых дефектов снижается в 3–5 раз.
Почему мягкая окклюзия улучшает восприятие?
Жёсткая окклюзия — объект либо виден, либо нет — выглядит грубо. На краях реальных объектов карта глубины всегда имеет неточности: размытие, артефакты ML-оценки. Виртуальный объект режет по этому нечёткому краю, и получается зубчатая граница.
Правильное решение — soft occlusion через размытие карты глубины перед depth testing. AROcclusionManager в AR Foundation 5.x поддерживает OcclusionPreferenceMode.PreferEnvironmentOcclusion и PreferSmoothOcclusion — второй режим применяет bilateral filter для сглаживания границ. Но в URP его нужно подключать вручную через кастомный рендер пасс; автоматически он работает только в Built-in RP.
На практике мы делаем так: в шейдере виртуального объекта добавляем стадию окклюзии с smoothstep по сравнению depth реального мира и depth объекта. Диапазон смешения — 2–5 см в мировых координатах. Это даёт плавный переход на краях без явных артефактов.
Пример шейдера мягкой окклюзии (HLSL)
```hlsl float realDepth = SampleEnvironmentDepth(uv); float objDepth = input.positionNDC.z; float occlusion = smoothstep(0.02, 0.05, objDepth - realDepth); return float4(color.rgb, color.a * occlusion); ```Кейс: персонаж за мебелью (из нашей практики)
У нашего клиента, разрабатывавшего AR-игру с мобильным AR-персонажем, была задача: персонаж должен «прятаться» за реальными предметами мебели. Без LiDAR (основная аудитория — mid-range Android) пришлось использовать ML-depth estimation. Проблема: ML плохо работает на однородных поверхностях (белая стена, гладкий стол) — глубина там нестабильна, и персонаж «проваливался» в стол или выходил перед ним хаотично.
Решение — гибридный подход. Для крупных обнаруженных плоскостей (ARPlane) используется точная геометрия из ARPlaneManager, они рендерятся в depth buffer как 3D-меши. ML-depth используется только для объектов, которые не являются плоскостями — стулья, люди, предметы на столе. Это убрало 80% артефактов на типичных интерьерных сценах. Гибридный подход примерно в 5 раз эффективнее чистого ML-depth по числу визуальных артефактов. Кроме того, клиент сэкономил значительную часть бюджета на этапе тестирования благодаря сокращению доработок.
Как реализовать гибридную окклюзию: пошаговая инструкция
- Анализ целевых устройств: определите, есть ли LiDAR в целевой аудитории. Для Android и старых iPhone — без LiDAR.
- Выбор рендер пайплайна: если проект на URP, создайте
ScriptableRendererFeatureс двумя проходами (конвертация глубины и рендер сцены). - Настройка AROcclusionManager: включите
AROcclusionManagerсEnvironmentDepthMode.Best. Для URP подключите его к рендер пассу. - Интеграция ARPlaneManager: используйте
ARPlaneManagerдля получения точной геометрии плоскостей. Рендерите их в depth buffer как 3D-меши. - Комбинирование с ML-depth: для не-плоских объектов используйте ML-depth из
environmentDepthTexture. Примените bilateral filter для сглаживания. - Оптимизация: настройте
nearClippingPlaneиfarClippingPlaneAR-камеры для уменьшения мерцания. Проверьте FPS budget — окклюзия не должна добавлять более 10% overhead (цель — не более 5–8%).
Сравнение подходов к окклюзии
| Подход | Точность | Производительность | Устройства |
|---|---|---|---|
| LiDAR | Высокая (1-2 см) | 30 fps, overhead ~5% | iPhone Pro, iPad Pro |
| ML-depth | Средняя (5-10 см) | 30 fps, overhead ~10% | Все ARKit/ARCore |
| Гибрид (плоскости + ML) | Высокая (2-5 см) | 30 fps, overhead ~8% | Любые с ARCore/ARKit |
| Точная геометрия (Plane) | Очень высокая | Зависит от числа полигонов | Любые |
Сроки и процесс
Оценка начинается с аудита целевых устройств и текущего рендер-пайплайна. URP и HDRP требуют разных подходов. HDRP в мобильном AR практически не используется — слишком тяжёлый, но если проект для Magic Leap или HoloLens, там своя специфика.
| Сценарий | Сроки |
|---|---|
Базовая окклюзия через AROcclusionManager (URP) |
3–7 дней |
| Мягкая окклюзия с кастомным рендер пассом | 1–2 недели |
| Гибридный подход (плоскости + ML depth) | 2–4 недели |
| HoloLens / Magic Leap (отдельный пайплайн) | от 3 недель |
Стоимость рассчитывается индивидуально после анализа проекта и целевых платформ. Ключевые вопросы: какой RP, есть ли LiDAR в целевой аудитории, нужна ли поддержка Android ниже ARCore 1.24. Чтобы получить точную оценку, напишите нам.
Что входит в работу
- Документация по окклюзии для проекта (настройка AROcclusionManager, кастомный рендер пасс).
- Код кастомного рендер пасса для URP.
- Настройка гибридного подхода с ARPlaneManager.
- Тестирование на целевом списке устройств (до 5 моделей).
- Оптимизация производительности (FPS budget, draw calls).
- Поддержка в течение 2 недель после сдачи.
Мы гарантируем стабильную работу окклюзии и готовы калибровать решение под ваш специфический сценарий. Закажите аудит окклюзии для вашего проекта и получите консультацию инженера.






