第一:什么是AR
- 增強(qiáng)現(xiàn)實(shí)AR, 將2D或者3D的元素添加到相機(jī)的實(shí)時(shí)視圖中, 就好像 這些元素居住在現(xiàn)實(shí)世界中;
- ARKit結(jié)合了設(shè)備運(yùn)動(dòng)跟蹤,相機(jī)場(chǎng)景拍攝,高級(jí)場(chǎng)景處理和顯示,簡(jiǎn)化了AR體驗(yàn)的任務(wù),這是官方的解釋: 就是讓虛擬內(nèi)容是真實(shí)世界的一部分的錯(cuò)覺。
第二:開發(fā)AR
- 首先要開發(fā)AR, 需要具備A9以上的芯片設(shè)備,iPhone6S以上。
如果app是以AR開發(fā)為主的:請(qǐng)使用應(yīng)用程序Info.plist中ARKit的UIRequiredDeviceCapabilities部分中的鍵。
如果增強(qiáng)現(xiàn)實(shí)是應(yīng)用程序的輔助功能,使用isSupported 來判斷是否支持設(shè)備。 - 其次要理解一個(gè)概念: 在所有AR體驗(yàn)中,ARKit使用坐標(biāo)系,遵循:y軸向上,z軸指向觀察者,x軸指向觀看者的右側(cè)。右手系坐標(biāo)原則: vy6F7b.jpg
這里有篇文章寫的很好 關(guān)于MAC, IOS的坐標(biāo)系。
創(chuàng)建工程

選擇AR.png

