1. ARKit 工作流程
ARkit 是一個業(yè)界領先的AR框架, 先簡單介紹一下AR的原理. 基本上ARKit工作的流程是:
- 從攝像頭觀察周圍環(huán)境, 并構建環(huán)境的基本模型, 這樣, 我們得到一個現(xiàn)實空間的簡單描述.
- 將手機中的虛擬空間和現(xiàn)實空間進行"對齊"
- 在手機的虛擬空間放置的物件, 就能在現(xiàn)實空間中顯示了.
我們很大部分的創(chuàng)作在于虛擬空間的搭建和編程上, 當我們得到一個虛擬的空間, ARKit的強大能力就能夠幫助我們將這個虛擬的空間疊加到現(xiàn)實空間中, 在你的屏幕上實現(xiàn)增強現(xiàn)實的魔法!
2. 搭建虛擬空間 - 場景 (Scene)
1 ) 場景的組成
ARKit中, 上面提到虛擬空間稱為場景(Scene). 場景通過節(jié)點(Node)組成
打個比喻, 場景就是電影的錄影廠, 燈光, 演員, 道具都可以稱為一個節(jié)點. 并可以成為一定的層級關系 ( 如果你有數(shù)據(jù)結構的基礎, 節(jié)點間的關系其實是來自于一個根節(jié)點的樹 ), 舉個例子

不過當然, 你的Scene不一定是電影拍攝這樣的語境, 我們可以很自由地進行組織, 不必拘泥例子中的結構
2 ) Demo - 如何構建一個場景
下面就通過Apple官方的Starter Project進行解釋如何構建一個場景
首先, 我們創(chuàng)建一個AR 項目,

然后在Content Technology中選取SceneKit

這樣我們得到一個簡單的 AR app, 它是直接就能運行的
代碼中的sceneView很重要:
@IBOutlet var sceneView: ARSCNView!
它是一個 ARSCNView, 這個是一個用于展示AR物件的視圖, 負責渲染, 相當于AR的前端
sceneView顧名思義, 其實就是"to view a scene", 沒錯就是展示場景, 它顯示什么場景由它的.scene屬性決定, 下面介紹兩個設置它的方式
- 方式1 -
XCode提供的初始代碼是第一種設置方式:
let scene = SCNScene(named: "art.scnassets/ship.scn")!
sceneView.scene = scene
即通過直接設置sceneView的scene來展示預先搭建的.scn文件, Xcode的默認AR項目中這個.scn文件是一個飛船模型, .scn格式文件是在Xcode中創(chuàng)作的三維文件, 除了這個格式,我們也可以傳入其他三維格式的作品

這是一個很簡單的方式, 優(yōu)點是可以讓編程和虛擬物件的創(chuàng)作這兩個流程較好地分離, 如果你是一名CG設計師, 那這個方式就很直接方便了
- 方式2 -
我們上面提到, 場景由節(jié)點組成, 所以第二種我要介紹的, 就是增量地進行節(jié)點的添加, 為了說明這個方法, 我們可以嘗試從一個一無所有的sceneView開始
我們先將Xcode的默認AR項目中刪除飛船的資源文件, 也就是清空art.scnassets中的文件

然后去掉ViewDidLoad()中設置sceneView.scene的代碼. 然后我們?nèi)牧汩_始用代碼搭一個場景
我們嘗試制作一個棒棒糖, 這里創(chuàng)建一個makeLollipop函數(shù), 在這個函數(shù)中, 我們給sceneView的根節(jié)點綁定一個子節(jié)點, 用來后續(xù)存放棒棒糖的結構
func makeLollipop(_ x: Float, _ y: Float, _ z: Float) {
let lollipopNode = SCNNode()
sceneView.scene.rootNode.addChildNode(lollipopNode)
}
然后我們可以增量地添加棒棒糖的幾個實體, 一個是糖球, 一個是糖棒
func makeLollipop(_ x: Float, _ y: Float, _ z: Float) {
let lollipopNode = SCNNode()
sceneView.scene.rootNode.addChildNode(lollipopNode)
// add candy
let candyNode = SCNNode(geometry: SCNSphere(radius: 0.05))
candyNode.position = SCNVector3(x, y, z)
lollipopNode.addChildNode(candyNode)
// add stick
let stickNode = SCNNode(geometry: SCNCylinder(radius: 0.008, height: 0.3))
stickNode.position = SCNVector3(x, y-0.15, z)
lollipopNode.addChildNode(stickNode)
}
這里我用了快速創(chuàng)建簡單幾何體的函數(shù), 它們還是比較直觀的, 這里不多作解釋了, 步驟基本是:
上面, 我們通過增量的方式, 構建了這樣一個場景結構:
- 創(chuàng)建節(jié)點, 這個時候可以指定節(jié)點中的幾何體
- 將節(jié)點加入到你選定的父節(jié)點中
注: 幾何體也可以來自于預先搭建好的三維文件

