使 ARKit 摄像头在物体后面变暗/变亮

问题描述 投票:0回答:4

我目前正在开发一个 ARKit 项目,我想使实际的相机输入变暗,以便 3D 场景中的对象更加突出。

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

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

B) 设置背景颜色,如下所示:

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

可悲的是,颜色带有 alpha <1 are still opaque, so no matter what alpha I set I can't see anything of the camera feed.

有人能想出一种不同的技巧来使相机画面变暗吗?

ios ios11 arkit
4个回答
5
投票

您的选项 B 不起作用有两个原因:

  1. 场景视图是不透明的,因此其后面没有任何东西可以与部分透明的背景颜色混合。
  2. sceneView.scene.background
    是实际显示相机图像的内容,因此如果将其设置为某种颜色,则根本不再显示相机图像。

您可能会考虑的一些其他选项(大部分未经测试):

  • 正如您链接的答案中所引用的,使用

    SCNTechnique
    设置multipass渲染。在第一遍中,使用
    excludeCategoryMask
    (和场景内容)渲染整个场景,设置为仅渲染背景,使用使所有像素变暗(或模糊或其他)的着色器。在第二遍中,仅渲染您想要在没有该着色器的情况下出现的节点(使用简单的直通着色器)。

  • 保留选项 B,但使场景视图不透明。将 视图的

    backgroundColor
    (不是场景的
    background
    )设置为纯色,并设置场景
    transparency
    background
    以根据该颜色淡出相机源。

  • 使用几何图形为您的场景创建“物理”背景 - 例如一个大尺寸的

    SCNPlane
    ,作为相机的子元素放置在某个固定距离处,该距离比任何其他场景内容都远得多。设置平面的背景颜色和透明度。

  • 使用多个视图 -

    ARSCNView
    ,变得不透明且具有清晰的背景,另一个(不一定是 SceneKit 视图)仅显示相机源。扰乱其他视图(或添加其他有趣的东西,如
    UIVisualEffectView
    )来遮挡相机画面。

  • 向 Apple 提交有关

    sceneView.background
    的错误,无法获得节点和材质获得的全套着色自定义选项(滤镜、着色器修改器、完整着色器程序)等,没有这些选项,自定义背景比自定义要困难得多场景的其他方面。


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 距离进行剪辑,而不是根据相机和目标之间的直线距离进行剪辑。

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


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)

0
投票

我找到了另一个解决方案:您可以使用场景背景上的

intensity
属性来调暗相机源。 例如。这将以 30% 的亮度渲染背景:

sceneView.scene.background.intensity = 0.3
最新问题
© www.soinside.com 2019 - 2025. All rights reserved.