Part1.效果展示
效果展示
圖展示了『前后左右上下+頭部隨動』即六自由度的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)渲染部分。
直接使用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ì)在十厘米左右矾飞。
圖示為六自由度一膨,三自由度為去除up/down,left/right,forward/back三軸的剩余部分。
Part3 VR部分的實(shí)現(xiàn)
Camera設(shè)置
在此Demo中需要注意的就是camera的設(shè)置洒沦。與一般游戲開發(fā)不同的是豹绪,我們這里需要2個camera,分別用于左右眼內(nèi)容顯示申眼。
因?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童本,不勝感激。
如果有什么想交流的脸候,歡迎私信巾陕。