ARKit – 如何显示来自放置在 SCNPlane 上的虚拟 SCNCamera 的源?

2023-12-09

我使用 ARKit 和 SceneKit 将一些对象放入 AR 空间中。效果很好。现在我想添加一个额外的摄像机 (SCNCamera),该摄像机放置在场景中的其他位置,由公共 SCNNode 连接和定位。它旨在从另一个(固定)角度向我展示当前场景。

现在我想在 i.Ex 上展示这个额外的 SCNCamera feed。 SCNPlane(作为漫反射第一种材质)- 就像电视屏幕一样。当然,我知道它只会显示位于相机焦点中的 SceneKit 内容,而不显示 ARKit 图像的其余部分(当然这只能由主相机实现)。那么简单的彩色背景就可以了。

我看过描述如何在 ARSpace 中的虚拟显示器上播放视频文件的教程,但我需要来自我自己当前场景的实时摄像机反馈。

我定义了这个对象:

let camera = SCNCamera()
let cameraNode = SCNNode()

然后在 viewDidLoad 中我这样做:

camera.usesOrthographicProjection = true
camera.orthographicScale = 9
camera.zNear = 0
camera.zFar = 100
cameraNode.camera = camera
sceneView.scene.rootNode.addChildNode(cameraNode)

然后我调用我的设置函数,将虚拟显示器放置在我所有 AR 东西旁边,同时定位相机节点(指向对象在场景中停留的方向)

cameraNode.position = SCNVector3(initialStartPosition.x, initialStartPosition.y + 0.5, initialStartPosition.z)

let cameraPlane = SCNNode(geometry: SCNPlane(width: 0.5, height: 0.3))
cameraPlane.geometry?.firstMaterial?.diffuse.contents = cameraNode.camera
cameraPlane.position = SCNVector3(initialStartPosition.x - 1.0, initialStartPosition.y + 0.5, initialStartPosition.z)

sceneView.scene.rootNode.addChildNode(cameraPlane)

一切都编译并加载...显示显示在给定位置,但它保持完全灰色。我放在场景中的 SCNCamera 根本没有显示任何内容。 AR 场景中的其他一切都运行良好,只是我没有从该摄像头获得任何反馈。

Gray plane instead of camera feed

有谁有办法让这个场景发挥作用吗?

为了更好地可视化,我添加了一些更多的打印屏幕。

下面显示了根据 ARGeo 输入的 SCNCamera 的图像。但它需要整个屏幕,而不是像我需要的那样在 SCNPlane 上显示其内容。

View from the SCNCamera

下一个打印屏幕实际上显示了我使用发布的代码获得的当前 ARView 结果。正如您所看到的,灰色显示平面仍然是灰色的 - 它什么也不显示。

Current AR View

最后一个打印屏幕是蒙太奇照片,显示了我想要得到的预期结果。

Expected or Desired AR View

这怎么能实现呢?我在这里错过了一些基本的东西吗?


经过一番研究和睡眠后,我得出了以下可行的解决方案(包括一些无法解释的障碍):

目前,附加的 SCNCamera feed 未链接到 SCNPlane 上的 SCNMaterial,因为这是最初的想法,但我将使用附加的 SCNView(目前)

在定义中我添加了另一个视图,如下所示:

let overlayView   = SCNView() // (also tested with ARSCNView(), no difference)
let camera        = SCNCamera()
let cameraNode    = SCNNode()

然后,在 viewDidLoad 中,我设置了这样的东西......

camera.automaticallyAdjustsZRange = true
camera.usesOrthographicProjection = false
cameraNode.camera                 = camera
cameraNode.camera?.focalLength    = 50
sceneView.scene.rootNode.addChildNode(cameraNode) // add the node to the default scene

overlayView.scene                    = scene // the same scene as sceneView
overlayView.allowsCameraControl      = false
overlayView.isUserInteractionEnabled = false
overlayView.pointOfView              = cameraNode // this links the new SCNView to the created SCNCamera
self.view.addSubview(overlayView)    // don't forget to add as subview

