iOS借助ARKit实现六自由度的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发现可以便捷的实现VR效果,当然需要舍弃一部分内容。
个人以为,VR项目中核心组成有三:渲染引擎,九轴算法,反畸变算法。在此处我们可以基本舍弃反畸变算法与九轴算法,依靠SceneKit实现渲染部分。

层级关系.png

直接使用Xcode9beta在ARKit新建工程Demo的基础上添加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];

关于自由度

目前iPhone上可以下载到的VRAPP基本都是三自由度,即围绕XYZ三轴心旋转实现camera跟随头部转动的效果。用户无法自由移动从而接近或沿四周观察物体。手机在不借助外接设备的情况下实现VR空间定位的产品目前基本没有。但是借助ARKit,我们可以实现且误差估计在十厘米左右。

六轴自由度.jpg

图示为六自由度,三自由度为去除up/down,left/right,forward/back三轴的剩余部分。

Part3 VR部分的实现

Camera设置

在此Demo中需要注意的就是camera的设置。与一般游戏开发不同的是,我们这里需要2个camera,分别用于左右眼内容显示。


双目视差(来自网络,侵删).jpg

因为左右眼内容实际是不一样的,所以需要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];

之后针对摄像头组的矩阵直接赋与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)];
}

文档提到过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,不胜感激。
如果有什么想交流的,欢迎私信。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,029评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,395评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,570评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,535评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,650评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,850评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,006评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,747评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,207评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,536评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,683评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,342评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,964评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,772评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,004评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,401评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,566评论 2 349

推荐阅读更多精彩内容