使对象后面的ARKit相机变暗/变亮

时间:2017-12-06 16:48:12

标签: ios ios11 arkit

我正在开展一个ARKit项目,我想让实际的相机输入变暗,这样我3D场景中的物体就会更加突出。

到目前为止我找到了2个解决方案:

A)手动将CIFilter应用于相机帧并将其作为背景图像设置为SceneKit场景,如this SO post中的回答 这里的问题是fps坦克显着。

B)设置背景颜色如下:

sceneView.scene.background.contents = UIColor(white: 0.0, alpha: 0.2)

可悲的是,alpha< 1的颜色仍然是不透明的,所以无论我设置什么alpha,我都看不到相机的任何东西。

有人会想到一个不同的技巧来使相机变暗吗?

3 个答案:

答案 0 :(得分:4)

您的选项B无效,原因有两个:

  1. 场景视图是不透明的,因此没有任何东西可以让部分透明的背景色混合。
  2. var pt = SqlGeography.Point(-77.1851436, 39.1065236, 4326); var binary = pt.Serialize().Value; var hexString = "0x" + BitConverter.ToString(binary).Replace("-", ""); 是实际显示相机图像的内容,因此如果您将其设置为一种颜色,则根本不再显示相机图像。
  3. 您可能会考虑其他一些选项(大部分未经测试):

    • 根据您链接的答案引用,使用sceneView.scene.background设置multipass渲染。在第一遍中,渲染整个场景,使用SCNTechnique(和您的场景内容)设置为仅使用背景渲染,使用着色(或模糊或其他)所有像素的着色器。在第二遍中,仅渲染要在没有该着色器的情况下显示的节点(使用简单的直通着色器)。

    • 保留选项B,但使场景视图不透明。将视图 excludeCategoryMask(不是场景的backgroundColor)设置为纯色,并设置场景的background { {1}}淡出相机颜色的相机。

    • 使用几何体创建一个" physical"您的场景背景 - 例如一个transparency大尺寸,放置在相机的一个孩子的某个固定距离,比任何其他场景内容远得多。设置平面的背景颜色和透明度。

    • 使用多个视图 - background,制作非透明且背景清晰,另一个(不一定是SceneKit视图)只显示相机Feed。与其他视图混淆(或放入其他有趣的东西,如SCNPlane)以遮挡相机输入。

    • File a bug with Apple关于ARSCNView没有得到节点和素材获得的全套着色自定义选项(滤镜,着色修饰符,完整着色器程序)等,没有它们自定义背景很多比定制场景的其他方面更困难。

答案 1 :(得分:1)

我通过创建具有SCNNode几何形状的SCNSphere并使用ARSCNView.pointOfView使其附着在相机上来达到这种效果。

enter image description here

override func viewDidLoad() {
    super.viewDidLoad()

    let sphereFogNode = makeSphereNode()
    arView.pointOfView!.addChildNode(sphereFogNode)

    view.addSubview(arView)
}

private static func makeSphereGeom() -> SCNSphere {
    let sphere = SCNSphere(radius: 5)
    let material = SCNMaterial()

    material.diffuse.contents = UIColor(white: 1.0, alpha: 0.7)
    material.isDoubleSided = true

    sphere.materials = [material]
    return sphere
}

private static func makeSphereNode() -> SCNNode {
    SCNNode(geometry: makeSphereGeom())
}

剪切外球

这会使照相机以及球体边界之外的所有物体变暗。命中测试(ARFrame.hitTest)不遵守球体边界。您可以从球外接收结果。

通过球体的不透明性可以看到球体之外的东西。似乎不透明的事物将在球体外部变得透明。

enter image description here

白色部分是球体内部的平面,灰色部分是球体外部的平面。平面是纯白色且不透明。我尝试使用SCNScene.fog*来将SceneKit图形裁剪到球体外部,但是雾似乎并不会遮挡渲染的内容,只会影响其外观。 SCNCamera.zFar也不起作用,因为它基于Z距离而不是相机与目标之间的直线距离进行裁剪。

只要使您的球体足够大,一切都会看起来很好。

答案 2 :(得分:0)

对于那些想要实现rickster选项“使用几何体为场景创建“物理”背景的人”,这是我的代码(.scnassets中的平面和透明度)

    guard let backgroundPlane = sceneView.scene.rootNode.childNode(withName: "background", recursively: false) else { return }
    backgroundPlane.removeFromParentNode()
    backgroundPlane.position = SCNVector3Make(0, 0, -2)
    sceneView.pointOfView?.addChildNode(backgroundPlane)