我正在开展一个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,我都看不到相机的任何东西。
有人会想到一个不同的技巧来使相机变暗吗?
答案 0 :(得分:4)
您的选项B无效,原因有两个:
var pt = SqlGeography.Point(-77.1851436, 39.1065236, 4326);
var binary = pt.Serialize().Value;
var hexString = "0x" + BitConverter.ToString(binary).Replace("-", "");
是实际显示相机图像的内容,因此如果您将其设置为一种颜色,则根本不再显示相机图像。您可能会考虑其他一些选项(大部分未经测试):
根据您链接的答案引用,使用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
使其附着在相机上来达到这种效果。
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
)不遵守球体边界。您可以从球外接收结果。
通过球体的不透明性可以看到球体之外的东西。似乎不透明的事物将在球体外部变得透明。
白色部分是球体内部的平面,灰色部分是球体外部的平面。平面是纯白色且不透明。我尝试使用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)