ios swift scenekit augmented-reality arkit

ios - ARKit esconde objetos detrás de las paredes



swift scenekit (4)

¿Cómo puedo usar los planos horizontales y verticales seguidos por ARKit para ocultar objetos detrás de paredes / detrás de objetos reales? Actualmente, los objetos 3D agregados se pueden ver a través de las paredes al salir de una habitación y / o frente a los objetos que deberían estar detrás. Entonces, ¿es posible utilizar los datos que ARKit me brinda para brindar una experiencia AR más natural sin que los objetos aparezcan a través de las paredes?


Gran solución:

GitHub: arkit-oclusión

Trabajó para mi.

Pero en mi caso quise poner las paredes por código. Entonces, si no desea configurar los Muros por usuario -> use la detección de planos para detectar muros y establecer los muros por código.

O en un rango de 4 metros, el sensor de iPhone funciona y puede detectar obstáculos con ARHitTest .


Para crear un material de oclusión es muy sencillo.

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


Para la operación de retención (también conocido como .colorBufferWriteMask o material de bloqueo) puede usar la propiedad de instancia, llamada .colorBufferWriteMask , en iOS 11 y macOS 13. Esta propiedad escribe información de canal de profundidad cuando se procesa el material. Puedes usarlo de esta manera:

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

o de esta manera:

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()

Puede usar esta propiedad fácilmente para sombrear sus muros virtuales invisibles. Para colocar estos muros virtuales invisibles en un lugar correcto, ARWorldMap clase ARWorldMap (funciona en iOS 12) y ARAnchors .

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

ARWorldMap es el estado de asignación de espacio y el conjunto de ARAnchors de una sesión de AR de seguimiento mundial. Lea sobre esto here .


Tienes dos problemas aquí.

(¡Y ni siquiera usaste expresiones regulares !)

¿Cómo crear una geometría de oclusión para ARKit / SceneKit?

Si configura el colorBufferWriteMask de un material de colorBufferWriteMask en un valor vacío ( [] en Swift), los objetos que usen ese material no aparecerán en la vista, pero seguirán escribiendo en el búfer z durante el procesamiento, lo que afecta el procesamiento de otros objetos En efecto, obtendrás un "agujero" con forma de objeto, a través del cual se muestra el fondo (la imagen de la cámara, en el caso de ARSCNView ), pero que aún puede ocultar otros objetos de SceneKit.

También deberá asegurarse de que una oclusión se rinda antes de cualquier otro nodo que se supone que debe ocultar. Puede hacer esto utilizando la jerarquía de nodos (no puedo recordar de antemano si los nodos principales se representan antes que sus secundarios o al revés, pero es bastante fácil de probar). Los nodos que son pares en la jerarquía no tienen un orden determinista, pero puede forzar un orden independientemente de la jerarquía con la propiedad renderingOrder . El valor predeterminado de esa propiedad es cero, por lo que establecerlo en -1 se procesará antes que todo. (O para un control más preciso, establezca la orden de renderingOrder para varios nodos en una secuencia de valores).

¿Cómo detectar muros / etc para saber dónde colocar la geometría de oclusión?

En iOS 11.3 y versiones posteriores (también conocido como "ARKit 1.5"), puede activar vertical detección de plano vertical . (Tenga en cuenta que cuando recupera los anclajes del plano vertical , se giran automáticamente. Por lo tanto, si conecta modelos al ancla, su dirección local "hacia arriba" es normal al plano.) También es nuevo en iOS 11.3, puede obtener una estimación de forma más detallada para cada plano detectado (ver ARSCNPlaneGeometry ), independientemente de su orientación.

Sin embargo, incluso si tiene la horizontal y la vertical, los límites exteriores de un plano son solo estimaciones que cambian con el tiempo. Es decir, ARKit puede detectar rápidamente dónde está una parte de una pared, pero no sabe dónde están los bordes de la pared sin que el usuario pase algún tiempo agitando el dispositivo para trazar el espacio. E incluso entonces, los bordes asignados podrían no alinearse precisamente con los de la pared real.

Entonces ... si usa planos verticales detectados para ocluir la geometría virtual, puede encontrar lugares donde se muestren los objetos virtuales que se supone que deben estar ocultos, ya sea por no estar totalmente escondidos en el borde de la pared o ser visibles a través de los lugares donde ARKit no ha mapeado toda la pared real. (El último problema que podría resolver al asumir que ARKit lo hace en mayor medida).