WX20171018-180443@2x.png
SceneKit: SceneKit底層實(shí)現(xiàn)使用Metal和OpenGL, 蘋果這個(gè)封裝狂魔封裝起來的一套高性能3D圖形框架;
SpeiteKit: SpeiteKit是Ios7引入的一套主要開發(fā)2D游戲的框架, 通過支持自定義OpenGL ES著色器和照明,可以與SceneKit集成;
Metal: Metal是一套直接訪問圖形處理單元(GPU)編程的高效框架, 非常底層, 接近Metal(金屬板了);
最后點(diǎn)擊next創(chuàng)建好工程:
運(yùn)行后會(huì)通過攝像機(jī)看到有一個(gè)3D的立體模型出現(xiàn)在眼前, 再看代碼:
class ViewController: UIViewController, ARSCNViewDelegate {//VC遵循ARSCNView代理
@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()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Release any cached data, images, etc that aren't in use.
}
}
通過代碼了解一些基本概念。
- SCNView: 主要是顯示SceneKit的3D模型, 顯示3D場(chǎng)景,繼承自UIView; showsStatistics 是否顯示統(tǒng)計(jì)數(shù)據(jù), 場(chǎng)景中最下面的綠條
- ARSCNView:將相機(jī)捕捉到的界面作為3D場(chǎng)景,繼承自SCNView
- ARSession:管理相機(jī)設(shè)備和AR體驗(yàn)所需要的處理的對(duì)象,包括從設(shè)備的運(yùn)動(dòng)感測(cè)硬件讀取數(shù)據(jù),控制設(shè)備的內(nèi)置相機(jī),以及對(duì)捕獲的相機(jī)圖像執(zhí)行圖像分析。會(huì)話綜合了所有這些結(jié)果,以建立設(shè)備居住的真實(shí)世界空間與模擬AR內(nèi)容的虛擬空間之間的對(duì)應(yīng)關(guān)系。簡(jiǎn)單來說調(diào)動(dòng)現(xiàn)實(shí)硬件, 結(jié)合虛擬軟件,建立關(guān)系。通過ARSCNView管理這個(gè)會(huì)話。
- ARCamera:被稱為照相機(jī),通過照相機(jī)捕捉真實(shí)世界的圖像。被ARSession調(diào)用。
- SCNScene:就是在是視圖上所需要放置的場(chǎng)景, 萬物皆場(chǎng)景。是SCNView的屬性;
- SCNNode:稱為節(jié)點(diǎn),場(chǎng)景是由無數(shù)個(gè)節(jié)點(diǎn)組成, 他有自己的位置和坐標(biāo)系統(tǒng),我們會(huì)把幾何模型, 燈光效果等添加到節(jié)點(diǎn)上, 又稱萬物皆節(jié)點(diǎn)。每一個(gè)Scene都有一個(gè)跟節(jié)點(diǎn)rootNode。
-
ARConfiguration:AR會(huì)話配置的的抽象基類:它可以增加AR體驗(yàn),設(shè)置了配置對(duì)象的屬性,并將配置傳遞給會(huì)話的方法。
要運(yùn)行ARSession,首先創(chuàng)建一個(gè)具體的ARConfiguration子類的實(shí)例:
ARKit包括以下具體配置類:
ARWorldTrackingConfiguration
提供高品質(zhì)的AR體驗(yàn),使用后置攝像頭精確跟蹤設(shè)備的位置和方向,并允許平面檢測(cè)和打擊測(cè)試。
AROrientationTrackingConfiguration
提供使用后置攝像頭并僅跟蹤設(shè)備方向的基本AR體驗(yàn)。
ARFaceTrackingConfiguration
提供使用前置攝像頭并跟蹤用戶臉部的移動(dòng)和表情的AR體驗(yàn)。
總結(jié)如下圖:
A548B070-4849-43C4-9756-39CB182B8469.png
通過代碼和概念:可以總結(jié)啟動(dòng)AR的步驟:
- 通過ARSCNView加載SCNScene場(chǎng)景;
- SCNScene啟動(dòng)相機(jī)ARCamera捕捉現(xiàn)實(shí)場(chǎng)景;
- 捕捉場(chǎng)景后ARSCNView將場(chǎng)景數(shù)據(jù)傳遞給ARSession;
- ARSession通過管理ARSessionConfiguration實(shí)現(xiàn)場(chǎng)景追蹤;
- 給ARSCNView的scene添加一個(gè)子節(jié)點(diǎn)(3D物體模型);
寫一個(gè)簡(jiǎn)單Demo, AR播放視頻
- 給一個(gè)本地的視頻url:
override func viewDidLoad() {
super.viewDidLoad()
// Set the view's delegate
sceneView.delegate = self
sceneView.showsStatistics = false;
//本地視頻URL
let bundlePath = Bundle.main.url(forResource: "馴龍記.mp4", withExtension: nil)
//首先創(chuàng)建一個(gè)創(chuàng)景:
let scene = SCNScene()
//創(chuàng)建一個(gè)平面的幾何
let plane = SCNPlane.init(width: 0.664, height: 0.375);
//初始一個(gè)渲染器
let materials = SCNMaterial()
//創(chuàng)建player
let player = AVPlayer.init(url: bundlePath!)
//渲染器擴(kuò)散接受內(nèi)容
materials.diffuse.contents = player
//設(shè)置渲染器
plane.materials = [materials]
//設(shè)置節(jié)點(diǎn)
let node = SCNNode(geometry: plane)
//節(jié)點(diǎn)位置
node.position = SCNVector3(0, 0, -1.0)
//設(shè)置根節(jié)點(diǎn)
scene.rootNode.addChildNode(node);
//播放
player.play()
sceneView.scene = scene
}
完成
其中
node.position = SCNVector3(0, 0, -1.0)
坐標(biāo)z軸, 正值朝向觀察者, 負(fù)值是正面可以觀察到的;
渲染器接受到的內(nèi)容:
materials.diffuse.contents = ?
//可以是一種顏色(NSColor,UIColor,CGcolorRef)
//可以是圖像(NSImage, UIImage, CGImageRef)
//可以是CALayer
//可以是路徑 (NSString or NSURL)
//可以是場(chǎng)景SKScene SKTexture
//可以是二維碼: AVCaptureDevice;( iOS 11以上)
//可以是AVPlayer;
//設(shè)置顏色的動(dòng)畫

