Подтвердить что ты не робот

ARKit скрывает объекты за стенами

Как я могу использовать горизонтальную и вертикальную плоскости, отслеживаемые ARKit, чтобы скрыть объекты за стенами/за реальными объектами? В настоящее время 3D добавленные объекты можно увидеть сквозь стены, когда вы выходите из комнаты и/или перед объектами, за которыми они должны стоять. Так можно ли использовать данные, которые ARKit дает мне, чтобы обеспечить более естественный опыт AR без объектов, возникающих через стены?

4b9b3361

Ответ 1

У вас здесь две проблемы.

(И вы даже не использовали регулярные выражения !)

Как создать геометрию окклюзии для ARKit/SceneKit?

Если вы установите для материала colorBufferWriteMask пустое значение ([] в Swift), любые объекты, использующие этот материал, не будут отображаться в представлении, но они все равно будут записываться в z-буфер во время рендеринга, что влияет на рендеринг другие объекты. По сути, вы получите "дыру", подобную вашему объекту, через которую показывает фон (подача камеры, в случае ARSCNView), но которая еще может скрывать другие объекты SceneKit.

Вам также необходимо убедиться, что окклюдированный отображается перед любыми другими узлами, которые он должен скрывать. Вы можете сделать это, используя иерархию узлов (я не могу вспомнить, были ли родительские узлы визуализированы перед их детьми или наоборот, но это достаточно легко проверить). Узлы, которые являются одноранговыми узлами в иерархии, не имеют детерминированного порядка, но вы можете принудительно выполнить порядок независимо от иерархии с свойством renderingOrder. Это свойство по умолчанию равно нулю, поэтому установка его на -1 будет отображаться перед всем. (Или для более тонкого управления, установите для renderingOrder для нескольких узлов последовательность значений.)

Как обнаружить стены /etc, чтобы вы знали, где разместить геометрию окклюзии?

В iOS 11.3 и более поздних версиях (ака "ARKit 1.5") вы можете включить обнаружение vertical плоскости. (Обратите внимание, что, когда вы возвращаете vertical плоскости якоря назад, они автоматически вращаются. Поэтому, если вы присоедините модели к якорю, их местное "вверх" направление нормальное к плоскости.) Также новинка в iOS 11.3, вы можете получить более подробную оценку формы для каждой обнаруженной плоскости (см. ARSCNPlaneGeometry), независимо от ее ориентации.

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

Итак... если вы используете обнаруженные вертикальные плоскости для окклюзии виртуальной геометрии, вы можете найти места, где виртуальные объекты, которые должны быть скрыты, проходят сквозь них, либо не скрываясь прямо на краю стены, либо будучи видимыми через места где ARKit не отображает всю настоящую стену. (Последняя проблема, которую вы могли бы решить, предполагая в большей степени, чем ARKit).

Ответ 2

Отличное решение:

GitHub: аркит-окклюзия

Работал для меня.

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

Или в диапазоне 4 метров датчик сенсора iphone работает, и вы можете обнаружить препятствия с помощью ARHitTest.

Ответ 3

Для операции удержания (aka blackhole или blocking material) вы можете использовать свойство instance, называемое .colorBufferWriteMask, в iOS 11 и macOS 13. Это свойство записывает информацию канала глубины при рендеринге материала. Вы можете использовать его так:

torus.geometry?.firstMaterial?.colorBufferWriteMask = .alpha

или таким образом:

func blockingMaterial() -> SCNMaterial {
    let holdout = SCNMaterial()
    holdout.isDoubleSided = true
    holdout.diffuse.contents = CIColor.black
    holdout.colorBufferWriteMask = SCNColorMask(rawValue: 0)
    return holdout
}
torus.geometry?.firstMaterial = blockingMaterial()

Вы можете легко использовать это свойство для затенения невидимых виртуальных стен. Чтобы разместить эти невидимые виртуальные стены в нужном месте, вы ARWorldMap класс ARWorldMap (он работает в iOS 12) и ARAnchors.

session.getCurrentWorldMap { worldMap, error in 
    guard let worldMap = worldMap else {
        showAlert(error)
        return
    }
}
let configuration = ARWorldTrackingConfiguration()
configuration.initialWorldMap = worldMap
session.run(configuration) 

ARWorldMap - это состояние отображения пространства и набор ARAnchors из сеанса AR отслеживания мирового уровня. Читайте об этом здесь.