點擊獲取本文示例代碼, 本文代碼在分支ARKit中偿洁。
如果你想了解更多關(guān)于OpenGL ES的知識,請移步至OpenGL ES相關(guān)文章目錄
iOS11推出了新框架ARKit米母,通過ARKit和SceneKit可以很方便的制作AR App驮吱。蘋果也提供了AR基本的應(yīng)用框架阳距,你可以直接從此開始你的AR App的開發(fā)逾雄。
不過本系列文章將使用OpenGL ES為ARKit提供渲染支持腐巢,接下來我們先去了解一下ARKit的理論相關(guān)知識品追。
AR基本概念
AR最基本的概念就是將虛擬的計算機圖形和真實環(huán)境結(jié)合的技術(shù)。該技術(shù)有很多種實現(xiàn)方式冯丙。
- 使用2D或者3D圖形裝飾人臉肉瓦,常見于一些相機和視頻類App,主要使用人臉識別追蹤技術(shù)胃惜。
- 基于標記的3D模型放置泞莉,比如基于AR的故事書,陰陽師的現(xiàn)世召喚船殉。標記可以是簡單的黑框包裹的標記鲫趁,也可以是一張復雜圖片的特征點訓練數(shù)據(jù)。如果你感興趣可以前往ARToolKit利虫,這是一個開源的AR框架挨厚,主要用于基于標記的AR。最近出ARToolkit6 Beta了糠惫,不知道有沒有新的功能開放幽崩。
- 追蹤真實環(huán)境的特征點,計算真實攝像機在真實環(huán)境的位置寞钥。所謂特征點慌申,就是圖片中灰度變化比較劇烈的位置,所以想要更精準穩(wěn)定的計算,就需要真實環(huán)境的顏色變化比較豐富蹄溉。ARKit就是使用這種原理進行攝像機定位的咨油。
世界追蹤(WorldTracking)
通過追蹤真實世界的特征點,計算真實攝像機位置并應(yīng)用到3D世界的虛擬攝像機是AR實現(xiàn)中最重要的部分柒爵。計算結(jié)果的精確性直接影響到渲染出來的結(jié)果役电。ARKit使用ARSession
來管理整個AR處理流程,包括攝像機位置的計算棉胀。
#pragma make - AR Control
- (void)setupAR {
if (@available(iOS 11.0, *)) {
self.arSession = [ARSession new];
self.arSession.delegate = self;
}
}
- (void)runAR {
if (@available(iOS 11.0, *)) {
ARWorldTrackingSessionConfiguration *config = [ARWorldTrackingSessionConfiguration new];
config.planeDetection = ARPlaneDetectionHorizontal;
[self.arSession runWithConfiguration:config];
}
}
- (void)pauseAR {
if (@available(iOS 11.0, *)) {
[self.arSession pause];
}
}
使用ARSession
的方式很簡單法瑟,初始化,設(shè)置delegate
唁奢,開啟ARSession
需要傳入一個配置ARWorldTrackingSessionConfiguration
霎挟,ARWorldTrackingSessionConfiguration
代表AR系統(tǒng)會追蹤真實世界的特征點,計算攝像機位置麻掸。蘋果以后也有可能會出ARMarkerTrackingSessionConfiguration
之類用來識別追蹤標記的配置吧酥夭。ARSession
開啟后會啟動相機,并且會通過傳感器感知手機位置脊奋。借用WWDC中的一張圖熬北。
ARSession
綜合相機捕獲的視頻流和位置信息生成一系列連續(xù)的ARFrame
。
- (void)session:(ARSession *)session didUpdateFrame:(ARFrame *)frame {
...
}
每個ARFrame
包含了從相機捕捉的圖片诚隙,相機位置相關(guān)信息等讶隐。在這個方法里我們需要繪制相機捕捉的圖片。根據(jù)相機位置等信息繪制3D物體等久又。
平面檢測
ARKit提供了另一個很酷的功能整份,檢測真實世界的平面,并提供一個ARPlaneAnchor
對象描述平面的位置籽孙,大小,方向等信息火俄。
- (void)runAR {
if (@available(iOS 11.0, *)) {
ARWorldTrackingSessionConfiguration *config = [ARWorldTrackingSessionConfiguration new];
config.planeDetection = ARPlaneDetectionHorizontal;
[self.arSession runWithConfiguration:config];
}
}
上面的config.planeDetection = ARPlaneDetectionHorizontal;
設(shè)置了檢測平面的類型是水平犯建。不過目前也就只有這一個選項可以選。如果ARKit檢測到了平面瓜客,會通過delegate
中的方法- (void)session:(ARSession *)session didAddAnchors:(NSArray<ARAnchor*>*)anchors
提供數(shù)據(jù)給你适瓦。你可以判斷ARAnchor
是不是ARPlaneAnchor
來判斷是否檢測到了平面。ARAnchor
用來表示3D物體在真實環(huán)境的位置谱仪。你只要保持你的3D物體和ARAnchor
的3D變換同步就能實現(xiàn)AR效果了玻熙。
Hit Test
Hit Test可以讓你方便的在檢測到的平面上放置物體。當你點擊屏幕時疯攒,使用Hit Test可以檢測出你點擊的位置有哪些平面嗦随,并且提供ARAnchor
用于設(shè)置放置物體的位置。
[frame hitTest:CGPointMake(0.5, 0.5) types:ARHitTestResultTypeExistingPlane];
使用ARFrame的hitTest
方法,第一個傳入的點取值范圍從(0,0)
到(1,1)
枚尼,第二個參數(shù)代表可以檢測哪些對象贴浙。可以檢測到的對象如下署恍。
-
ARHitTestResultTypeFeaturePoint
崎溃,根據(jù)距離最近的特征點檢測出來的連續(xù)表面。 -
ARHitTestResultTypeEstimatedHorizontalPlane
盯质,非精準方式計算出來與重力垂直的平面袁串。 -
ARHitTestResultTypeExistingPlane
, 已經(jīng)檢測出來的平面,檢測時忽略平面本身大小呼巷,把它看做一個無窮大的平面囱修。 -
ARHitTestResultTypeExistingPlaneUsingExtent
, 已經(jīng)檢測出來的平面,檢測時考慮平面本身的大小朵逝。
檢測成功則返回NSArray<ARHitTestResult *> *
蔚袍,ARHitTestResult
中包含檢測類型,相交點的距離配名,平面的ARAnchor
啤咽。注意只有檢測到ARHitTestResultTypeExistingPlane
和ARHitTestResultTypeExistingPlaneUsingExtent
才會有ARAnchor
。這四個檢測類型是可以通過|
的方式同時存在的渠脉,比如ARHitTestResultTypeEstimatedHorizontalPlane | ARHitTestResultTypeExistingPlane
宇整。
光線強度調(diào)節(jié)
ARKit還提供了一個檢測光照強度的功能,主要為了讓3D模型的光照和環(huán)境的光照強度保持一致芋膘。在ARFrame
中有一個lightEstimate
的變量鳞青,如果檢測光照強度成功,則會有值为朋。值的類型為ARLightEstimate
臂拓,其中只包含一個變量ambientIntensity
。在3D光照模型中习寸,它對應(yīng)環(huán)境光胶惰,它的值從0 ~ 2000。使用OpenGL渲染時霞溪,可以使用這個值調(diào)整光照模型中的環(huán)境光強度孵滞。
ARKit的理論知識差不多到此結(jié)束了,下一篇將會介紹如何使用OpenGL ES渲染ARFrame
里的內(nèi)容鸯匹。