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
4 回答
你有两个问题 .
(你甚至没有使用正则表达式!)
如何为ARKit / SceneKit创建遮挡几何?
如果将SceneKit材质的colorBufferWriteMask设置为空值(Swift中的
[]
),则使用该材质的任何对象都会在渲染过程中仍然写入z缓冲区,这会影响其他对象的渲染 . 实际上,你会得到一个像你的对象一样的形状,背景显示(相机输入,在ARSCNView
的情况下),但仍然可以遮挡其他SceneKit对象 .你应该晦涩难懂 . 你可以使用节点层次结构来做到这一点(我可以很容易地测试) . 作为层次结构中对等方的节点没有确定性顺序,但您可以使用renderingOrder属性强制执行任何层次结构的顺序 . 该属性默认为零,因此将其设置为-1将在所有内容之前呈现 . (或者为了更精细的控制,将几个节点的
renderingOrder
设置为一系列值 . )如何检测墙/等,以便知道遮挡几何的位置?
在iOS 11.3及更高版本(又名"ARKit 1.5")中,您可以打开vertical平面检测 . (注意,当你从那里得到vertical平面锚点时,它们会自动旋转 . 所以如果你将模型附加到锚点,它们的局部"up"方向与飞机垂直 . )在iOS 11.3中也是新的,你可以获得更多每个检测到的平面的详细形状估计(参见ARSCNPlaneGeometry),无论其方向如何 .
但是,即使您具有水平和垂直,平面的外部界限也只是随时间变化的估计值 . 也就是说,ARKit可以快速检测墙壁的哪个部分,但是如果没有用户花费一些时间挥动设备来绘制空间,它就不知道墙壁的边缘 . 即使这样,映射的边缘也可能与真实墙壁的边缘不精确对齐 .
因此......如果您使用检测到的垂直平面遮挡虚拟几何体,您可能会发现应该隐藏的虚拟对象显示的位置,或者通过不是完全隐藏在墙的边缘,或者通过位置可见其中ARKit没有映射整个真实墙 . (后一个问题你可以通过假设比ARKit更大的范围来解决 . )
好方案:
GitHub: arkit-occlusion
为我工作 .
但在我的情况下,我想通过代码设置墙 . 因此,如果您不想按用户设置墙壁 - >使用平面检测来检测墙壁并按代码设置墙壁 .
或者在4米的范围内,iphone depht传感器工作,您可以使用ARHitTest检测障碍物 .
对于保持操作(也就是黑洞或阻塞材料),您可以在iOS 11和macOS 13中使用名为
.colorBufferWriteMask
的实例属性 . 此属性在渲染材质时会写入深度通道信息 . 你可以这样使用它:或者这样:
您可以轻松地使用此属性来遮蔽隐形虚拟墙 . 要将这些不可见的虚拟墙放置到正确的位置,可以帮助您(类似于iOS 12)和
ARAnchors
.ARWorldMap
是来自世界跟踪AR会话的空间映射状态和ARAnchor集 . 阅读它here .为了创建一个遮挡材料,它非常简单