close
当前位置: 物联网在线 > 技术文库 > ios >

iOS 借助 ARKit 实现六自由度的 VR

iOS 借助 ARKit 实现六自由度的 VR

图展示了『前后左右上下+头部随动』即六自由度的VR效果。

原理解析 涉及的库

ARKit & SceneKit

原理

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

我接触SceneKit发现可以便捷的实现VR效果,当然需要舍弃一部分内容。

个人以为,VR项目中核心组成有三:渲染引擎,九轴算法,反畸变算法。在此处我们可以基本舍弃反畸变算法与九轴算法,依靠SceneKit实现渲染部分。

iOS 借助 ARKit 实现六自由度的 VR

层级关系

直接使用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,我们可以实现且误差估计在十厘米左右。

iOS 借助 ARKit 实现六自由度的 VR

六轴自由度

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

Part3 VR部分的实现 Camera设置

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

iOS 借助 ARKit 实现六自由度的 VR

因为左右眼内容实际是不一样的,所以需要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,可以实现很逼真的光影效果。

至此我们就可以实现文头提供的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,不胜感激。

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


(责任编辑:ioter)

用户喜欢...

iOS开源:WJClipsButton-Clips 按钮的完整实现

效果 要求 Swift 3.0 iOS 8.0 Xcode 8.0 安装 WJClipsButton is available through CocoaPods . To install it, simply add the following line to your Podfile: pod "WJClipsButton" 使用 Code Import import WJClipsButton Init Setup let wjButton = WJCl...


iOS高可控性日历基础组件-SKCalendarView的使用和实现思路的分享

SKCalendarView是一个高可控性的日历基础组件,为了提高应用的自由度,默认只提供了日历部分的视图封装,但不涵盖切换月份按钮、年月分显示等非关键性控件,但请不要担心,SKCalendarView为...


iOS 开发之模糊效果的五种实现

在iOS开发中我们经常会用到模糊效果使我们的界面更加美观,而iOS本身也提供了几种达到模糊效果的API,如:Core Image,使用Accelerate.Framework中的vImage API,在iOS 7之前系统的类提供UIToolbar,在...


iOS 使用输入框的inputAccessoryView属性实现键盘上添加视图

在开发应用程序时会经常用到输入消息并发送消息的功能,比如今日头条或者UC头条这些软件底部都会有,如何想向这些应用一样点击UITextField或者UITextView就可以弹出键盘并在键盘上也能加上...


iOS上下文实现评价星星

创建两个 view,通过 for 循环创建 imageView,未点亮星星视图在下、点亮星星视图在上重合在一起,当用户点击视图时,通过改变点亮星星视图的 width 实现功能 本文思路: 直接重写 drawrect 方法...


iOS端一次视频全屏需求的实现

对于一个带有视频播放功能的app产品来说,视频全屏是一个基本且重要的需求。虽然这个需求看起来很简单,但是在实现上,我们前后迭代了三套技术方案。这篇文章将介绍这三种实现方案中...


iOS 动画进阶 - 实现炫酷的上拉刷新动效

最近撸了一个上拉刷新的小轮子,只要遵循一个协议就能自定义自己动效的上拉刷新和加载,我自己也写了几个动效进去,下面是一个比较好的动效的实现过程 先上效果图和 github地址 ,有其...


iOS 实现点击微信头像效果

公司产品需要实现点击个人主页头像可以放大头像、缩放头像、保存头像效果(和点击微信个人头像类似),故找个时间实现一下,记录下来,供自己查看,也给大家做个参考。 实现效果(...


图解 RACCommand 底层实现原理

RACCommand作为RAC框架里比较特殊的存在,继承于NSObject,它是一个类而不是信号。整个类的结构也比较简洁,根据官方的解释,可以使用它来创建和订阅相应事件的信号。对于副作用相关的操作...


iOS 用Swipe手势和动画实现循环播放图片

主要想法 添加3个ImageView展示图片,实现图片的无限循环。 使用Swipe手势识别用户向右或向左滑动图片。 使用CATransition给ImageView.layer添加动画,展示图片更换的效果。 实现 在storyboard添加三个...