今年,Apple发布了ARKit 2的新功能。其中之一就是图像检测。这是一个非常酷的功能,允许您在用户的环境中跟踪2D图像,并在其上放置增强现实内容。在本课程中,您将学习如何通过检测您喜欢的任何图像以及如何在呈现模型时更改模型的材质,将您自己的3D模型放置在任何对象之上。
如果这是您的第一个ARKit项目,我强烈建议您阅读我们的ARKit简介,因为我们不会在这里介绍基础知识。
要学习本教程,您需要Xcode 10并确保下载assets文件夹。您可以下载Final Xcode项目,以帮助您与自己的进度进行比较。
如果您运行该应用程序,Apple的太空飞船将出现在您的环境中。这是AR模板。由于我们不需要此场景及其纹理,请单击art.scnassets,删除ship.scn和texture.png。
DeleteAssets
要删除屏幕底部的统计信息,请在ViewDidLoad方法中将此行代码更改为false :
sceneView.showsStatistics = false
拖放iPhoneX.scn和AROriginalScreen.png里面art.scnassets。然后,打开图标文件夹,将所有这些文件夹拖放到Assets.xcassets文件夹中。
https://dl.dropboxusercontent.com/s/lgj0c14pwvf69ox/ImageDetection01.mp4?dl=0
转到ViewController.swift,按住Command + /注释第27行和第30行。我们不需要初始化场景,因为我们刚刚删除了ship.scn,我们需要用空白屏幕启动应用程序。
//let scene = SCNScene(named: “art.scnassets/ship.scn")!
//sceneView.scene = scene
这是一个图像检测应用程序,所以让我们将配置从ARWorldTrackingConfiguration更改为ARImageTrackingConfiguration。
let configuration = ARImageTrackingConfiguration()
我们需要为文件夹名称中的参考图像声明一个变量:AR文件夹中的主要文件夹。这将使我们有一条路径来查找我们的图像。
guard let referenceImages = ARReferenceImage.referenceImages(inGroupNamed: "AR Resources", bundle: Bundle.main) else { return }
让我们创建一个文件夹,其中所有的轨迹图像都将被放置。单击资产目录,右键单击空列并为AR Resources创建一个新文件夹。拖放iPhone Box的图片并将其宽度更改为0.2。
https://dl.dropboxusercontent.com/s/7lkqfoad51ip35b/ImageDetection02.mp4?dl=0
现在我们有参考图像的变量并将我们的图像放在文件夹中,让我们跟踪该图像。我们告诉配置跟踪参考图像,这是AR Resources文件夹。
configuration.trackingImages = referenceImages
configuration.maximumNumberOfTrackedImages = 1
删除ARSCNViewDelegate之后的 /* */
。它将取消注释渲染器:
func renderer(_ renderer: SCNSceneRenderer, nodeFor anchor: ARAnchor) -> SCNNode? {
let node = SCNNode()
return node
}
该渲染器允许您从渲染场景中的节点,所以你就可以将其添加在图像的顶部。
如果检测到图像,它将自动为每个检测到的图像添加一个ARImageAnchor锚点列表。
if anchor is ARImageAnchor {
}
在锚声明中,声明一个具有此大小的平面。我们之所以希望平面的尺寸大于盒子的大小,是因为我们希望标签的错觉漂浮在空中。
let plane = SCNPlane(width: 0.7, height: 0.35)
我们需要将平面链接到场景。最好的方法是创建一个SpriteKit场景(SKS),因为它是一个2D平面。由于盒子的表面是一个平面,SpriteKit场景足以满足我们的需求。将其命名为:DeviceScene,并且为了使浮动标签起作用,您需要单击场景并将其大小更改为(w:1400,h:700)。通过拖放这些元素从媒体库中插入这些图像:ARLeft,ARRight和iPhoneX-Screen。单击场景并将其颜色更改为“ 自定义”,并将不透明度设置为0。
SKS
让我们在平面下面声明我们新的SpriteKit场景并给它起名称:deviceScene。
let deviceScene = SKScene(fileNamed: "DeviceScene")
让我们通过设置我们的deviceScene的内容来定义我们的平面,把它放在双面并将内容翻译成正确的方向。
plane.firstMaterial?.diffuse.contents = deviceScene
plane.firstMaterial?.isDoubleSided = true
plane.firstMaterial?.diffuse.contentsTransform = SCNMatrix4Translate(SCNMatrix4MakeScale(1, -1, 1), 0, 1, 0)
场景的默认定位非常糟糕,这就是我们修复定位的原因。此外,内容只是片面的,我们需要允许内容是双面的。
现在,我们需要一个节点将几何体链接到它中并更改其旋转以匹配其锚定方向。然后,使planeNode成为节点的子节点。
let planeNode = SCNNode(geometry: plane)
planeNode.eulerAngles.x = -.pi / 2
node.addChildNode(planeNode)
声明您的3D模型及其所在的场景。然后,将变量链接到节点。节点的默认定位与框重叠,所以让我们给它一个负间距。然后,将其添加到planeNode。
var iPhoneNode = SCNNode()
let iPhoneScene = SCNScene(named: "art.scnassets/iPhoneX.scn")!
iPhoneNode = iPhoneScene.rootNode.childNodes.first!
iPhoneNode.position = SCNVector3(0, 0, 0.15)
planeNode.addChildNode(iPhoneNode)
恭喜!您刚学会了如何通过检测图像将3D模型放置在您的环境中。在本课程的其余部分,我将教你如何制作动画,以及与按钮的互动。最重要的是,您将玩光照和阴影。