iOS借助ARKit實(shí)現(xiàn)六自由度的VR

Part1.效果展示

效果展示


Demo.gif

demo02.gif

圖展示了『前后左右上下+頭部隨動』即六自由度的VR效果。

工程源碼:
https://github.com/WorkerAmo/ARKitPlusVR

已被錄入 https://github.com/olucurious/awesome-arkit

Part2.原理解析

涉及的庫

ARKit & SceneKit

原理

github上有Google CardBoard供大家使用,也有早期某好人開源后不更新的版本陌凳。
我接觸SceneKit發(fā)現(xiàn)可以便捷的實(shí)現(xiàn)VR效果,當(dāng)然需要舍棄一部分內(nèi)容胆胰。
個人以為,VR項(xiàng)目中核心組成有三:渲染引擎落塑,九軸算法朱庆,反畸變算法蛤克。在此處我們可以基本舍棄反畸變算法與九軸算法捺癞,依靠SceneKit實(shí)現(xiàn)渲染部分。

層級關(guān)系.png

直接使用Xcode9beta在ARKit新建工程Demo的基礎(chǔ)上添加ARSCNView雙屏即可构挤。

// retrieve the SCNView
SCNView *scnViewLeft = [[SCNView alloc]initWithFrame:CGRectMake(0, 0, self.view.frame.size.width*0.5, self.view.frame.size.height)];
scnViewLeft.pointOfView = cameraNodeLeft;
scnViewLeft.scene = scene;
scnViewLeft.backgroundColor = [UIColor blackColor];
[self.sceneView addSubview:scnViewLeft];
    
SCNView *scnViewRight = [[SCNView alloc]initWithFrame:CGRectMake(self.view.frame.size.width*0.5, 0, 0.5*self.view.frame.size.width, self.view.frame.size.height)];
scnViewRight.pointOfView = cameraNodeRight;
scnViewRight.scene = scene;
scnViewRight.backgroundColor = [UIColor blackColor];
[self.sceneView addSubview:scnViewRight];

關(guān)于自由度

目前iPhone上可以下載到的VRAPP基本都是三自由度髓介,即圍繞XYZ三軸心旋轉(zhuǎn)實(shí)現(xiàn)camera跟隨頭部轉(zhuǎn)動的效果。用戶無法自由移動從而接近或沿四周觀察物體筋现。手機(jī)在不借助外接設(shè)備的情況下實(shí)現(xiàn)VR空間定位的產(chǎn)品目前基本沒有唐础。但是借助ARKit,我們可以實(shí)現(xiàn)且誤差估計(jì)在十厘米左右矾飞。

六軸自由度.jpg

圖示為六自由度一膨,三自由度為去除up/down,left/right,forward/back三軸的剩余部分。

Part3 VR部分的實(shí)現(xiàn)

Camera設(shè)置

在此Demo中需要注意的就是camera的設(shè)置洒沦。與一般游戲開發(fā)不同的是豹绪,我們這里需要2個camera,分別用于左右眼內(nèi)容顯示申眼。


雙目視差(來自網(wǎng)絡(luò)瞒津,侵刪).jpg

因?yàn)樽笥已蹆?nèi)容實(shí)際是不一樣的,所以需要2個camera在增強(qiáng)視差實(shí)現(xiàn)立體效果豺型。
考慮到后續(xù)需要2個眼睛隨著頭部轉(zhuǎn)動仲智,會產(chǎn)生位移與旋轉(zhuǎn)买乃,所以我們需要增加一個新的camera作為2個camera的容器姻氨。

// Containor Camera. 
_cameraNode = [SCNNode node];
_cameraNode.camera = [SCNCamera camera];
[_cameraNode setPosition:SCNVector3Make(0, 0, 0)];
[scene.rootNode addChildNode:_cameraNode];

// Camera left
SCNNode *cameraNodeLeft = [SCNNode node];
cameraNodeLeft.camera = [SCNCamera camera];
[cameraNodeLeft setPosition:SCNVector3Make(-0.1, 0, 0)];
[_cameraNode addChildNode:cameraNodeLeft];
    
// Camera right
SCNNode *cameraNodeRight = [SCNNode node];
cameraNodeRight.camera = [SCNCamera camera];
[cameraNodeRight setPosition:SCNVector3Make(0.1, 0, 0)];
[_cameraNode addChildNode:cameraNodeRight];

之后針對攝像頭組的矩陣直接賦與containor camera即可。

關(guān)于攝像頭的空間坐標(biāo)

借助WWDC2017發(fā)布的ARKit-ARCamera.transform實(shí)現(xiàn)頭部隨動與空間定位剪验。

#pragma mark - ARSessionDelegate

- (void)session:(ARSession *)session didUpdateFrame:(ARFrame *)frame
{   
    // Retrive the matrix from ARKit - ARFrame - camera.
    _transform = frame.camera.transform;
    [_cameraNode setTransform:SCNMatrix4FromMat4(_transform)];
}

文檔提到過ARFrame提供的transform,這里的transform是六自由度的肴焊。