效果:

關鍵:
你完全可以結合上述兩種方法來搭建場景, 其實兩種方法都是基于節(jié)點的結構的當你用Xcode創(chuàng)建的三維實體, 節(jié)點的關系能夠被很好的解析, 其他軟件制作的可能需要進行一定的拆分和組織, 所以我們也需要學會通過指定
geometry參數(shù)來創(chuàng)建SCNNode()的方法
3. 現(xiàn)實空間的要素
1 ) AR攝像機
文檔: ARCamera
這個攝像機的定義和CG概念上的攝像機類似, 它包含一個攝像機的三維位置信息, 旋轉(zhuǎn)姿態(tài)信息, 現(xiàn)實空間各個點和這個攝像機的相對位置對于描述這個現(xiàn)實空間是很關鍵的
2 ) AR 幀
文檔: ARFrame
現(xiàn)實空間的基本輸入首先就是一幀幀的圖像, 在ARKit中, 除了基本的像素信息, 它還包含了設備的三維空間的位置信息, 環(huán)境的跟蹤信息等等, 得到ARFrame需要用到的硬件不只是攝像頭, 還需要運動傳感器
3 ) 特征點 ( 點云 )
文檔: rawFeaturePoints
ARPointCloud
當你移動你的設備時, 攝像頭會分析視頻幀并搜集環(huán)境中一些有代表性的特征點, 有時可能是角點 ( 指尖, 桌角, 屏幕的角, 鍵盤鍵粒, 文字邊緣等等 ), 有時可能是紋理 ( 木紋, 衣物皺褶, 纖維 ), 也有可能是色彩轉(zhuǎn)折 ( 比如地面和墻面 ). 我不知道Apple用的特征點檢測算法有哪些, 但是你可以去了解一下常見的幾個算法
特征點的跨幀匹配是ARKit對世界描述的很關鍵的步驟, 比如說, 你在一個幀中用上了一個鈕扣上的特征點, 如果你能在后面的幀也能找到鈕扣的特征點并成功匹配, 你就能得到這個鈕扣在三維空間的位置估計
當你的點不止一個而是很多的時候, 你對這個空間的描述就更加準確. 當然, 當前這個技術不能做到完美, 所以很多時候AR還是會"飄", ARKit 的文檔也提到
ARKit does not guarantee that the number and arrangement of raw feature points will remain stable between software releases, or even between subsequent frames in the same session.
4 ) 錨點
文檔: ARAnchor
錨是比特征點更加可靠的現(xiàn)實空間標記, 它能夠提高其周圍區(qū)域的現(xiàn)實跟蹤質(zhì)量, 文檔中提到一些很有用的錨點:
ARPlaneAnchor: ARKit能夠檢測空間中的平面, 你可以給這些平面綁定一個"平面錨點", 它常常是一個干凈的桌面, 地面等等, 宜家的虛擬家具app就用到了平面檢測來減少虛擬家具的漂移
ARImageAnchor, 掃描一張圖片, 并記憶這個圖像的特征, 當我們下次見到這個圖像的時候, 我們就能夠?qū)⑺O置為一個錨點, 在其周圍展示我們的虛擬世界, 它比平面特征更加豐富, 因為平面往往是一些地面, 桌面的紋理, 而圖片則細節(jié)更多. 這種錨點常常會用來做虛擬故事書. 當掃描到故事書上特定的圖片時, 能夠在其上播放虛擬場景, 讓情節(jié)"躍然紙上"
ARObjectAnchor: 這個真的太badass了! 能夠檢測并記錄一個現(xiàn)實三維物件, 你可以將一個杯子作為一個"物體錨", 創(chuàng)建這樣一個錨需要用攝像機掃描這個三維物件并得到豐富的特征點. 當攝像機下次看到這個三維物件的時候, 它能夠記住它并將它作為現(xiàn)實空間的描述標記, 比特征點和圖片更加高級!
ARFaceAnchor
這個能夠準確定位你的五官, 并為你戴上虛擬飾物, 很多美顏相機, 直播軟件都有用到這個功能, 這個就非常容易聯(lián)想到了
5 ) 環(huán)境光
文檔: lightEstimate
要讓我們的虛擬物件在現(xiàn)實環(huán)境中疊加得更加真實, 我們希望它被打上和環(huán)境一樣的燈光
ARKit 提供了對環(huán)境光位置估計的功能, 你可以估計環(huán)境光的位置, 強度后, 往你的場景中添加一盞對應位置和強度的燈. 這樣你的虛擬物件才能和周圍的現(xiàn)實真正的契合. 方法我會在后續(xù)教程講到, 敬請期待哦
點個喜歡吧~??