// Size and place the view on the bottom
overlayView.frame  = CGRect(x: 0, y: 0, width: self.view.bounds.width * 0.8, height: self.view.bounds.height * 0.25)
overlayView.center = CGPoint(x: self.view.bounds.width * 0.5, y: self.view.bounds.height - 175)

然后,在其他一些函数中,我将包含 SCNCamera 的节点放置到我想要的位置和角度。

// (exemplary)
cameraNode.position = initialStartPosition + SCNVector3(x: -0.5, y: 0.5, z: -(Float(shiftCurrentDistance * 2.0 - 2.0)))          
cameraNode.eulerAngles = SCNVector3(-15.0.degreesToRadians, -15.0.degreesToRadians, 0.0)

结果是屏幕底部出现一种窗口(新的 SCNView),显示与主场景视图中相同的 SceneKit 内容,通过 SCNCamera 的视角及其节点位置进行查看,效果非常好。

Main AR view plus additional view from other perspective

在常见的 iOS/Swift/ARKit 项目中,这种构造会产生一些可能难以解决的副作用。

1) 主要是,新的 SCNView 从所需的角度显示 SceneKit 内容,但背景始终是实际的物理摄像机源。我无法弄清楚如何通过仍然显示所有 SceneKit 内容来使背景成为静态颜色。更改新场景的背景属性也会影响整个主场景,这实际上是不希望的。

2)这可能听起来令人困惑,但是一旦包含以下代码(这对于使其工作至关重要):

overlayView.scene = scene

整个场景的动画速度(两者)双倍! (为什么?)

我通过添加/更改以下属性来纠正此问题,该属性几乎恢复了动画速度行为(默认):

// add or change this in the scene setup
scene.physicsWorld.speed = 0.5

3)如果项目中有像 SCNAction.playAudio 这样的动作,所有效果将不再播放 - 只要我不这样做:

overlayView.scene = nil

当然,附加的 SCNView 停止工作,但其他一切都会恢复正常。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

ARKit – 如何显示来自放置在 SCNPlane 上的虚拟 SCNCamera 的源? 的相关文章

