SceneKit ARKit发光效果

时间:2018-07-17 21:41:53

标签: scenekit arkit cifilter glow bloom

嗨,我正在尝试在节点周围产生发光效果。 我使用了SCNNode过滤器属性,并将其设置为CIFilter数组。

仅当该节点后面没有我不了解的节点时,它才起作用并呈现。我试图设置渲染顺序和readDepth选项,但没有成功。我真的停留在这一点上,希望您的投入!

请参阅屏幕截图中的示例和代码示例。

func addBloom() -> [CIFilter]? {
    let bloomFilter = CIFilter(name:"CIBloom")!
    bloomFilter.setValue(10.0, forKey: "inputIntensity")
    bloomFilter.setValue(30.0, forKey: "inputRadius")

    return [bloomFilter]
}

使用以下方法进行调用:

myNode.filters = addBloom() 

enter image description here

最后一点,我注意到要使CIFilter与Metal配合使用,必须将antiAliasing设置为.none

arSceneView.antialiasingMode = .none

非常感谢!

Adrien

1 个答案:

答案 0 :(得分:4)

对于没有应用过滤器的节点,您是否尝试将writesToDepthBuffer设置为false?

有关信息,writesToDepthBuffer指的是:

  

SceneKit的渲染过程使用深度缓冲区来确定   渲染表面相对于查看器的顺序。默认值   此属性的值为YES,指定SceneKit保存深度   每个渲染像素的信息,供以后的渲染过程使用。   通常,渲染时禁用写入深度缓冲区   半透明的对象,因为渲染过程的后期   可能需要有关其背后不透明物体的深度信息。

此示例似乎运行良好:

/// Generates An SCNPlane & A Red & Green SCNSphere
func generateNodes(){

    let planeNode = SCNNode(geometry: SCNPlane(width: 1, height: 0.5))
    planeNode.geometry?.firstMaterial?.diffuse.contents = UIColor.black
    planeNode.position = SCNVector3(0, 0, -1)

    let redSphereNode = SCNNode(geometry: SCNSphere(radius: 0.1))
    redSphereNode.geometry?.firstMaterial?.diffuse.contents = UIColor.red
    redSphereNode.position = SCNVector3(-0.3, 0, -1)
    redSphereNode.filters = addBloom()

    let greenSphereNode = SCNNode(geometry: SCNSphere(radius: 0.1))
    greenSphereNode.geometry?.firstMaterial?.diffuse.contents = UIColor.green
    greenSphereNode.position = SCNVector3(0.3, 0, -1)
    greenSphereNode.filters = addBloom()

    self.augmentedRealityView.scene.rootNode.addChildNode(planeNode)
    self.augmentedRealityView.scene.rootNode.addChildNode(redSphereNode)
    self.augmentedRealityView.scene.rootNode.addChildNode(greenSphereNode)
    planeNode.geometry?.firstMaterial?.writesToDepthBuffer = false

}


/// Creates An Array Of CIBloom Filters
///
/// - Returns: [CIFilter]?
func addBloom() -> [CIFilter]? {
    let bloomFilter = CIFilter(name:"CIBloom")!
    bloomFilter.setValue(10.0, forKey: "inputIntensity")
    bloomFilter.setValue(30.0, forKey: "inputRadius")

    return [bloomFilter]
}

但是要注意的一件事,我确实注意到,如果我使用具有透明背景的图像作为SCNPlane的内容,则不会起作用,尽管使用另一幅图像也可以。

希望它会为您指明正确的方向...