AR技术
增强现实(Augmented Reality,简称 AR),是一种实时地计算摄影机影像的位置及角度并加上相应图像的技术,这种技术的目标是在屏幕上把虚拟世界套在现实世界并进行互动。
一个最简单地AR场景实现所需要的技术以及步骤包含如下
1.多媒体捕捉现实图像:如摄像头
2.三维建模:3D立体模型
3.传感器追踪:主要追踪现实世界动态物体的六轴变化,这六轴分别是X、Y、Z轴位移及旋转。其中位移三轴决定物体的方位和大小,旋转三周决定物体显示的区域。
4.坐标识别及转换:3D模型显示在现实图像中不是单纯的frame坐标点,而是一个三维的矩阵坐标。这基本上也是学习AR最难的部分,好在ARKit帮助我们大大简化了这一过程。
5.除此之外,AR还可以与虚拟物体进行一些交互。
ARKit概述
1.ARKit是2017年6月6日,苹果发布iOS11系统所新增框架,它能够帮助我们以最简单快捷的方式实现AR技术功能。
2.ARKit框架提供了两种AR技术,一种是基于3D场景(SceneKit)实现的增强现实,一种是基于2D场景(SpriktKit)实现的增强现实
3.要想显示AR效果,必须要依赖于苹果的游戏引擎框架(3D引擎SceneKit,2D引擎SpriktKit),主要原因是游戏引擎才可以加载物体模型。
目前ARKit框架本身只包含相机追踪,不能直接加载物体模型
4.ARKit虽然是iOS11新出的框架,但并不是所有的iOS11系统都可以使用,而是必须要是处理器A9及以上才能够使用,苹果从iPhone6s开始使用A9处理器,也就是iPhone6及以前的机型无法使用ARKit
初识ARKit
1, 我们先创建一个AR3D项目
2, 项目中的代码
@IBOutlet var sceneView: ARSCNView!
override func viewDidLoad() {
super.viewDidLoad()
// Set the view's delegate
sceneView.delegate = self
// Show statistics such as fps and timing information
sceneView.showsStatistics = true
// Create a new scene
let scene = SCNScene(named: "art.scnassets/ship.scn")!
// Set the scene to the view
sceneView.scene = scene
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
// Create a session configuration
let configuration = ARWorldTrackingConfiguration()
// Run the view's session
sceneView.session.run(configuration)
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
// Pause the view's session
sceneView.session.pause()
}
3, 代码中用到了哪些类
// 该视图可以绘制相机背景,提供和更新相机,管理锚点的节点,并更新照明
ARSCNView
// 该类用于描述3d场景。 它封装了一个节点层次结构
SCNScene
/*
继承自ARConfiguration。ARConfiguration用于描述和配置在ARSession中使用的增强现实技术。
不过苹果建议使用ARWorldTrackingConfiguration。
世界跟踪提供设备的6个自由度跟踪(X、Y、Z轴位移及旋转)
通过在场景中查找特征点,世界跟踪可以对框架执行命中测试(hitTest)。
会话暂停后,无法继续追踪。
*/
ARWorldTrackingConfiguration
/*
在设备上配置并运行不同的增强现实技术。在视图中用于更新场景。
*/
ARSession
这些类都非常重要,需要特别指出的是SCNScene
并不是ARKit中的类,而是SceneKit中的类。
4, 归类总结与实战
ARKit主要跟设备有关,主要作用是跟踪摄像头,【获取现实中的图像与3D建模应该也是该框架完成的】。而整个3D场景由SceneKit解决。
下面给出两张图,再做一个demo应该就差不多能达到初识程度了。
demo:在现实中添加一个星球。通过手指点击,可切换星球,通过手指移动能移动星球。代码详情:https://github.com/taoGod/ARKit1.git
override func viewDidLoad() {
super.viewDidLoad()
// 1、创建scene
let scene = SCNScene()
// 4、创建几何形
let sphere = SCNSphere(radius: 0.1)
// 5、制作几何形的材料
let material = SCNMaterial()
material.diffuse.contents = UIImage(named: "earth")
sphere.materials = [material]
// 3、创建节点,设置节点位置,添加进scene
node = SCNNode(geometry: sphere)
node.position = SCNVector3(0, -0.05, -0.5)
scene.rootNode.addChildNode(node)
// 2、将scene设置为sceneView的scene
sceneView.scene = scene
// 添加手势
let tapGes = UITapGestureRecognizer(target: self, action: #selector(tapGesAction(_:)))
sceneView.addGestureRecognizer(tapGes)
}
@objc fileprivate func tapGesAction(_ tapGes: UITapGestureRecognizer) {
let sceneView = tapGes.view as! ARSCNView
let touchLocation = tapGes.location(in: sceneView)
let hitResults = sceneView.hitTest(touchLocation, options: [:])
if !hitResults.isEmpty {
if currentIndex == imageNames.count {
currentIndex = 0
}
guard let hitResult = hitResults.first else {return}
let node = hitResult.node
node.geometry?.firstMaterial?.diffuse.contents = UIImage(named: imageNames[currentIndex])
currentIndex += 1
}
}
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
// 平面移动
guard let touch = touches.first else {
return
}
let preLocation = touch.previousLocation(in: sceneView)
let location = touch.location(in: sceneView)
let x = Float(location.x - preLocation.x)
let y = Float(location.y - preLocation.y)
let position = node.position
node.position = SCNVector3(position.x + x/1000, position.y - y/1000, -0.5) // 垂直方向是反的
}
ARSCNView.hitTest
:可通过获取屏幕的一个点所在一条线上的所有节点
SCNVector3
:三分量矢量的表示。在这里描述节点的3D位置。
SceneKit使用三分量向量用于各种目的,例如描述节点或顶点位置,表面法线,缩放或平移变换。 应该根据使用向量的上下文来解释不同的向量组件。