相關(guān)
ARKit實(shí)戰(zhàn):如何實(shí)現(xiàn)任意門
Animoji實(shí)現(xiàn)方案分享
Animoji模型優(yōu)化方案總結(jié)
ARKit進(jìn)階:物理世界
ARKit進(jìn)階:材質(zhì)
解決 ARKit 用Metal錄制時(shí)顏色變暗的問題
記一個(gè)SceneKit Morpher引發(fā)的Crash
寫在前面
其實(shí)準(zhǔn)備ARKit已經(jīng)很久了,確切地說當(dāng)WWDC開始介紹時(shí)就開始了。其后參加了蘋果的ARKit workShop,加上自己有點(diǎn)事,所以文章一直沒發(fā)出來,現(xiàn)在再發(fā)一篇上手文章,也沒什么意義。所以本篇文章重在workShop上與蘋果工程師的交流和我對ARKit的理解, 最后會簡單介紹一下相關(guān)技術(shù)。
更新
蘋果最近更新了ARKit的文檔,加入了基于深度攝像頭的人臉識別(目前就是iPhone X的前置攝像頭)。在work shop上ARKit團(tuán)隊(duì)明確表示不會支持前置攝像頭,這么快就被打臉……所以大家可以期待,ARKit將在前置攝像頭上有更多的應(yīng)用。
Work Shop Demo
MarkDown無法傳視頻,這里是視頻鏈接。
ARKit
AR(Augment Reality)大家都知道,就是將3D模型渲染在攝像頭圖像之上,混合渲染達(dá)到虛擬物品就好像是現(xiàn)實(shí)的一部分。ARKit解決了模型定位難的問題,結(jié)合CoreMotion運(yùn)動數(shù)據(jù)與圖像處理數(shù)據(jù),來建立一個(gè)非常準(zhǔn)確的SLAM系統(tǒng),構(gòu)建虛擬世界和現(xiàn)實(shí)世界之間的映射。同時(shí)能夠分析環(huán)境自動給模型添加光源,實(shí)際效果還是比較驚艷的。
從結(jié)構(gòu)上看,ARKit提供了一套簡單易用的AR框架,但框架之外,需要很多的三維空間、游戲編程、3D模型、GPU渲染的知識來理解AR技術(shù)。ARKit最重要的兩個(gè)類是
ARSession
與ARSCNView
類似與AVFoudation,ARKit中由ARSesseion類來配置SLAM系統(tǒng)的建立。設(shè)置RSession的配置選項(xiàng)為ARWorldTrackingSessionConfiguration來追蹤設(shè)備的方向與位置,并且能夠檢測平面。這個(gè)選項(xiàng)只有A9處理器之上才支持。其他型號處理器(6S以下)只能追蹤設(shè)備的方向。
ARKit的提供了自帶的兩個(gè)渲染類:ARSCNView和ARSKView,后者用來渲染2D模型。之前鮮有問津的SceneKit算是有了用武之地。這兩個(gè)類會自動開啟攝像頭并建立虛擬空間與現(xiàn)實(shí)空間之間的映射。同時(shí)ARKit也支持自定義用OpenGL或Metal實(shí)現(xiàn)渲染類,但要自己管理與ARSession之間的通信,同時(shí)要遵循iOS GPU命令不能在后臺調(diào)用的規(guī)則。
其他比較重要的類有ARAnchor
、ARHitTestResult
、ARFrame
、ARCamera
。
- ARAnchor
世界中點(diǎn),可以用來放置虛擬物品,也可以代指現(xiàn)實(shí)物品的放置位置。ARAnchor在世界中是唯一的,并包含仿射變換的信息。
- ARHitTestResult
HitTest的返回,世界中的ARAnchor。
與UIKit中的hitTest不同,ARKit的HitTest以設(shè)備方向配合視圖坐標(biāo),建立一條世界中的射線,所有在射 線上的ARAnchor, 會以由近到遠(yuǎn)的方式返回。此外SCeneKit的HitTest返回虛擬物品。
- ARFrame
攝像頭視頻幀的包裝類,包含位置追蹤信息、環(huán)境參數(shù)、視頻幀。重點(diǎn)是它包含了蘋果檢測的特征點(diǎn),通過rawFeaturePoints可以獲取,不過只是特征的位置,具體的特征向量并沒有開放。
- ARCamera
場景中的攝像機(jī),用來控制模型視圖變換和投影變換。同時(shí)提供6DOF(自由度信息,方向+位置)與追蹤信息。
對ARKit的思考
從框架接口來看,ARKit 暴露出來的能力并不多且小心翼翼。
AR的能力,由三部分組成:
- 3D渲染
- 空間定位與方向追蹤
- 場景理解(檢測與識別)
目前看 ARKit 只提供了3D渲染的入口,其他兩個(gè)都被封裝起來了,所以目前來看渲染是差異化的主要途徑,但不唯一。ARKit workShop 上,面對大家提出的苛刻問題,蘋果工程師大量提到特征點(diǎn)。其實(shí)計(jì)算機(jī)視覺是可以在場景理解這一層面做一些自定義的。如果蘋果開放更多的能力,那AR的能力完全可以作為任何一個(gè)APP的特性。
此外,ARKit還存在一些問題:
- ARKit 是基于慣性-視覺來做空間定位的,需要平穩(wěn)緩慢的移動+轉(zhuǎn)向手機(jī),才能構(gòu)建更加準(zhǔn)確的世界,這對用戶來說是一種考驗(yàn),需要積極提示。
- 理論上 ARKit 在雙目攝像頭上的表現(xiàn)應(yīng)該優(yōu)于單目,這里需要具體測試,如何來平衡用戶體驗(yàn)。
- .scn文件還是知識一個(gè)簡單的3維模型編輯器,支持的文件格式少,對模型、光照的編輯方式不太友好。對骨骼動畫的支持還有只在能用的階段。
- 一旦剛開始檢測平面失敗,出現(xiàn)時(shí)間久,飄逸的現(xiàn)象,后期很難再正確檢測,要強(qiáng)制重啟。
ARKit最佳實(shí)踐
模型與骨骼動畫
- 如果是使用.dae 轉(zhuǎn) .scn 文件,資源中包含骨骼動畫時(shí),加載.scn文件到 scene 中會丟失動畫,需要在加載時(shí)手動恢復(fù)一下(方法)。
- 設(shè)計(jì)骨骼動畫是,要求設(shè)計(jì)師把動畫放在根節(jié)點(diǎn)上,不要分散地放在每個(gè)bone上,這樣可以方便地讀取出動畫到
CAAnimation
。 - 最好不要將太遠(yuǎn)的光照加載模型文件中,這樣會導(dǎo)致加載文件到
SCNNdoe
時(shí),你的 node 真實(shí)尺寸特別大,而你期望的尺寸可能只是模型對象的大小。 - 模型的
SCNMaterial
是用 physically based lighting model 會有更好的表現(xiàn),設(shè)置比較好的環(huán)境光也比較重要。
光照
- 合理的陰影會大大提高AR的效果,貼一張紋理當(dāng)然可以,但動態(tài)陰影更讓人沉浸,我們還是要有追求的。
- 使用Bake ambient occlusion(ABO)效果,模型會更逼真。
- 光照node加載到
SCNScene
的rootNode
上,這對做碰撞檢測尤其重要
ARKit workShop
匯總了一下workShop上,比較感興趣的問題和蘋果工程師的回答,摻雜自己的理解。
1 . ARFrame提供的YUV特征,如何獲取RGB特征?
答:使用Metal去獲取特征點(diǎn)的RGB值。
(這個(gè)我一般是用OpenGL的shader去做,我想蘋果工程師是說將圖像用Metal轉(zhuǎn)成位圖后,根據(jù)坐標(biāo)去獲取RGB值。但特征點(diǎn)不多的話,直接在CPU中利用公式計(jì)算一下不就行了嗎?不過也許Metal有更強(qiáng)大的方法。)
2 . ARKit中怎么做虛擬環(huán)境?
答:利用Cube背景。
(這個(gè)在VR中用的比較多,就是用一個(gè)貼滿背景的立方體包裹住攝像機(jī)所在的空間,網(wǎng)上的資料較多。)
3 . ARKit的如何模擬光源的?為什么不產(chǎn)生陰影。
答:ARKit通過圖像的環(huán)境來設(shè)置模型的環(huán)境光強(qiáng)度,而環(huán)境光是不產(chǎn)生陰影的。
(我猜蘋果應(yīng)該是通過像素值來確定環(huán)境光的,如果用高級一點(diǎn)的方法完全可以添加直射光。光照有許多模型,只有帶方向的光才會產(chǎn)生陰影,如果想用ARKit做出陰影,可以看我的回答。)
4 . AVFoudation與ARSession之間的切換會有問題嗎?
答: ARSession
底層也是用AVFoudation
的,如果重新打開ARKit,只需要重新 run 一下 ARSession
可以了,但切換時(shí)會有卡頓。
(我自己試了一下,切換時(shí)確實(shí)有輕微的卡頓,切換后ARSession就停止攝像頭采集了,但3D渲染會繼續(xù),只是喪失了空間定位與檢測識別的能力。)
5 . ARKit是否支持前置攝像頭?
答:不支持。ARKit并不是一個(gè)用于前置攝像頭環(huán)境的技術(shù),因?yàn)榭臻g有限,能提供的信息也非常有限。
(這個(gè)問題是很多參會者關(guān)心的問題,但 ARKit 團(tuán)隊(duì)似乎不是很 care ,說到底還是因?yàn)榍爸脭z像頭的場景中,用戶很少會移動,畫面中一般大部分都是人臉,這樣 ARKit 的定位與檢測能力無法很好使用。建議由類似需求的同學(xué)好好梳理,是不是想要的是3D渲染而不是AR。
6 . ARKit的最大應(yīng)用范圍是多少?
答:100米是 ARKit 在保持較好用戶體驗(yàn)的最大測量距離。
(這個(gè)其實(shí)我有點(diǎn)沒太聽清,實(shí)際數(shù)字應(yīng)該是100米以上)
7 . ARKit如何做marker?
答:ARKit不會提供這樣的能力,如果想實(shí)現(xiàn)的,可以用 ARKit 提供的特征點(diǎn)來跑自己的計(jì)算機(jī)視覺。
(熟悉計(jì)算機(jī)視覺的同學(xué)應(yīng)該都明白,其實(shí)marker就是一種簡單的圖像識別,如果 ARKit 提供的特征點(diǎn)可靠的話,完全可以自己做特征匹配。現(xiàn)場問了蘋果工程師,他們的特征點(diǎn)是什么特征,他們不愿回答,不過看使用場景的話,應(yīng)該是一種邊緣敏感的低維特征,應(yīng)該類似 PCA + SURF)。
8 . ARKit合適支持A8?性能如何?
答:支持A8處理器并不在計(jì)劃中(這里指的是空間定位能力,A8只支持空間方向追蹤),ARKit 的大部分計(jì)算都是在CPU上處理的,在A8處理器上的性能損耗在 15% ~ 25%, 在A9處理器上的性能損耗在 10% ~ 15%。
(看他們的意思,大量的計(jì)算,在A8上應(yīng)該是比較低效的,解釋了為什么A8上的追蹤能力是閹割版的。性能應(yīng)該說還不錯(cuò),與游戲類似)
9 . 如何追蹤實(shí)際的物體?
答:可以在已識別的物體位置上,添加一個(gè)node, 這樣就能在之后的處理中一直保持這個(gè)物體的追蹤。
(這次的wrokShop,蘋果大量提到他們的特征點(diǎn),如果他們真的足夠重視的話,應(yīng)該開放特征檢測的過程與特征向量,希望后期能夠開放吧)
10 . 如何連接兩個(gè)不同 ARKit 世界?
答:ARKit沒有計(jì)劃支持這些,比較 tricky 的做法是將兩個(gè)手機(jī)緊挨著啟動ARKit。
(這個(gè)也是很多參會者關(guān)注的問題,相信不少人已經(jīng)有了自己的解決方案,這里我后期會出一篇文章講解。)
AR相關(guān)
渲染
AR說到底還是一種游戲技術(shù),AR提供了定位、檢測平面的功能,這些功能并沒有暴露出來供我們自定義,那么只能在渲染方面做出差異。
目前ARKit支持的3D渲染引擎,有sceneKit,Unity3D,UE。后兩者都是成熟的游戲引擎,能夠提供完整的游戲功能,但沒有我們沒有使用,主要因?yàn)椋?/p>
- 上手較慢,iOS11 9月中旬就要發(fā)布了,時(shí)間緊促。
- 接入U(xiǎn)nity3D會給安裝包造成很大壓力,成本大約10M。
最終決定還是用sceneKit,主要出于一下考慮:
- ARKit目前對Unity3D,UE的支持沒有sceneKit好。
- sceneKit用OC寫,可以O(shè)CS。
- sceneKit是系統(tǒng)動態(tài)庫,對安裝包壓力不大。
- sceneKit雖然能力弱,但是對于AR來說足夠了,AR畢竟打造不了復(fù)雜的游戲。
坐標(biāo)系
ARKit和OpenGL一樣,使用右手坐標(biāo)系, 這個(gè)新建一個(gè)camera就可以看出來。
定位
將模型加載到空間中,需要6個(gè)自由度(6DOF)的信息來指定模型的表現(xiàn):
分別是沿三個(gè)坐標(biāo)軸的平移與旋轉(zhuǎn)。
可以使用旋轉(zhuǎn)矩陣、歐拉角、四元數(shù)來定義空間旋轉(zhuǎn),ARKit的這三種方式均有運(yùn)用。
- 旋轉(zhuǎn)矩陣
這個(gè)好理解,使用旋轉(zhuǎn)的變換矩陣即可,維度4*4,定義一次旋轉(zhuǎn)需要16個(gè)數(shù)。
- 歐拉角
把空間旋轉(zhuǎn)分解成繞三個(gè)局部坐標(biāo)軸的平面旋轉(zhuǎn),分別是pitch(俯仰角,繞x軸),yaw(偏航角,繞y軸),roll(翻滾角,繞z軸),然后以一定順序做旋轉(zhuǎn)(sceneKit中是 roll -> yew -> pitch),歐拉角是使用三個(gè) 3*3 矩陣連乘實(shí)現(xiàn),而且存在萬向鎖的問題。
當(dāng)pitch為90°時(shí),pitch與yew的旋轉(zhuǎn)軸重合了,這時(shí)飛機(jī)喪失了一個(gè)旋轉(zhuǎn)的維度。
- 四元數(shù)
將三維空間的旋轉(zhuǎn)表示成四維空間的超球面上位移, 概念有點(diǎn)復(fù)雜。簡單來說,我們只需要旋轉(zhuǎn)軸 ,和角度 ?? 來構(gòu)造一個(gè)單位四元數(shù) q:
那么旋轉(zhuǎn)可以定位為:
對任何需要旋轉(zhuǎn)的點(diǎn) ,將它擴(kuò)展成一個(gè)純四元數(shù) ,代入上面的公式,就可以得到旋轉(zhuǎn)后的點(diǎn)。
追蹤
visual-inertial odometry :基于視覺和慣性的測量方法,慣性數(shù)據(jù)是指角速度和加速度,這些都由Core Motion
提供,加上圖像特征,能夠更準(zhǔn)確地建立SLAM系統(tǒng)。ARKit會將提取到的特征點(diǎn)映射的空間中,也就是說特征點(diǎn)是由三維坐標(biāo)的,我們可以利用特征點(diǎn)來確定圖像中物體的遠(yuǎn)近。實(shí)測效果不錯(cuò),誤差在分米以內(nèi)。