/**
 The transformation matrix that defines the camera's rotation and translation in world coordinates.
 */

關(guān)于PBR材質(zhì)

這篇博文很詳細(xì),可供參考功戚。
PBR娶眷,即Physically based rendering,可以實(shí)現(xiàn)很逼真的光影效果啸臀。
http://www.reibang.com/p/b30785bb6c97

至此我們就可以實(shí)現(xiàn)文頭提供的Demo效果了届宠。雖然誤差還是有的烁落,但是畢竟是單目SLAM,是不是已經(jīng)很厲害了呢。

使用注意點(diǎn)

因?yàn)檫@里空間定位基本依賴于ARKit提供的數(shù)據(jù)豌注,所以ARKit的精確度直接影響到視覺效果伤塌。所以記得使用時記得遵守ARKit提到的運(yùn)行條件,即https://developer.apple.com/documentation/arkit 提到的

ARKit requires an iOS device with an A9 or later processor.
& 
Understanding Augmented Reality:
Best Practices and Limitations段落中
However, it relies on details of the device’s physical environment that are
not always consistent or are difficult to measure in real time without some
degree of error. To build high-quality AR experiences, be aware of these 
caveats and tips.

簡而言之:6S以上的設(shè)備轧铁,良好的光線環(huán)境每聪,避免對著白墻(無法獲取特征點(diǎn))。

這里我分享個沒有嚴(yán)謹(jǐn)驗(yàn)證過的適用于ARKit快速穩(wěn)定的技巧:
斜對著方形區(qū)域齿风,水平環(huán)繞掃視矩形后繼續(xù)瞄準(zhǔn)沿豎直方向觀測药薯,基本就能保持穩(wěn)定了。


如果您覺得有價(jià)值救斑,請?jiān)趃ithub賞個star童本,不勝感激。
如果有什么想交流的脸候,歡迎私信巾陕。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市纪他,隨后出現(xiàn)的幾起案子鄙煤,更是在濱河造成了極大的恐慌,老刑警劉巖茶袒,帶你破解...
    沈念sama閱讀 212,718評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件梯刚,死亡現(xiàn)場離奇詭異,居然都是意外死亡薪寓,警方通過查閱死者的電腦和手機(jī)亡资,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,683評論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來向叉,“玉大人锥腻,你說我怎么就攤上這事∧富眩” “怎么了瘦黑?”我有些...
    開封第一講書人閱讀 158,207評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長奇唤。 經(jīng)常有香客問我幸斥,道長,這世上最難降的妖魔是什么咬扇? 我笑而不...
    開封第一講書人閱讀 56,755評論 1 284
  • 正文 為了忘掉前任甲葬,我火速辦了婚禮,結(jié)果婚禮上懈贺,老公的妹妹穿的比我還像新娘经窖。我一直安慰自己坡垫,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,862評論 6 386
  • 文/花漫 我一把揭開白布画侣。 她就那樣靜靜地躺著葛虐,像睡著了一般。 火紅的嫁衣襯著肌膚如雪棉钧。 梳的紋絲不亂的頭發(fā)上屿脐,一...
    開封第一講書人閱讀 50,050評論 1 291
  • 那天,我揣著相機(jī)與錄音宪卿,去河邊找鬼的诵。 笑死,一個胖子當(dāng)著我的面吹牛佑钾,可吹牛的內(nèi)容都是我干的西疤。 我是一名探鬼主播,決...
    沈念sama閱讀 39,136評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼休溶,長吁一口氣:“原來是場噩夢啊……” “哼代赁!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起兽掰,我...
    開封第一講書人閱讀 37,882評論 0 268
  • 序言:老撾萬榮一對情侶失蹤芭碍,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后孽尽,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體窖壕,經(jīng)...
    沈念sama閱讀 44,330評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,651評論 2 327
  • 正文 我和宋清朗相戀三年杉女,在試婚紗的時候發(fā)現(xiàn)自己被綠了瞻讽。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,789評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡熏挎,死狀恐怖速勇,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情坎拐,我是刑警寧澤烦磁,帶...
    沈念sama閱讀 34,477評論 4 333
  • 正文 年R本政府宣布,位于F島的核電站廉白,受9級特大地震影響个初,放射性物質(zhì)發(fā)生泄漏乖寒。R本人自食惡果不足惜猴蹂,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,135評論 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望楣嘁。 院中可真熱鬧磅轻,春花似錦珍逸、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,864評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至撮躁,卻和暖如春漱病,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背把曼。 一陣腳步聲響...
    開封第一講書人閱讀 32,099評論 1 267
  • 我被黑心中介騙來泰國打工杨帽, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人嗤军。 一個月前我還...
    沈念sama閱讀 46,598評論 2 362
  • 正文 我出身青樓注盈,卻偏偏與公主長得像,于是被迫代替她去往敵國和親叙赚。 傳聞我的和親對象是個殘疾皇子老客,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,697評論 2 351

推薦閱讀更多精彩內(nèi)容