iOS 借助 ARKit 實現六自由度的 VR

ylwv8965 7年前發布 | 17K 次閱讀 iOS開發 VR 移動開發

效果展示

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

 

原理解析

涉及的庫

ARKit & SceneKit

原理

github上有Google CardBoard供大家使用,也有早期某好人開源后不更新的版本。

我接觸SceneKit發現可以便捷的實現VR效果,當然需要舍棄一部分內容。

個人以為,VR項目中核心組成有三:渲染引擎,九軸算法,反畸變算法。在此處我們可以基本舍棄反畸變算法與九軸算法,依靠SceneKit實現渲染部分。

層級關系

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

// retrieve the SCNView
SCNView scnViewLeft = [[SCNView alloc]initWithFrame:CGRectMake(0, 0, self.view.frame.size.width0.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.width0.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];</code></pre>

關于自由度

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

六軸自由度

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

Part3 VR部分的實現

Camera設置

在此Demo中需要注意的就是camera的設置。與一般游戲開發不同的是,我們這里需要2個camera,分別用于左右眼內容顯示。

因為左右眼內容實際是不一樣的,所以需要2個camera在增強視差實現立體效果。

考慮到后續需要2個眼睛隨著頭部轉動,會產生位移與旋轉,所以我們需要增加一個新的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];</code></pre>

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

關于攝像頭的空間坐標

借助WWDC2017發布的ARKit-ARCamera.transform實現頭部隨動與空間定位。

#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)]; }</code></pre>

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

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

    關于PBR材質

    這篇博文很詳細,可供參考。

    PBR,即Physically based rendering,可以實現很逼真的光影效果。

    http://www.jianshu.com/p/b30785bb6c97

    至此我們就可以實現文頭提供的Demo效果了。雖然誤差還是有的,但是畢竟是單目SLAM,是不是已經很厲害了呢。

    使用注意點

    因為這里空間定位基本依賴于ARKit提供的數據,所以ARKit的精確度直接影響到視覺效果。所以記得使用時記得遵守ARKit提到的運行條件,即 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以上的設備,良好的光線環境,避免對著白墻(無法獲取特征點)。

    這里我分享個沒有嚴謹驗證過的適用于ARKit快速穩定的技巧:

    斜對著方形區域,水平環繞掃視矩形后繼續瞄準沿豎直方向觀測,基本就能保持穩定了。

    如果您覺得有價值,請在github賞個star,不勝感激。

    如果有什么想交流的,歡迎私信。

     

    來自:http://www.jianshu.com/p/4f9809021142

     

 本文由用戶 ylwv8965 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!