随机推荐

  • 在任务管理器中更改程序进程名称?

    好吧 我一直在四处寻找 但在任何地方都找不到答案 我希望我的程序做的是每次运行它时 任务管理器中显示的名称都是随机的 有一个名为 Liberation 的程序 当您运行它时 它会将进程名称更改为一些随机字符 例如 AeB4B3wf52 tm
  • 使用 maxLines 选取框

    如何使用 MaxLines 而不是 SingleLine 来制作选取框 这是我的 TextView
  • MySQL:用户“user”@“IP_ADDRESS”的访问被拒绝 - 允许某些主机的远程访问对其他主机失败

    背景 我可以从某些子网访问 mysql 实例 但不能从其他子网访问 至少看起来是这样 网络上的机器10 0 21 xx能够连接到 MySQL 实例 但从10 0 7 xx I get 使用密码的用户访问被拒绝 有趣的是 MySQL 安装在与
  • 动态访问 PHP 数组

    我尝试访问 this gt arrDataName key 在带有键的元素上 key从数组 this gt arrDataName 但 PHP 解释错误 我尝试过 周围的 arrDataName to this gt arrDataName
  • 我可以强制报表顶部的图表始终可见吗

    我有以下报告 In Excel我会用一个叫做Freeze Pane在图表下方 这意味着当用户向下滚动时 表格将滚动 但图表将始终保持可见 是否可以在中实现此行为RS EDIT 注 图表和tablix使用不同Datasets 是的 您可以通过
  • 从设计角度应该如何对待 CouchDB 修订版?

    据我所知 CouchDB 修订版不应被视为文档版本控制这个词的意义 从其他帖子来看 它们似乎被视为暂时数据 直到粗粒度的数据出现为止 compact操作称为 我的问题是 如果我有兴趣使用 CouchDB 来维护文档以及这些文档的版本历史记录
  • 如何为history.pushState和replaceState设置“默认”值?

    对于使用的浏览器titleparam 我们应该使用什么值来告诉浏览器使用其默认值 In Safari 5 1 7 7534 57 2 if I put null or undefined as the title param it uses
  • Haskell:在不使用spawn的情况下分割管道(广播)

    这个问题有点代码高尔夫 而且很新鲜 我正在使用很棒的pipesHaskell 中的库 我想拆分一个管道以沿多个通道发送相同的数据 进行广播 这Pipes Concurrent教程建议使用spawn创建邮箱 利用Output的幺半群状态 例如
  • 查找视图依赖的所有表[重复]

    这个问题在这里已经有答案了 我有一个 Oracle 视图 我想找到我的视图所依赖的所有表 可能 我的视图依赖于其他视图 在这种情况下 我想递归地导航依赖项并访问表 这是我的架构的示例 CREATE TABLE T1 A NUMBER CRE
  • 如何获取当前页面中显示的所有项目?

    For the 官方示例多选时 如果设置每页显示 50 行并单击标题行中的全选复选框 则实际上表中的所有行都被选中 问题是我只想选择当前页面中的所有行 有什么方法可以实现吗 我不想手动单击每一行 我为你想要实现的目标创建了一个演示 http
  • 如何从字符串[]中删除非字母字符? [复制]

    这个问题在这里已经有答案了 这是代码 StringBuilder sb new StringBuilder Regex rgx new Regex a zA Z0 9 var words Regex Split textBox1 Text
  • SFENCE 是否会阻止存储缓冲区隐藏来自 MESI 的更改?

    如果 Core 进行写入 但其 L1 中不存在缓存行 则它会写入存储缓冲区 另一个 Core 请求该缓存行 MESI 无法看到存储缓冲区更新并返回未修改的缓存行 存储缓冲区不久后被刷新 但第二个核心已经使用旧值 我不明白如何SFENCE解决
  • 比较 DOM 节点与 DOM 元素

    我在解决这个问题时遇到了一些麻烦 我知道 DOM 中的所有内容都是一个节点 并且 DOM 元素也是一个节点 然而 我的问题是 我有一个 DOM 节点和一个 DOM 元素 我需要比较它们以查看它们是否引用相同的元素 这可能吗 我认为我的问题有
  • 保存领域关系并不会使它们持久化

    我有一个清单articles 这些文章是通过使用插入的realm copyToRealmOrUpdate 效果非常好 现在每篇文章都有一个不应该被持久化的authorId 相反 我想找到存储的作者 RealmObject并设置其与文章的关系
  • Android ViewPager 中心项目更大

    我想创建一个 ViewPager 选定的中心项目比其他项目大 上一个和下一个项目的部分始终可见 我在用viewPager setPageMargin 20 使上一个和下一个项目的一部分可见 但是 如何使选定的中心项目比其他项目稍大一些 您可
  • 有没有我可以使用的 Subversion Web 客户端

    我想在 Linux 首选 或 Windows 上安装 svn Web 客户端 我只需要只读功能 不需要提交 并且我希望能够使用 diff 来比较修订版本 我的 svn 服务器在另一台机器上 因此 Web 服务器需要通过 http 访问它 也
  • 链接到更高级别文件夹中的文件

    我在提供比我的根文件夹级别更高的文档时遇到问题 a href home folder document docx Proposal a 在浏览器中 上面的内容被解释为 http localhost home folder document
  • 连接文件夹中的大量文件时参数列表太长

    这是一个将多个相同模式文件连接成一个大文件的命令 在文件夹中我有 77k 个文件 我得到Argument list too long 示例文件名是每分钟 cartreset 2014 05 08 01 12 log rm f tmp tem
  • Chrome 开发工具 - “大小”与“内容”

    在 Chrome 开发工具的 网络 选项卡中查看有关样式表的信息时 一列指定 大小 和 内容 有人能解释一下这两个数字之间的区别吗 在某些页面上 数字很接近 而在其他页面上 数字则相差相当大 大小 是线路上的字节数 内容 是资源的实际大小
  • ARKit – 如何显示来自放置在 SCNPlane 上的虚拟 SCNCamera 的源?

    我使用 ARKit 和 SceneKit 将一些对象放入 AR 空间中 效果很好 现在我想添加一个额外的摄像机 SCNCamera 该摄像机放置在场景中的其他位置 由公共 SCNNode 连接和定位 它旨在从另一个 固定 角度向我展示当前场