【问题标题】:SceneKit LiDAR features for object occlusion用于对象遮挡的 SceneKit LiDAR 功能
【发布时间】:2021-02-26 23:20:09
【问题描述】:

使用 LiDAR 进行对象遮挡可在 RealityKit 中使用场景理解选项。基本上扫描的几何图形用于遮挡。

arView.environment.sceneUnderstanding.options.insert(.occlusion)

遗憾的是,这不包含在 SceneKit 中。虽然仍然可以通过 ARMeshAnchor 从 LiDAR 获取扫描的几何图形,但对象遮挡必须从该几何图形中手动完成。 这是关于它的讨论:Apple Forum

是否已经有这种方法的解决方案?

【问题讨论】:

标签: swift scenekit arkit realitykit lidar


【解决方案1】:

我通过执行以下操作在 SceneKit 中实现了对象遮挡:

//Before starting session, put this option in configuration
if ARWorldTrackingConfiguration.supportsSceneReconstruction(.mesh) {
        configuration.sceneReconstruction = .mesh
} else {
        // Handle device that doesn't support scene reconstruction
}
// Run the view's session
sceneView.session.run(configuration)

你会在这个方法中得到场景重建网格,所以这样实现

func renderer(_ renderer: SCNSceneRenderer, nodeFor anchor: ARAnchor) -> SCNNode? {
    guard let meshAnchor = anchor as? ARMeshAnchor else {
            return nil
        }

    let geometry = createGeometryFromAnchor(meshAnchor: meshAnchor)

    //apply occlusion material
    geometry.firstMaterial?.colorBufferWriteMask = []
    geometry.firstMaterial?.writesToDepthBuffer = true
    geometry.firstMaterial?.readsFromDepthBuffer = true
        

    let node = SCNNode(geometry: geometry)
    //change rendering order so it renders before  our virtual object
    node.renderingOrder = -1
    
    return node
}

网格更新时更新您的节点

func renderer(_ renderer: SCNSceneRenderer, didUpdate node: SCNNode, for anchor: ARAnchor) {
    guard let meshAnchor = anchor as? ARMeshAnchor else {
            return
        }
    let geometry = createGeometryFromAnchor(meshAnchor: meshAnchor)

        // Optionally hide the node from rendering as well
        geometry.firstMaterial?.colorBufferWriteMask = []
        geometry.firstMaterial?.writesToDepthBuffer = true
        geometry.firstMaterial?.readsFromDepthBuffer = true
        

    node.geometry = geometry
}

其他方法

// Taken from https://developer.apple.com/forums/thread/130599
func createGeometryFromAnchor(meshAnchor: ARMeshAnchor) -> SCNGeometry {
    let meshGeometry = meshAnchor.geometry
    let vertices = meshGeometry.vertices
    let normals = meshGeometry.normals
    let faces = meshGeometry.faces
    
    // use the MTL buffer that ARKit gives us
    let vertexSource = SCNGeometrySource(buffer: vertices.buffer, vertexFormat: vertices.format, semantic: .vertex, vertexCount: vertices.count, dataOffset: vertices.offset, dataStride: vertices.stride)
    
    let normalsSource = SCNGeometrySource(buffer: normals.buffer, vertexFormat: normals.format, semantic: .normal, vertexCount: normals.count, dataOffset: normals.offset, dataStride: normals.stride)
    // Copy bytes as we may use them later
    let faceData = Data(bytes: faces.buffer.contents(), count: faces.buffer.length)
    
    // create the geometry element
    let geometryElement = SCNGeometryElement(data: faceData, primitiveType: primitiveType(type: faces.primitiveType), primitiveCount: faces.count, bytesPerIndex: faces.bytesPerIndex)
    
    return SCNGeometry(sources: [vertexSource, normalsSource], elements: [geometryElement])
}

func primitiveType(type: ARGeometryPrimitiveType) -> SCNGeometryPrimitiveType {
        switch type {
            case .line: return .line
            case .triangle: return .triangles
        default : return .triangles
        }
}

【讨论】:

  • 看起来是个不错的方法。我已经在飞机上的阴影中使用了带有“colorBufferWriteMask”的遮挡,这对这种方法很有意义。表现如何?有什么问题吗?
  • 它的工作,但遮挡期间的边缘不如 RealityKit 中的平滑。
  • github 项目示例在这里:github.com/haris008/SceneKit-Occlusion
猜你喜欢
  • 2014-09-22
  • 2023-03-04
  • 2021-07-26
  • 1970-01-01
  • 1970-01-01
  • 2020-04-11
  • 2020-08-06
  • 2013-04-13
  • 2017-02-27
相关资源
最近更新 更多