ARKit 演示:增强现实电影制作
已发表: 2022-03-11AR 和 VR 正在成为主流,所有顶级的高科技公司都在追求它们:苹果有 ARKit,谷歌有 ARCore,微软有自己的 HoloLens(当然还有 Unity)。 随着一些应用程序受到公众的广泛关注,增强现实应用程序开发正成为移动开发人员非常渴望的技能。
在本文中,我想演示一个简单但有意义的小应用程序,它不仅仅具有一个旋转立方体。 谁还需要旋转立方体? 让我们制作矩阵。
ARKit 简介
ARKit 是一个 Apple 框架,用于为 iOS 设备创建 AR 应用程序。 可以使用多个渲染器:SpriteKit 用于 2D 对象,SceneKit 用于 3D,如果我们想要实现自定义渲染器,则可以使用 Metal。
对于这个演示,我们将使用 SceneKit 来渲染和放置完全渲染的 3D 对象(刀)。
从 ARKit v2 开始,ARKit 支持五种类型的配置:
AROrientationTrackingConfiguration – 当您只想跟踪设备的方向时(例如,对于星座应用程序)。 使用这种配置,不会跟踪像侧步这样的物理运动,也不会影响场景中对象的位置或方向。
ARWorldTrackingConfiguration——这可能是 AR 最常用的配置,因为它支持大多数人认为的增强现实。 示例包括虚拟宠物或口袋妖怪狩猎应用程序。
ARFaceTrackingConfiguration – 此配置目前仅受 iPhone X 支持,因为它需要 TrueDepth 摄像头(如 Face ID)。 此配置跟踪面部特征及其与中性面部表情的相对偏移(例如,用户可以在订购前试用时尚太阳镜的应用程序)。
ARImageTrackingConfiguration – 如果您有一组标记并且想要显示动物跳出标记,那么此配置适合您。 这些不必是卡片式标记,而是任何 2D 图片。 你可以把相机对准蒙娜丽莎,她会转过头告诉你一些事情。 一个缺点是您必须事先说明图像标记的物理尺寸是多少。
ARObjectScanningConfiguration – 此配置是 ARImageTrackingConfiguration 的 3D 版本。
在这个演示中,我们将在场景中添加刀具和子弹,我们希望有六个自由度,因此合适的工具是 ARWorldTrackingConfiguration。
应用概念
每个看过《黑客帝国》的人都记得尼奥(基努·里维斯饰)躲避子弹并在半空中阻止他们。 我们的应用程序将帮助我们从实时摄像机源中重新创建这个场景。 因此,我们可以创建自定义视频来展示类似 Neo 的能力。
我们的应用程序将有子弹和刀具的 3D 模型。 电影中需要多少子弹或刀具取决于用户。 如果您想花一些时间添加其他模型,应用程序代码是开源的,可以在 GitHub (https://github.com/altaibayar/toptal_ar_video_maker) 上找到。 虽然这不是一个完整的 AR 教程,但如果您尝试在 iOS 上进行 AR 应用程序开发,那么演示和源代码应该是很有价值的资源。
预期的用例场景如下:
- 让一个朋友装扮成 Neo(对于应用程序的运行不是绝对必要的,但在我们这样做的时候最好看起来不错)。
- 让“Neo”站在离您约 10 米(30 英尺)的地方。
- 启动应用程序并扫描地平面。
- 添加在“Neo”处飞行的子弹和刀具。
- 按住录制按钮录制视频,同时“Neo”执行一些很酷的动作来躲避或阻止子弹
- 释放录制按钮并将视频保存到您的库中。
构建应用程序
如前所述,我们希望能够在记录所有 360 度场景的同时自由移动,并让子弹和刀具适当地跟踪摄像机运动。
出于演示目的,我们将只有两种类型的虚拟对象:刀和霰弹枪子弹。
刀是详细的对象,我将使用来自 https://poly.google.com/view/3TnnfzKfHrq 的免费模型(感谢 Andrew)。
然而,霰弹枪子弹是简单的球形物体,我们可以简单地对它们进行编码。我们将把它们做成金属的和炽热的以增加多样性。 由于我们正在模拟霰弹枪,我们还将它们生成为分组集群。 为了让聚类不费力,我们可以使用 GamplayKit 中的高斯随机数生成器。

GameplayKit 是一个有用的工具,只要您需要随机噪声生成、状态机、人工智能或基于概率的决策,它就会派上用场。
override init() { super.init(); // generate 50 gaussian distributed position around [0, 0, 0] let positions = Randomness.gaussian(center: SCNVector3Zero, count: 50); for pos in positions { let node = SCNNode(geometry: sphereGeometry()); node.position = pos; self.addChildNode(node); } } private func sphereGeometry() -> SCNGeometry { // radius of one projectile sphere is 5mm/0.2inch let sphere = SCNSphere(radius: 0.005); // sphere is reddish sphere.firstMaterial?.diffuse.contents = UIColor.red; // reflection on light is gray/silver sphere.firstMaterial?.reflective.contents = UIColor.gray; // metalness is 0.3 sphere.firstMaterial?.metalness.contents = 0.3; // shading should be realistic sphere.firstMaterial?.lightingModel = .physicallyBased; return sphere; }
类似的随机偏移逻辑可用于刀具,但由于它们不表现为集群,因此可以使用简单的随机分布。
应用架构
深入讨论哪种架构范式是最好的,超出了这个演示的范围。 有许多文章深入探讨了该主题。
相反,我只会列出项目的结构,作为找到链接的 GitHub 项目的指南:主要组件是什么,它们是如何连接的,以及为什么选择它们。
该应用程序只有三个屏幕:
PermissionViewController – 我们要求用户授予应用程序访问所需移动功能的屏幕。
- 相机——显然
- 图库- 保存录制的视频和麦克风输入
- 麦克风- 我用来创建视频的库需要权限(默认情况下,来自麦克风的声音将用作音轨的来源)。
ExportViewController – 此屏幕显示录制的视频并提供共享或保存视频的选项。
MainViewController – 所有的魔法都发生在这里。
根据我的经验,最好包装所有必要的 ARKit 类,如 ARSession、ARConfiguration 和所有独特类型的 SCNNode。 这样,代码是不言自明的。
ARSession 被继承到 ToptalARSession 中,新的会话类只有三个方法:我们设置所需的所有内容的类构造函数以及 resetTracking 和 pauseTracking 方法。
该应用程序识别四种独特类型的 SCNNode:
- KnifeNode – 表示刀 3D 对象,并自动加载 3D 刀作为其几何图形。
BulletsNode – 此节点代表一组霰弹枪弹。 随机高斯噪声、颜色和物理照明模式是自动设置的。
使用 KnifeNode 或 BulletsNode 的类不需要特殊或额外的工作,它们可以用作自定义应用程序以添加更多种类的 3D 对象的模板。
- ReticleNode – 包裹一个 3D 模型,该模型出现在地板上方的场景中,以显示将添加刀具或子弹的位置。
- DirectionalLightNode – 这是一个代表垂直光指向下方的节点。
参考文献和学分
刀型号:https://poly.google.com/view/3TnnfzKfHrq
从 SCNScene 录制:https://github.com/svtek/SceneKitVideoRecorder
按钮图标,ARKit 演示应用程序:https://developer.apple.com/documentation/arkit/handling_3d_interaction_and_ui_controls_in_augmented_reality