ARKit 使 SCNLight 指向相机正在看的地方?

ARKit make an SCNLight point ahead where the camera is looking?

所以我可以访问 sceneView.pointOfView并且我想让 AR 体验感觉就像我在我面前直接用闪光灯照射我看到的物体,当我指向它们时它们会变亮。

我试过这样创建聚光灯:

let spotLight = SCNLight()
spotLight.type = .spot
spotLight.spotInnerAngle = 60
spotLight.spotOuterAngle = 60
let spotNode = SCNNode()
spotNode.light = spotLight
spotNode.position = position

然后我认为将灯光添加到 pointOfView 节点可以使灯光随相机移动,这意味着它始终会照亮前方...

sceneView.pointOfView?.addChildNode(spotLight)

这不起作用,对象显示为黑色,不亮。

我做错了什么?我想让光点指向我通过 AR 体验看到的东西,就像我拿着手电筒直照前方一样....

有什么建议吗?

您是否正在寻找一种虚拟手电筒来真实地照亮相机画面中的真实世界场景?这是一个非常高的要求。

你基本上是在谈论将光锥投影映射到每个可见的真实世界表面上,这需要检测和建模这些表面,这比水平面检测 ARKit 做的要多得多。

(如果你想不真实地照亮现实世界的场景,你需要做的就是在视图中间放置一个半透明的白色圆圈。也许喜欢混合模式。对于一个小更逼真一点,根据 hit-testing 相对于 AR 场景的视图中心,改变圆圈的大小或 3D 距离。)


你想要一个虚拟手电筒来照亮你在 AR 中放置的虚拟对象吗?这很容易做到。事实上,您的代码是实现这一目标的大部分方法。可能出现的问题:

spotNode.position = position

您上面的代码片段没有说明您是从哪里获得这个职位的。如果你想让聚光灯节点连接到相机,它应该是一个零向量。也就是说,你想让它在相机节点的局部space中有一个中立的位置。将此向量设置为非零值会使您的光源从相机位置偏移一个恒定的位移(可能会导致光线在您的场景中没有任何用处)。

sceneView.pointOfView?.addChildNode(spotLight)

根据此代码运行的时间,sceneView.pointOfView 可能为零,因此您实际上并未执行 addChildNode 调用。在向其添加子节点之前检查以确保相机节点存在。 (我尝试将此代码添加到 ARKit WWDC17 session 的示例代码中——如果将其放入他们的 ARSCNView.setup() 函数中,您应该会看到您放置的任何虚拟对象都被明亮的聚光灯完全遮挡。)

顺便说一下,您不一定需要向 pointOfView 节点添加子节点来容纳灯 — pointOfView 节点可以同时连接相机和灯。