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

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

4 ответов


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

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

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

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

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

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

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

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

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


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

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

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

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

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


для деятельности владением-вне (a.к. a. blackhole или блокирующий материал) вы можете использовать свойство экземпляра, называемое .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 класс (он работает в 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 - это состояние отображения пространства и набор Аранчоров из сеанса AR отслеживания мира. Читайте об этом здесь.


чтобы создать окклюзионный материал, это очень просто

    let boxGeometry = SCNBox(width: 0.1, height: 0.1, length: 0.1, chamferRadius: 0)

    // Define a occlusion material 
    let occlusionMaterial = SCNMaterial()
    occlusionMaterial.colorBufferWriteMask = []

    boxGeometry.materials = [occlusionMaterial]
    self.box = SCNNode(geometry: boxGeometry)
    // Set rendering order to present this box in front of the other models
    self.box.renderingOrder = -1