AR与SceneKit和Metal

2020-12-11 07:47:13

最近,我发现自己需要使用ARKit在iOS应用程序中处理和可视化点云和网格,并使用2020 iPad“ LiDAR”传感器收集点云。为了实现最佳性能和内容创建便利性,我认为最好同时提供自定义着色器和常规的易于使用的3D层次结构。最好的选择似乎是Metal和SceneKit,它们需要一些初始设置才能协同工作。该设置在本文中详细介绍。

如果这一切听起来都不熟悉,请在此处,此处和此处查看这些技术的介绍。

为了帮助您重新创建我所做的工作,该帖子随附了一个GitHub存储库,其中显示了详细信息:github.com/emllnd/ar-with-scenekit-and-metal。

请注意,回购使用了一些令人困惑的命名。 XCode项目的名称是“ smTest”(对于“ SceneKit Metal测试”),这导致诸如smTestTest之类的组合用于自动生成的单元测试项目……不是最佳选择,但请耐心等待。

另请注意,这并不是真正的初学者级内容,通常也不需要SceneKit和Metal渲染。如果您只想在iOS上做一些3D + AR,那么最好的入门技术可能是RealityKit + RealityComposer,更广泛使用的工具Unity或普通的SceneKit。

为了帮助您重新创建我所做的工作,该帖子随附了一个GitHub存储库,其中显示了详细信息:github.com/emllnd/ar-with-scenekit-and-metal。

请注意,回购使用了一些令人困惑的命名。 XCode项目的名称是“ smTest”(对于“ SceneKit Metal测试”),这导致诸如smTestTest之类的组合用于自动生成的单元测试项目……不是最佳选择,但请耐心等待。

另请注意,这并不是真正的初学者级内容,通常也不需要SceneKit和Metal渲染。如果您只想在iOS上做一些3D + AR,那么最好的入门技术可能是RealityKit + RealityComposer,更广泛使用的工具Unity或普通的SceneKit。

RealityKit似乎是未来,但我对运行时自定义网格的形状感兴趣,例如几何着色器,并且似乎还没有(真的吗?)用于将这种处理集成到RealityKit中的钩子。

事实证明,这些钩子确实存在于SceneKit中,这是一种更老更成熟的技术。它们可用于在常规渲染之前或之后实施自定义渲染步骤。可以在以下位置找到一篇有用的博客文章,其中包含有关“渲染器didRenderScene”挂钩的详细信息,它们对我有所帮助:SceneKit中的自定义金属制图。感谢您撰写Ippel先生!

我选择通过将Apple的两个示例应用程序融合在一起来开始结合ARKit,SceneKit和自定义Metal渲染:

XCode项目向导创建的默认SceneKit AR项目(创建步骤如下所示)

最棘手的部分是使深度融合正常工作。 SceneKit和Point Cloud演示的自定义Metal渲染器使用了不同的深度缓冲约定,这在我意识到必须调整深度设置以使其兼容之前引起了最初的困惑。

为了使深度混合表现良好且一致,需要设置适当的深度混合模式(在XCode Frame Debugger中显示为DepthStencilState –> DepthCompareFunction),以找到两个深度缓冲区的匹配值范围并保留3D场景。渲染器中的两个渲染器都处于各自的视锥中(对于znear和zfar具有良好的值),因此它们不会因太近或太远而被淘汰。

如果您在最近的Apple开发环境中的一个相当空的项目中工作,则很有可能立即就开始进行GPU调试。您只需要构建并运行您的应用,然后按相机图标(然后稍等):

如果您需要更深入的GPU调试选项或上手时遇到麻烦,可以在关于Frame Capture调试工具的页面以及启用Frame Capture的指南页面上找到更多信息。

有关如何组合两个渲染器的更多详细信息,请参见示例存储库的提交页面上的前几次提交(11月24日和28日)中包含的更改。它显示了我的历史:

根据Ippel先生的帖子添加了自定义的Metal渲染(绘制简单的三角形,...)

复制到SceneDepthPointCloud演示中,并确保仍在构建应用程序(使用SceneDepthPointCloud进行构建...)

弄乱了累积设置等,以使事情更接近工作(几乎可以工作……)

并最终调整了深度融合,深度范围和摄像机视锥设置,以便能够同时看到两个场景(改进了…,同时绘制了两个……)

所有这些步骤的最终结果可以在下面看到。 当然,这仅仅是更有趣的应用程序的起点,该应用程序利用常规3D资产工作流的简便性和速度,并根据需要有选择地应用自定义GPU处理的功能。 在此文章首次发布时(2020年12月),我不确定两个渲染器之间的深度缓冲区是否完全同步,即使它们确实同时渲染也是如此。 点云在火箭飞机(?😄)的后面看起来还不错,但是我不确定它们在重叠情况下是否正确运行。 但是,解决方法应该仅仅是调整相机和深度缓冲区参数以及可能的场景比例(著名的遗言……)。 如果时间允许,我将使用改进的详细信息更新帖子和存储库。