书名:AR开发权威指南:基于AR Foundation
ISBN:978-7-115-54479-7
本书由人民邮电出版社发行数字版。版权所有,侵权必究。
您购买的人民邮电出版社电子书仅供您个人使用,未经授权,不得以任何方式复制和传播本书内容。
我们愿意相信读者具有这样的良知和觉悟,与我们共同保护知识产权。
如果购买者有侵权行为,我们可能对该用户实施包括但不限于关闭该帐号等维权措施,并可能追究法律责任。
编 著 汪祥春
责任编辑 张 涛
人民邮电出版社出版发行 北京市丰台区成寿寺路11号
邮编 100164 电子邮件 315@ptpress.com.cn
网址 http://www.ptpress.com.cn
读者服务热线:(010)81055410
反盗版热线:(010)81055315
本书第1章介绍AR技术原理和AR Foundation概况,讲述用Unity开发AR应用的环境配置及调试方法,第2章对AR Foundation体系架构及关键组件、核心功能技术进行深入探讨,第3章讲述平面检测识别及参考点相关知识,第4章介绍2D图像与3D物体的检测识别跟踪知识,第5章介绍人脸检测、人脸表情捕捉、人脸特效实现的相关技术,第6章介绍光照估计、环境光反射、AR阴影生成的相关知识,第7章讨论云锚点、持久化存储、AR多人体验共享的相关知识,第8章介绍摄像头图像获取及自定义渲染管线的相关知识,第9章讨论2D、3D人体姿态估计及人形遮挡的相关知识,第10章讲述摄像机及手势操作的相关知识,第11章讨论在AR应用中使用3D音、视频的相关知识,第12章讲述开发AR应用的设计原则与设计指南,第13章讨论AR开发时的性能问题排查及优化技术。
本书适合AR Foundation初学者、Unity开发人员阅读,也可以作为大专院校相关专业师生的学习用书以及培训学校的教材。
自2017年以来,增强现实(Augmented Reality,AR)技术发展迅速,已从实验室的科研转变为消费型的大众技术,并呈现爆发态势。在计算机视觉与人工智能技术的推动下,AR无论是在跟踪精度、设备性能,还是人机交互自然性上都有了很大提高。据权威机构预测,AR会成为下个十年改变人们生活、工作的最重要的技术之一,并在5G通信技术的助力下出现需求爆发。
AR技术是一种将虚拟信息与真实世界融合展示的技术,它广泛运用了人工智能、三维建模、实时跟踪注册、虚实融合、智能交互、传感计算等多种技术手段,将计算机生成的文字、图像、三维模型、音频、视频、动画等虚拟信息模拟仿真后应用到现实世界中。AR技术同时考虑了现实世界与虚拟信息的相互关系,虚实信息互为补充,从而实现对现实世界的增强。借助于AR Foundation,我们不再单独需要昂贵的设备就可以体验到AR带来的奇妙体验,使移动手机具备了另一种崭新的应用形式。
AR Foundation是Unity构建的跨平台、开放式AR开发架构,这个平台架构于ARKit、ARCore、SenseAR和其他第三方AR SDK插件之上,其目的就是利用Unity的跨平台能力构建一种与平台无关的AR开发环境,提供给开发者一致的开发界面,并按照指定的发布平台自动选择合适的底层SDK版本。AR Foundation的一次开发多平台部署模式极大地降低了AR应用的开发成本,也降低了开发人员的学习成本,并且更重要的是由于其开放性,将来可以纳入除手机之外的各类可穿戴便携设备(如手环、眼镜等)AR开发SDK中,形成一个完整的AR开发、测试、部署环境。
AR是一门前沿技术,AR Foundation处于高速发展中,当前可供开发者参考的技术资料非常匮乏,更没有成体系的完整学习指南。本书旨在为AR Foundation技术开发人员提供相对完善的、成体系的学习材料,解决AR发展早期参考资料缺乏的问题。
本书关注AR Foundation技术的应用,但在讲解技术点的同时,对其原理、技术背景进行了较深入的探究,采取循序渐进的方式,使读者知其然更能知其所以然,一步一步地将读者带入AR开发的殿堂。
本书面向AR Foundation初学者与程序员,尽力采用通俗易懂的语言,但仍希望读者能具备以下前置知识。
(1)有一定的编程经验。尽管Unity有良好的代码封装集成机制,但仍然需要编写代码去实现特定功能和效果。学习过C#、Java之类高级语言的读者会更加容易理解接口及方法调用,同时,如果读者有一定的Shader语言基础,学习效果更佳,但这不是必需的。
(2)对Unity引擎操作界面比较熟悉,对Unity的基础操作比较熟练,如创建场景、脚本、挂载组件等。
(3)有一定的数学基础。数字三维空间就是用数学精确描述的虚拟世界,如果读者对坐标系、向量及基本的代数运算有所了解,会对理解AR Foundation工作原理、渲染管线有很大的帮助,但本书中没有直接用到复杂数学计算,读者不用太担心。
本书属于技术类图书,预期读者包括:
(1)对AR技术有兴趣的科技工作者;
(2)向AR方向转型的程序员、工程师;
(3)研究或讲授AR技术的教师;
(4)渴望利用新技术的自由职业者或者其他行业人员。
(1)结构清晰。本书分3个部分,第一部分为基础篇,包括第1章和第2章,基础篇从AR技术原理入手,详述了AR Foundation体系架构及其关键组件核心功能;第二部分为功能技术篇,包括第3章至第11章,对AR Foundation各个功能技术点进行全面深入的剖析;第三部分为提高篇,包括第12章和第13章,主要从更高层次对AR开发中的原则及性能优化进行讲解,提升读者对AR开发的整体把握能力。
(2)循序渐进。本书充分考虑不同知识背景读者的需求,按知识点循序渐进,通过大量配图、实例进行详细讲解,即使是毫无Unity使用经验的读者也能轻松上手。
(3)深浅兼顾。在讲解AR Foundation技术点时,对其技术原理、理论脉络进行了较深入的探究,语言通俗易懂,对技术阐述深入浅出。
(4)实用性强。本书实例丰富,每个技术点都有案例,注重对技术的实际运用,力图解决读者在项目开发中面临的难点问题,实用性非常强。
汪祥春,计算机科学与技术专业硕士,全国信息技术标准化技术委员会、计算机图形图像处理及环境数据表示分技术委员会虚拟现实与增强现实标准工作组成员,中国增强现实核心技术产业联盟成员。现从事AR技术研发及管理工作。拥有深厚的软件工程专业背景和省部级科技项目实施管理经验,CSDN博客专家。拥有十余年软件开发及项目管理经验。
尽管作者在本书的编写过程中,多次对内容、语言描述的一致性和准确性进行审查、校正,但由于作者水平有限,书中难免会有谬误之处,欢迎广大读者批评指正。可以发邮件(yolon3000@163.com)联系作者获取本书配套程序,本书技术讨论QQ群为190304915。本书编辑联系邮箱为zhangtao@ptpress.com.cn。
仅以此书献给我的妻子欧阳女士、孩子妍妍及轩轩,是你们的支持让我能勇往直前,永远爱你们,也感谢张涛编辑对本书的大力支持。
作者
增强现实(Augmented Reality, AR)技术是一种将虚拟信息与真实世界融合展示的技术,其广泛运用了人工智能、三维建模、实时跟踪注册、虚实融合、智能交互、传感计算等多种技术手段,将计算机生成的文字、图像、三维模型、音频、视频、动画等虚拟信息模拟仿真后,应用到真实世界。增强现实技术考虑了真实世界与虚拟信息的相互关系,虚实信息互相补充,从而实现对真实世界的增强,如图1-1所示。
▲图1-1 AR技术将虚拟信息叠加在真实环境之上从而达到增强现实的目的
VR、MR、AR这些英文缩写有时让初学者感到困惑。VR是Virtual Reality的缩写,即虚拟现实,是一种能够创建和体验虚拟世界的计算机仿真技术,它利用计算机生成交互式的全数字三维视场,能够营造全虚拟的环境。MR是Mix Reality的缩写,即混合现实,是融合真实和虚拟世界的技术。混合现实概念由微软公司提出,强调物理实体和数字对象共存并实时相互作用,如实时遮挡、反射等。本书主要关注AR技术,并将在后文详细讲述如何用AR Foundation来开发构建移动端AR应用。
第一个为用户提供沉浸式混合现实体验功能的AR系统是在20世纪90年代初发明的,虚拟装置及系统于1992年在美国空军阿姆斯特朗实验室开发。在AR技术萌芽后,经过无数人的努力,最早将AR技术带到大众视野的产品是Google公司的Google Glass增强现实眼镜,虽然Google Glass项目最终并未能继续下去,但它给整个AR行业带来了生机和活力,AR研究及应用由此进入蓬勃发展时期。2017年Apple公司的ARKit和Google公司的ARCore SDK的推出,把AR从专门的硬件中剥离了出来,使得人们可以通过普通手机体验到AR带来的奇妙感受。AR越来越受到各大公司的重视,技术也是日新月异,百花齐放。
顾名思义,增强现实是对现实世界环境的一种增强,即现实世界中的物体被计算机生成的文字、图像、视频、3D模型、动画等虚拟信息“增强”。叠加的虚拟信息可以是建设性的(即对现实环境的附加),也可以是破坏性的(即对现实环境的掩蔽),并与现实世界无缝地交织在一起,让人产生身临其境的感觉,分不清虚实。通过这种方式,增强现实可以改变用户对真实世界环境的持续感知能力,这与虚拟现实将虚实隔离,用虚拟环境完全取代用户所处的真实世界环境完全不一样。
增强现实的主要价值在于它将数字世界带入个人对现实世界的感知,而不是简单地显示数据,通过与被视为环境自然部分的沉浸式集成来实现对现实的增强。借助先进的AR技术(例如计算机视觉和物体识别),用户周围的真实世界变得可交互和可操作。简而言之,AR就是将虚拟信息放在现实世界中展现,并且让用户和虚拟信息进行互动,AR通过环境理解、注册等技术手段将现实与虚拟信息进行无缝对接,将在现实中可能不存在的事物构建在与真实环境一致的同一个三维场景中并予以展现、衔接融合。增强现实技术将改变我们观察世界的方式,想像在路上用户行走或者驱车行驶,通过增强现实显示器(AR眼镜或者全透明挡风玻璃显示器),信息化图像将出现在用户的视野之内(如路标、导航、提示),并且所播放的声音与用户所看到的场景保持同步,这些增强信息将实时进行更新,从而引发人们对世界认知方式的变革。
AR技术是一门交叉综合学科的技术,其涉及数学、物理、工程技术、信息技术、计算机技术等多领域的知识,相关专业术语、概念也非常多,其中重要的概念术语主要有以下这些。
硬件是AR的物质基础,增强现实需要的硬件主要包括处理器、显示器、传感器和输入设备。有些需要一些特殊的硬件,如深度传感器、眼镜,通常这类AR往往价格昂贵,有些则不需要专门的硬件,普通的移动端,如智能手机和平板电脑就能满足,但也通常包括照相机和MEMS传感器,如加速度计、GPS和固态电子罗盘等。
在增强现实中叠加的虚拟信息需要借助显示设备反馈到人脑中,这些显示设备包括光学投影系统、显示器、手持设备和佩戴在人体上的显示系统。头戴式显示器,简称头显。头显(Head Mounted Display,HMD)是一种佩戴在前额上的显示装置。HMD将物理世界和虚拟物体的图像放置在用户的眼球视场上,现代HMD常使用传感器进行六自由度监控,允许系统将虚拟信息与物理世界对齐,并根据用户头部运动相应地调整虚拟信息;眼镜是另一个常见的AR显示设备,眼镜相对更便携也更轻巧;移动端如手机屏幕也是AR常见显示设备。
眼镜(Glasses),这里特指类似近视眼镜的AR显示器,但它远比近视眼镜复杂,它使用相机采集真实环境场景,通过处理器对环境进行跟踪并叠加虚拟信息,并将增强的虚拟信息投射在目镜上。
平视显示器(HUD)是一种透明的显示器,可谓是增强现实技术的先驱设备,在20世纪50年代首次为飞行员开发,它将简单的飞行数据投射到他们的视线中,从而让他们保持“抬头”而不用看仪器设备。因为HUD可以显示数据、信息和图像,同时允许用户查看真实世界,所以它也是一种AR显示设备。
空间增强现实(Spatial Augmented Reality,SAR)利用数字投影仪在物理对象上显示图形信息,其系统的虚拟内容直接投影在现实世界中。任何物体表面,如墙、桌、泡沫、木块表面甚至是人体表面都可以成为可交互的显示屏。随着投影设备尺寸的减小,成本、功耗的降低以及3D投影技术的不断进步,SAR也处于快速发展阶段。
跟踪是AR实现定位的基础,增强现实系统可使用以下跟踪技术中的一种或多种:RGB相机或其他光学传感器、加速度计、GPS、陀螺仪、固态罗盘、RFID、深度相机、结构光、TOF。这些技术为跟踪提供了测量方面的支持。跟踪最重要的是需要跟踪用户头部或虚拟现实设备的姿态,跟踪用户的手或手持式输入设备,提供六自由度交互。
随着移动设备、可穿戴设备的普及,AR正在变得越来越受欢迎。但是,虚拟现实往往依赖于计算密集型计算机视觉及人工智能算法,所以对处理及传输延迟方面有非常高的要求。为了弥补单台设备计算能力的不足,有时还需要将数据处理功能移到中心服务器上,这在延迟和带宽方面对网络提出了非常高的要求,而5G技术的发展有利于解决这个问题。
输入技术包括普通的屏幕输入、手柄输入、将声音翻译成计算机指令的语音识别设备、用户身体运动的肢体识别和手势识别设备等。
处理器负责与增强现实相关的图形及算法运算,使得虚实融合、显示等。处理器接收来自传感器的数据——获取的环境信息,理解注册跟踪环境,生成图像视频模型等虚拟信息并叠加到合适的位置,最后渲染到显示设备上供用户查看。处理器也可从硬盘或者数据库中读取信息,随着技术和处理器的改进,处理器的运算速度越快,增强现实能处理的信息就越多,增强现实效果就越流畅越真实。
AR系统的一个关键指标是虚拟信息与现实世界的结合度。AR系统从摄像机图像中获取与摄像机无关的真实世界坐标,这个过程被称为图像配准。这个过程通常由两个阶段组成:第一阶段是在摄像机图像中检测特征点、基准标记或光流。在第一个阶段中可以使用特征检测方法,如角点检测、斑点检测、边缘检测或阈值处理等图像处理方法;第二阶段是用第一阶段获得的数据恢复真实世界坐标系,在某些情况下,场景三维结构应预先计算。在第二阶段中可以使用的数学方法包括射影(极线)几何、几何代数、指数映射旋转表示、卡尔曼滤波和粒子滤波、非线性优化、稳健统计等。在AR中,软件与算法大多与计算机视觉相关,且主要与图像识别跟踪相关,增强现实的许多计算机视觉方法是从视觉测径法继承的。
AR中叠加的虚拟信息应该支持与用户的交互,它最令人兴奋的因素是对3D虚拟空间的引入能力,并能在现实中与虚拟信息进行交互。这个交互包括对用户操作的反馈,也包括程序自发的主动交互,如随着距离的不同显示不同的细节信息等。
AR系统具有3个突出的特点:
① 真实世界和虚拟信息融合;
② 具有实时交互性;
③ 在三维空间中定位AR子流产生的虚拟物体。
AR技术可以将虚拟信息叠加到现实世界之上,因而在很多领域都有广泛的应用前景和发展潜力。AR技术可广泛应用于数字领域。游戏娱乐领域是最显而易见的应用领域,AR游戏最早并非起源于手机,而是起源于NDS。此类游戏大多数的玩法是在桌面上摆放识别卡,然后玩家可通过手机屏幕与识别出来的内容进行交互。2011年任天堂3DS主机内置的“AR游戏”可利用摄像头拍摄“AR卡片”,利用AR技术将摄像头拍摄到的内容以另外一种形式展现在屏幕内;2019年4月,国内AR探索手游《一起来捉妖》上线,这是与Pokémon Go差不多的捉怪游戏。在娱乐、游戏领域中,AR正处于快速发展阶段。
除此之外,AR技术在文学、考古、博物、建筑、视觉艺术、零售、应急管理/搜救、教育、社会互动、工业设计、医学、空间沉浸与互动、飞行训练、导航、旅游观光、音乐、虚拟装潢等领域都有着广阔的应用前景。
提示
在本书中:1.虚拟对象、虚拟信息、虚拟物体均指在真实环境上叠加的由计算机处理、生成的文字、图像、3D模型、视频等非真实信息,严格来讲这三者是有差别的,但有时我们在描述时并不严格区分这三者;2.Unity、Unity3D均指Unity 3D引擎软件;3.Vertex Shader、顶点着色器、顶点Shader均指顶点Cg代码,Fragment Shader、片元着色器、片元Shader均指片元Cg代码。
AR带给用户奇妙体验是因为有数学、物理、几何、人工智能、传感器、工程、计算机科学等高新技术的支持,对开发人员而言,了解其技术原理有助于理解AR的整个运行生命周期;理解其优势与不足,可更好地服务于应用开发工作。
环境注册与跟踪是AR的基本功能,即时定位与地图映射(Simultaneous Localization And Mapping,SLAM)是在未知环境中确定周边环境的一种通行技术手段,其最早由科学家Smith、Self、Cheeseman于1988年提出。SLAM技术解决的问题可以描述为:将一个机器人放入未知环境中的未知位置,想办法让机器人逐步绘制出该环境的完全地图,所谓完全地图(Consistent Map)是指可使人不受障碍地进入每个角落的地图。SLAM作为一种基础技术,最早用于军事(核潜艇海底定位就有了SLAM的雏形),如今,它逐步走入大众的。当前,在室外我们可以利用GPS、北斗等导航系统实现高精度的定位,这基本上解决了室外的定位和定姿问题,而室内定位的发展则缓慢得多。为解决室内的定位定姿问题,SLAM技术逐渐脱颖而出。SLAM一般处理流程包括Track和Map两部分。所谓的Track是用来估测相机的位姿的,也叫前端,而Map部分(后端)则是进行深度的构建,通过前端的跟踪模块估测得到相机的位姿,采用三角法(Triangulation)计算相应特征点的深度,然后进行当前环境Map的重建,重建出的Map同时为前端提供更好的位姿估测,并可以用于闭环检测。SLAM是机器人技术、AR技术中自主导航的基础技术,近年来发展得非常快,图1-2是Kumar教授进行SLAM实验的图示。
▲图1-2 Kumar教授进行SLAM实验
定位与跟踪系统是AR的基础,目前在技术上,解决室内定位与位姿问题主要采用视觉惯性测距系统(Visual Inertial Odometry,VIO)和惯性导航系统。综合使用VIO与惯性导航系统可以通过软件实时追踪用户的空间位置(用户在空间上的六自由度姿态)。VIO在帧刷新之间计算用户的位置,为保持应用流畅,VIO速度必须达到每秒30次及以上。这些计算要并行完成两次,通过视觉(摄像)系统将现实世界中的一个点与摄像机传感器上的一帧像素匹配,从而追踪用户的姿态。惯性导航系统(设备加速度计和陀螺仪统称为惯性测量单元,即Inertial Measurement Unit,简称IMU)也可以追踪用户的姿势,VIO与惯性导航系统并行计算,在计算完之后,卡尔曼滤波器(Kalman Filter)结合两个系统的输出结果,评估哪一个系统提供的估测更接近用户的“真实”位置,从而作出选择。定位与跟踪系统追踪用户在三维空间中的运动,作用类似于汽车里程表与加速计等。
提示
自由度(Degrees of Freedom,DOF)是指物理学当中描述一个物理状态,可独立对物理状态的结果产生影响的变量的数量。运动自由度是确定一个系统在空间中的位置所需要的最小坐标数。在三维坐标系中描述一个物体在空间中的位置和朝向信息需要6个自由度数据,即6DOF,指x轴、y轴、z轴方向上的三维运动(移动)加上俯仰/偏转/滚动(旋转)。
惯性导航系统的最大优势是IMU的读取速度大约为1000次每秒,并且这是基于加速度的(设备移动),可以提供更高的精度,通过航迹推算(Dead Reckoning)即可快速测量设备移动。航迹推算是一种估算方法,类似于向前走一步,然后估测行走距离。估测出的结果会有误差,并且这类误差会随时间累积,所以IMU帧率越高,惯性导航系统从视觉系统中复位所需的时间越长,追踪位置与真实位置偏差就越多。
VIO使用摄像头采集视觉信息,设备帧率通常为30帧/秒并且依赖场景复杂度(不同的场景帧率也有所不同)。通常随着距离的增大,光学系统测量误差也不断地增大(时间也会有轻度影响),所以用户移动得越远,误差就越大。
惯性导航系统与视觉测量系统各有各的优势和不足,但惯性导航和视觉测量是基于完全不同的测量方法,它们之间并没有相互依赖的关系。这意味着在遮蔽摄像头或者只看到一个具有很少光学特征的场景(例如白墙)时惯性导航系统照样可以正常工作,或者设备在完全静止的条件下,视觉测量系统可以呈现出一个比惯性导航系统更加稳定的状态。卡尔曼滤波器会不断地选择最佳姿态,从而实现稳定跟踪。
在具体实现上,为了获得精确定位,VIO需要获取两张有差异的场景图像,然后对当前位置进行立体计算。人眼通过类似原理观察3D世界,一些跟踪器也因此依赖立体相机。采用两台相机比较好计算,测量两个相机之间的距离,同时捕获帧进行视差计算;而在只有一个相机时,可以先捕捉一次画面,然后移动到下一个位置进行第二次捕捉,再进行视差计算。使用IMU航迹推算可以计算两次数据读取位置之间的距离然后正常进行立体计算(也可以多捕获几次使计算更加准确)。为了获得较高的精度,系统依赖IMU精确航迹推算,从IMU读取的加速度和时间测量中,可以计算出速度和在获取两次画面之间设备移动的实际距离(公式S=0.5×a×t2)。使用IMU的困难是从IMU中除去误差以获得精确的加速度测量结果,在设备移动的几秒钟之内,若每秒运行1000次,一个微小的错误会造成很大程度的误差积累。
深度相机可以帮助设备增强对环境的理解。在低特征场景中,深度相机对提高设备地面检测、度量标度以及边界追踪的精度有很大的帮助。但是深度相机能耗较大,因此只有以非常低的帧率使用深度相机才能降低设备耗能。移动设备上的深度相机的拍摄范围也比较有限,这意味着它们只适合在手机上的短距离范围内使用(几米的范围),另外深度相机在成本方面也比较昂贵,因此原始设备制造商(Original Equipment Manufacturer,OEM)目前都避免在手机上大量采用。
立体RGB或鱼眼镜头也有助于人们看到更大范围的场景(因为立体RGB和鱼眼镜头具有潜在的光学特性。例如通过普通镜头可能只会看到白色的墙壁,但是通过一个鱼眼镜头可以在画面中看到有图案的天花板和地毯,Tango和Hololens就使用这种方法)。并且相对VIO而言,它们可以用更低的计算成本来获取深度信息。由于手机立体摄像头之间的距离非常近,因此手机上深度计算的精度范围也受到限制(相隔数厘米距离的手机相机在深度计算的误差上可以达到数米)。除此之外,TOF(Time Of Flight)、结构光方式也在快速的发展当中。
但综合设备存量、成本、精度各方面因素,VIO结合IMU进行位置定位跟踪仍将是以后一段时间内的主流做法。
为了使软件能够精确地匹配摄像机传感器上的像素与现实世界中的“点”,摄像机系统需要进行精密的校准。
几何校准:使用相机的针孔模型来校正镜头的视野和镜筒效果。由于镜头的形状,所有采集到的图像都会产生变形,软件开发人员可以在没有OEM帮助的情况下使用棋盘格和基本公开的相机规格进行几何校正,如图1-3所示。
▲图1-3 对图像信息进行几何校准示意图
光度校准:光度校准涉及底层技术,通常要求OEM参与。因为光度校准涉及图像传感器本身的细节特征以及内部透镜所用的涂层材料特性等,光度校准一般用于处理色彩和强度的映射。例如,正在拍摄遥远星星的望远镜连接的摄像机需要知道,传感器上一个像素光强度的轻微变化是否确实源于星星的光强变化,或者仅源于传感器或透镜中的像素差。光度校准对于AR跟踪器的好处是提高了像素和真实世界中的点的匹配度,因此可使视觉跟踪具有更强的鲁棒性以及出现更少的错误。
当我们在考虑IMU时,一定要记住IMU是用来测量加速度而不是距离或速度的,这点很重要。IMU数据读取错误造成的计算结果误差会随着时间的推移快速累积,校准和建模的目标就是确保距离测量具有足够的精度。理想情况下,在使用IMU时可以使摄像机具有足够长的时间来弥补由于用户遮盖镜头,或者场景中发生其他意外所造成视频帧跟踪的丢失。使用IMU测量距离的航迹推算是一种估测,但是通过对IMU行为进行建模,找出产生错误的所有来源,然后通过编写过滤器来减少这些错误,可以使这个估测更加精确。想象一下用户向前走一步,然后猜测用户走了几米这样的场景,仅凭一步去估测结果会有很大的误差,但是如果重复上千步,那么对用户每步的估测与实际行走距离的估测最终会变得非常准确。这就是IMU校准和建模的原理。
在IMU中会有很多错误来源,它们都需要分析捕获并过滤。假设一个机器臂通常用于以完全相同的方式重复地移动,对其IMU的输出不断进行采集和过滤,直到IMU的输出能够和机器臂的实际移动十分精确地匹配,这就是IMU校准与建模的过程。从IMU中获得非常高的精度很困难,对于设备厂商而言,必须消除所有引起这些误差的因素。Google和微软甚至将他们的设备发送到太空微重力环境中,以便消除额外的误差。
3D重建(3D Reconstruction)系统能够计算出场景中真实物体的形状和结构,并对真实环境进行3D重建,因此可以实现虚拟对象与真实物体发生碰撞或遮挡,如图1-4所示。要将虚拟对象隐藏在真实物体之后,就必须要对真实物体进行识别与重建。目前来看3D重建还有很多难点需要克服,当前移动端AR基本都不支持3D重建,因此AR中的虚拟对象会一直浮在真实物体的前面。3D重建通过从场景中捕获密集的点云(使用深度相机或者RGB相机),将其转换为网格,并将网格传递给3D重建系统(连同真实世界的坐标),然后将真实世界网格精准地放置在相机所捕获的场景上。在对真实环境进行3D重建后虚拟对象就可以与真实物体互动,实现碰撞或遮挡。
▲图1-4 Magic Leap演示的遮挡效果
提示
3D重建在Hololens术语中叫空间映射,在Tango术语中叫深度感知。
通过图像获取、摄像机标定、特征提取、立体匹配获取比较精确的匹配结果,结合摄像机标定的内外参数,就可以恢复三维场景信息。由于3D重建精度受匹配精度、摄像机的内外参数误差等因素的影响,只有重建前各个环节的精度高、误差小,才能较好地恢复真实场景的三维空间结构。我们只了解一下3D重建的概念,本书中我们不会用到3D重建相关的知识。但3D重建在构建AR系统深度信息方面非常重要,3D重建是实现真实物体与虚拟物体碰撞或遮挡的基础。
2017年,Apple公司与Google公司相继推出了各自的AR开发SDK工具包ARKit和ARCore,分别对应iOS平台与Android平台AR开发。ARKit和ARCore推出后,极大地促进了AR在移动端的普及发展,将AR从实验室带入了普通消费场景。
ARCore官方提供了Android、Android NDK、Unity、Unreal等开发包,ARKit官方只提供了XCode开发包,这也增加了利用其他工具进行开发的开发者的学习成本。在这种情况下,Unity构建了一个AR开发平台,这就是AR Foundation,这个平台架构在ARKit和ARCore之上,其目的就是利用Unity跨平台能力构建一种与平台无关的AR开发环境。换句话说,AR Foundation对ARKit和ARCore进行了再次封装,提供给开发者一致的开发界面,并按照用户的发布平台自动选择合适的底层SDK版本。
因此,AR Foundation是ARKit XR插件(com.unity.xr.arkit)和ARCore XR插件(com.unity. xr.arcore)的集合,虽然最终都会使用ARKit或ARCore,但因为Unity再次封装,它与专业平台(如ARKit插件和ARCore SDK for Unity)相比,C#调用与原生API略有不同。
AR Foundation的目标并不局限于ARKit与ARCore,它的目标是建成一个统一、开放的AR开发平台,因此,AR Foundation极有可能在下一步发展中纳入其他AR SDK,进一步丰富AR开发环境。在后续发展中,AR Foundation不仅会支持移动端AR设备开发,还会支持穿戴式AR设备开发。
从上面的描述我们可以看出,AR Foundation并不提供AR的底层开发API,这些与平台相关的API均由第三方,如ARKit、ARCore、SenseAR提供,因此AR Foundation对某特定第三方功能的实现要比原生的晚(AR Foundation将某第三方SDK的特定功能集成需要时间)。
AR Foundation提供了一个独立于平台的脚本API和MonoBehaviour,因此,开发者可以通过AR Foundation使用ARKit和ARCore共有的核心功能构建同时适用于iOS和Android两个平台的AR应用程序。换句话说,这可以让开发者只需开发一次应用,就可以将其部署到两个平台的设备上,不必做任何改动。
如前所述,AR Foundation实现某底层SDK的功能会比原生的稍晚,因此,如果我们要开发AR Foundation尚不支持的功能,可以单独使用对应的原生SDK。目前,如果我们只面向ARCore进行开发并希望获取完整的功能集,可使用Google为Unity开发提供的ARCore SDK for Unity;如果只面向ARKit进行开发并希望获取完整的功能集,可使用Unity提供的适用于Unity开发的ARKit插件(Apple并未提供Unity的ARKit SDK开发插件,在AR Foundation发展起来以后,Unity肯定不会再继续维护ARKit插件)。
AR Foundation架构于ARKit和ARCore之上,其与ARKit、ARCore的关系如图1-5所示。
▲图1-5 AR Foundation与ARCore、ARKit的关系图
在Unity引擎上,AR Foundation与ARCore、ARKit的区别如表1-1如示。
表1-1 AR Foundation、ARCore、ARKit联系与区别
SDK |
简介描述 |
---|---|
AR Foundation |
AR Foundation将ARKit和ARCore的底层API封装整合到一个统一、开放的框架中,并提供一些额外的实用功能,如Session生命周期管理,以及用于展示环境中已检测功能的MonoBehaviour |
Google ARCore SDK for Unity |
该SDK为ARCore支持Unity开发环境提供的原生API,并在Unity中向Android平台公开这些API,以方便开发者调用 |
Unity ARKit Plugin |
该插件是Unity开发的ARKit for Unity插件,用于在Unity中构建ARKit应用,它在Unity中公开了C#的ARKit Objective-C API,以便开发者调用。该插件还提供一些辅助功能,可以兼容iOS设备的前置和后置摄像头 |
AR Foundation与ARCore、ARKit都正处于快速发展中,ARCore基本保持每两个月进行一次更新的频率,ARKit也已经迭代到了ARKit 3,作为ARKit与ARCore上层的 AR Foundaion也已经更新到v3.0版。
但如前文所说,AR Foundation功能的实现要比底层的原生API稍晚一些,表1-2展示了AR Foundation、ARCore和ARKit功能对比。
表1-2 AR Foundation、ARCore、ARKit功能对比
支持功能 |
AR Foundation |
ARCore |
ARKit |
---|---|---|---|
垂直平面检测 |
√ |
√ |
√ |
水平平面检测 |
√ |
√ |
√ |
特征点检测 |
√ |
√+支持特征点姿态 |
√ |
光照估计 |
√ |
√+Color Correction |
√+Color Temperature |
射线检测(Hit Testing,对特征点与平面) |
√ |
√ |
√ |
图像跟踪 |
√ |
√ |
√ |
3D物体检测与跟踪 |
√ |
- |
√ |
环境光探头(Environment Probes) |
√ |
√ |
√ |
世界地图(World Maps) |
√ |
- |
√ |
人脸跟踪(Pose、Mesh、Region、Blendshape) |
√ |
√ |
√(iPhoneX 及更高型号) |
云锚点(Cloud Anchors) |
√ |
√ |
- |
远程调试(Editor Remoting) |
开发中 |
√-Instant Preview |
√-ARKit Remote |
模拟器(Editor Simulation) |
√ |
- |
- |
LWRP支持(支持使用ShaderGraph) |
√ |
开发中 |
开发中 |
摄像机图像API(Camera Image) |
√ |
√ |
- |
人体动作捕捉(Motion Capture) |
√ |
- |
√(iPhoneXR 及更高型号) |
人形遮挡(People Occlusion) |
√ |
- |
√(iPhoneXR 及更高型号) |
多人脸检测 |
√ |
√ |
√(iPhoneXR 及更高型号) |
多人协作(Collaborative Session) |
√ |
- |
√(iPhoneXR 及更高型号) |
多图像识别 |
√ |
√ |
√ |
AR应用是计算密集型应用,对计算硬件要求较高,就算在应用中对虚拟对象都不进行渲染,AR也在对环境、特征点跟踪进行实时解算。由于移动端硬件设备资源限制,一些高级AR应用只能在最新的处理器(包括CPU和GPU)上才能运行。同时得益于Apple强大的独立生态与软硬件整合能力,它在ARKit 3中推出了很多新功能,但由于目前Android系统碎片化严重,ARCore预计要等到新版Android系统发布后才能提供类似的功能。
AR Foundation只是对ARCore和ARKit再次封装,并不实现AR的底层API功能,换言之,AR Foundation只是一个功能的搬运工。因此,底层API没有的功能,AR Foundation也不可能有(AR Foundation会添加一些辅助功能以方便开发者开发AR应用)。同时,AR Foundation能实现的功能也与底层SDK所在平台相关,如ARKit有WorldMap功能,而ARCore没有,因此,即使AR Foundation支持WorldMap功能,这个功能也只能在iOS平台上才有效,在Android平台编译就会出错。这就是说AR Foundation支持的功能与底层SDK是密切相关的,脱离底层SDK谈AR Foundation功能是没有意义的。当然,如果是ARKit和ARCore都支持的功能,AR Foundation做的工作是在编译时根据平台选择无缝切换所用底层SDK,达到一次开发、跨平台部署的目的。
当前,AR Foundation主要支持的功能如表1-3所示。
表1-3 AR Foundation主要支持的功能
功能 |
描述 |
---|---|
世界跟踪(World Tracking) |
在物理空间中跟踪用户设备的位置和方向(姿态) |
平面检测(Plane Detection) |
对水平与垂直平面进行检测 |
参考点(Reference Points) |
对特定点的姿态跟踪。ARCore与ARKit中称为Anchor |
光照估计(Light Estimate) |
对物理环境中的光照强弱及方向进行估计 |
人脸跟踪(Face Tracking) |
检测并跟踪人脸 |
人脸表情捕捉(Facial Expression Capture) |
检测人脸表情 |
图像跟踪(Image Tracking) |
跟踪物理空间中的2D图像 |
物体跟踪(Object Tracking) |
跟踪物理空间中的物体对象,目前只支持ARKit |
Session分享 |
支持多人共享场景,这在ARKit中称为多人协作(Collaborative session)和世界地图(World Maps),在ARCore中称为Cloud Anchor |
人体动作捕捉(Motion Capture) |
简称动捕,检测屏幕空间或者物理空间中的人体及动作 |
人形遮挡(People Occlusion) |
利用计算机视觉判断人体在场景中的位置,获取人体形状及在场景中的位置实现虚拟物体遮挡 |
摄像机图像API |
提供摄像机图像底层支持,方便开发人员开发计算机视觉应用 |
虽然AR Foundtion是在底层SDK API之上的再次封装,但Unity为了实现AR跨平台应用做了大量工作,搭建了一个开放性的架构,使这个架构能够容纳各类底层SDK,能支持当前及以后其他底层SDK的加入,宏观上看,AR Foundation希望构建一个开发各类AR应用的统一平台。
为实现这个开放的架构,AR Foundation建立在一系列的子系统(Subsystem)之上。Subsystem隶属于UnityEngine.XR.ARSubsystems命名空间,负责实现特定的功能模块,而且这个实现与平台无关,即Subsystem处理与平台无关的特定模块的实现。如XRPlaneSubsystem负责实现平面检测、显示功能,在编译时,根据不同的运行平台自动调用不同底层的SDK。从调用者的角度看,只需要调用XRPlaneSubsystem的功能,而不用管最终这个实现是基于iOS还是Android,即对平台透明。
这种架构对上提供了与平台无关的功能,对下可以在以后的发展中纳入不同的底层SDK,从而实现最终的一次开发、跨平台部署的目标。其架构如图1-6所示。
▲图1-6 AR Foundation体系架构
世界跟踪指AR设备确定其在物理世界中的相对位置和方向的能力,在2D和3D空间中跟踪用户的运动并最终定位它们的位置是任何AR应用程序的基础。当设备在现实世界中移动时,AR Foundation会通过一个名为并行测距与映射(Concurrent Odometry and Mapping,COM)的过程来理解移动设备相对于周围世界的位置。AR Foundation会检测从摄像头图像中捕获的视觉差异特征(称为特征点),并使用这些点来计算其位置变化。这些视觉信息将与设备IMU惯性测量结果结合,一起用于估测摄像头随着时间推移而相对于周围世界的姿态(位置和方向)。
通过将渲染3D内容的虚拟摄像机的姿态与AR Foundation提供的设备摄像头的姿态对齐,就能够从正确的透视角度渲染虚拟内容,渲染的虚拟图像可以叠加到从设备摄像头获取的图像上,让虚拟内容看起来就像真实世界的一部分。
可跟踪指可以被AR设备检测/跟踪的真实特征,例如特征点、平面、人脸、人形、2D图像、3D物体等。
AR设备使用摄像机和图像分析来跟踪环境中用于构建环境地图的特定点,例如木纹表面的纹理点、书本封面的图像,这些点通常都是视觉差异点。特征点云包含了观察到的3D点和视觉特征点的集合,通常还附有检测时的时间戳。
会话的功能是管理AR系统的状态,是AR API的主要入口。在开始使用AR API的时候,可通过对比ARSessionState状态值来检查当前设备是否支持AR。Session负责处理整个AR应用的生命周期,控制AR系统根据需要开始和暂停视频帧的采集、初始化、释放资源等。
Session空间即AR Session初始化后建立的的坐标空间,Session空间原点(0,0,0)是指创建AR会话的位置。AR设备跟踪的坐标信息都是处在Session空间中,因此在使用时,需要将其从Session空间转换到其他空间,这个过程类似于模型空间和世界空间的转换。
AR Foundation利用射线检测来获取对应于手机屏幕的 (x,y) 坐标(通过点按或应用支持的任何其他交互方式),将一条射线投射到摄像头的视野中,返回这条射线贯穿的任何平面或特征点以及碰撞位置在现实世界空间中的姿态,这让用户可以选择环境中的物体。
使用增强图像(图像检测)可以构建能够响应特定2D图像(如产品包装或电影海报)的AR应用, 用户将手机的摄像头对准特定图像时触发AR体验,例如,他们可以将手机的摄像头对准电影海报,使人物弹出,或者引发一个场景。可离线编译图像以创建图像数据库,也可以在运行时实时添加参考图像,AR Foundation将检测这些图像、图像边界,然后返回相应的姿态。
借助于ARKit中的多人协作Session(Collaborative Session)或者ARCore中的Cloud Anchor,可以创建适用于iOS或Android设备的多人共享应用。在Android中使用云锚点,一台设备可以将锚点及其附近的特征点发送到云端进行托管,并可以将这些锚点与同一环境中Android或iOS设备上的其他用户共享,从而让用户能够同步拥有相同的AR体验。在ARKit中,利用协作Session或者WorldMap也可以直接在参与方中共享AR体验。
AR中大部分内容需要依托于平面进行渲染,如虚拟机器人,只有在检测到平面网格的地方才能放置。平面可分为水平、垂直两类,Plane描述了真实世界中的一个二维平面,如平面的中心点、平面的x和z轴方向长度、组成平面多边形的顶点。检测到的平面还分为三种状态,分别是正在跟踪、可恢复跟踪、永不恢复跟踪。不在跟踪状态的平面包含的平面信息可能不准确。两个或者多个平面还会被自动合并。
在AR Foundation的所有API中,Pose总是描述从物体的局部坐标系到世界坐标系的变换,即来自AR Foundation API的Pose可以被认同为OpenGL的模型矩阵或DirectX的世界矩阵。随着AR Foundation对环境理解的不断加深,它将自动调整坐标系以便其与真实世界保持一致。因此,每一帧图像都应被认为是处于一个完全独立的世界坐标空间中。
光照估计给我们提供了一个查询当前帧光照环境的接口,可以获取当前相机视图的光照强度、颜色分量以及光照方向,使用光照估计信息绘制虚拟对象照明效果会更真实,并且可以根据光照方向调整AR中虚拟物体的阴影方向,增强虚拟物体的真实感。
AR Foundation是Unity引擎的一个功能组件,因此在开发应用之前,首先需要安装Unity引擎。下面我们将引导读者完成Unity引擎的安装与设置。
(1)下载并安装Unity Hub。可以直接从Unity官方网站上下载(https://store.unity.com/ download-nuo)Unity Hub。Unity Hub为Unity集成管理工具,负责Unity各版本的安装管理、项目创建、账户授权管理等工作。下载Unity Hub时需要创建Unity用户账号,安装Unity Hub并启动,选择左侧的选项卡中的“安装”,界面如图1-7所示(这里我们已经安装了3个版本的Unity,第一次安装完Unity Hub并打开后,这个列表是空的)。
▲图1-7 Unity Hub安装界面
(2)在图1-7中,单击右上角的“安装”按钮,会打开Unity版本安装选择界面,如图1-8所示。
从列表中选择所需的Untiy版本。版本后带有f的为Final版本(最终版),带有a的为Alpha版本,带有b的为Beta版本,带有LTS的为Long-Term Support版本(长期支持版)。通常开发正式应用应当选择f版或者LTS版,Alpha版本与Beta版本可能会有各种缺陷和Bug。
▲图1-8 Unity版本安装选择界面
提示
在本书的编写过程中,为纳入最新技术,我们使用了多个版本的Unity,如基于ARKit 3的功能需要Unity 2019.3.0、XCode 11以上版本。
(3)在图1-8中选择一个版本后,单击“下一步”会打开Unity功能模块选择界面,如图1-9所示。
▲图1-9 Unity功能模块选择界面
读者可以根据自己的需求添加或者删除功能模块,通常我们会根据发布的手机平台选择Android Build Support或者iOS Build Support功能模块,否则,在工程创建后将无法切换发布平台。当然,这里选错、漏选也没关系,后期可以在Unity Hub安装界面里随时为已安装的Unity版本添加、删除功能模块。
(4)Android Studio安装(可选)。在进行Android开发时,Android Studio为可选安装步骤,如果不安装Android Studio,Unity引擎在安装时会自动下载并安装Android SDK和JDK。但安装Android Studio可以为计算机提供Android开发环境,方便实现高级开发,并能提供一些功能模拟及SDK版本管理,因此建议安装。可以到Google官网下载Android Studio,Android Studio开发界面如图1-10所示。
▲图1-10 Android Studio开发界面
(5)在Mac计算机中进行iOS平台开发时,需要下载安装XCode,可以在苹果官网下载最新版XCode,有多种版本可供选择,这里也需要注意,Alpha版本与Beta版本生成发布的应用无法登录AppStore,正式开发最好选择正式版本(即不带后缀alpha、beta字样的版本)。通常也可以直接在Mac计算机上启动AppStore安装XCode。
(6)在安装完Unity引擎后,最好先检测一下相关开发配置。新建一个项目,打开Unity引擎,在菜单中,依次选择Edit➤Preferences,打开Preference对话框,如图1-11所示。
▲图1-11 Preference对话框
在这里可以配置脚本编辑IDE、图片编辑软件,设置JDK/Andriod SDK/NDK。如果Unity工程在编译过程中出现一些非代码性的问题,多半是这里设置不正确。从图1-11也可以看到,Unity推荐使用引擎自带安装JDK/Andriod SDK/NDK的方法,但也允许开发者自定义JDK/Andriod SDK/NDK安装路径。
AR Foundation支持跨平台开发,但在不同平台,其开发环境配置与发布部署差异较大,因此,环境配置我们分成Android开发环境配置与iOS开发环境配置两部分进行讲解,本节主要针对Android开发。
现在我们创建一个新的项目,并导入AR Foundation和ARCore XR Plugin。使用鼠标单击“开始”菜单中的相应软件或者双击桌面的Unity图标(或者Unity Hub图标)启动Unity,单击“New”新建一个项目,命名为Helloworld,然后单击“创建项目”按钮,如图1-12所示。
▲图1-12 创建项目对话框
待Unity主窗口打开后,单击Unity菜单栏Window➤Package Manager,如图1-13所示,将打开Package Manager对话框。
▲图1-13 打开Package Manager对话框
Package Manager对话框默认不显示preview状态的AR Foundation和ARCore XR Plugin,单击对话框中的Advanced下拉菜单,选择Show preview packages,将显示所有的preview插件,如图1-14所示。
▲图1-14 选择Show preview packages下拉菜单选项
在左侧列表中选择AR Foundation后右侧面板将会显示该插件的详细信息,单击右下角的“Install”按钮安装插件,如图1-15所示。如此操作,将ARCore XR Plugin插件也安装好。
▲图1-15 安装ARCore XR Plugin插件
至此,已经将开发Android AR应用所需插件都导入了。
在Unity窗口中,按Ctrl+Shift+B快捷键,或者在菜单栏中选择File➤Build Settings…,打开设置窗口。选择“Platform”下的“Android”选项,然后单击“Switch Platform”按钮切换到Android平台。当Unity标志出现在Android选项旁边时,发布平台就切换成Android了,如图1-16所示。
单击左下角的“Player Settings…”按钮继续后续设置,如图1-17所示,选择Player,在Player栏中的Company Name与Product Name文本框中分别填写公司名与产品名,选择Android小图标,在Other Settings选项卡中删除Vulkan,因为Android目前不支持Vulkan。
▲图1-16 Build Settings对话框
▲图1-17 Player设置对话框(1)
继续向下滚动,在Identification栏中,Package Name填写应用程序包名,建议与上图Company Name和Product Name中输入的公司名和产品名一致。这个值要求唯一,因为如果它与另一个应用程序具有相同的包名,可能会导致问题。另外,我们还需要设置与ARCore兼容的Android最低版本,找到“Minimun API Level”选项,单击其下拉菜单,选择“Android7.0‘Nougat’(API level 24)”或以上,如图1-18所示,正如这个选项名字一样,应用程序与ARCore将不会在Nougat版本之前的Android设备上运行。同时,我们还需要设置“Target API Level”,这里设置的是“Android 8.0 ‘Oreo’ (API level 26)”,因为笔者的测试手机就是这个版本,读者可根据自己的需要设置,但目标版本不得低于Nougat,不然开发的AR应用将无法运行。
在完成以上设置后,单击“Other Settings”收起Other Settings设置折叠栏,然后单击“XR Settings”折叠栏展开之,在使用ARCore原生SDK进行开发时,要求勾选“ARCore Supported”复选框以确保应用得到ARCore的支持,但是在使用AR Foundation和ARCore XR Plugin进行Android AR开发时一定不要选中该复选框,不然编译将无法进行,如图1-19所示。
▲图1-18 Player设置对话框(2)
▲图1-19 确保ARCore Supported复选框不被选中
在Unity 2019以后,为了简化用户操作,Unity在安装的时候会自动进行环境检测。如果检测到已安装JDK和Android SDK后会自动进行设置;如果没有检测到Unity也可以进行集成安装(安装Unity时会一并安装JDK和Android SDK),无需要用户单独安装JDK和Android SDK。
在完成以上设置后,我们来搭建AR Foundation开发AR应用的基础框架,这个基础框架所有AR应用通用。
在Scenes工程文件夹中,我们重命名场景文件为“Helloworld”。为统一规范管理各类文件,在Project窗口Assets目录下新建Prefabs、Scripts两个文件夹,同时在Hierarchy窗口中删除Main Camera(因为AR Foundation AR Session Origin带有一个AR摄像机),Directional Light可根据需要决定是否删除,如图1-20所示。
▲图1-20 删除场景中无关对象,搭建工程基本框架
在Hierarchy窗口中的空白处右击,在弹出的菜单中依次选择XR➤AR Session和XR➤AR Session Origin,添加AR基础组件,如图1-21所示。
▲图1-21 添加AR基础组件
在Hierarchy窗口中的空白处右击,在弹出的菜单中依次选择XR➤AR Default Plane,将Hierarchy窗口中生成的AR Default Plane拖动到Project窗口中的Prefabs文件夹下,制作一个平面预制体,如图1-22所示,然后删除Hierarchy窗口中的AR Default Plane对象。
▲图1-22 制作平面预制体
在Hierarchy窗口选中AR Session Origin对象,然后在Inspector窗口中单击“Add Component”按钮,并在搜索框中输入“ARP”,然后双击搜索出来的AR Plane Manager添加该组件,如图1-23所示。
▲图1-23 添加AR Plane Manager组件
将Project窗口中Prefabs文件夹下的AR Default Plane拖动到ARPlaneManager组件下的Plane Prefab属性框,完成平面预制体的设置,如图1-24所示。
至此,AR应用的基础框架我们已经搭建好了,这是一个AR Foundation开发AR应用的基础框架,流程通用。
▲图1-24 为AR Plane Manager属性赋值
在Project窗口Scripts文件夹下的空白处右击,在弹出的菜单中依次选择Create➤C# Script,新建一个脚本文件,并命名为AppController,如图1-25所示。
▲图1-25 新建AppController脚本文件
双击AppController脚本,在Visual Studio中编辑该脚本,添加如代码清单1-1所示代码。
代码清单1-1
1. using System.Collections.Generic;
2. using UnityEngine;
3. using UnityEngine.XR.ARFoundation;
4. using UnityEngine.XR.ARSubsystems;
5.
6. [RequireComponent(typeof(ARRaycastManager))]
7. public class AppController : MonoBehaviour
8. {
9. public GameObject spawnPrefab;
10. static List<ARRaycastHit> Hits;
11. private ARRaycastManager mRaycastManager;
12. private GameObject spawnedObject = null;
13. private void Start()
14. {
15. Hits = new List<ARRaycastHit>();
16. mRaycastManager = GetComponent<ARRaycastManager>();
17. }
18.
19. void Update()
20. {
21. if (Input.touchCount == 0)
22. return;
23. var touch = Input.GetTouch(0);
24. if (mRaycastManager.Raycast(touch.position, Hits, TrackableType.PlaneWithin
Polygon | TrackableType.PlaneWithinBounds))
25. {
26. var hitPose = Hits[0].pose;
27. if (spawnedObject == null)
28. {
29. spawnedObject = Instantiate(spawnPrefab, hitPose.position, hitPose.rotation);
30. }
31. else
32. {
33. spawnedObject.transform.position = hitPose.position;
34. }
35. }
36. }
37. }
在上述代码中,首先我们使用[RequireComponent(typeof(ARRaycastManager))]属性确保添加该脚本的对象上必须有ARRaycastManager组件,因为射线检测需要用到ARRaycastManager组件。在Update()方法中,我们对手势操作进行射线检测,在检测到的平面上放置一个虚拟物体,如果该虚拟物体已存在,则将该虚拟物体移动到射线检测与平面的碰撞点。
经过以上步骤,整体AR应用框架已完全搭建起来了,为方便演示,我们在Hierarchy窗口中新建一个Cube,为其赋上红色材质,将其Scale缩放成(0.1,0.1,0.1),拖动到Prefabs文件夹中并删除Hierarchy窗口中的Cube,如图1-26所示。
▲图1-26 制作Cube预制体
最后一步,在Hierarchy窗口中选中AR Session Origin,为其挂载前面编写的AppController脚本(可以使用Add Component在搜索框中搜索AppController添加,也可以直接把AppController脚本拖到AR Session Origin对象上),并将上一步制作的Cube拖到AppController脚本的Spawn Prefab属性框中,如图1-27所示。
▲图1-27 将Cube赋给AppController脚本中的Spawn Prefab属性
AR应用已开发完成,将支持ARCore的手机通过USB或者Wi-Fi连接开发计算机(具体连接方法请参见1.6节),直接按Ctrl+Shift+B快捷键(或者选择File➤Build Settings)打开Build Settings对话框。在打开的对话框中保证选中当前场景,如没有出现当前场景,可单击右下方的Add Open Scenes。单击“Build And Run”,设置发布后的程序名,最后单击“Save”按钮开始编译生成apk,生成的apk应用会自动安装到连接的手机上并启动运行,如图1-28所示。
若编译没有错误,在Helloworld AR应用打开后,找一个相对平坦且纹理比较丰富的平面左右移动手机进行平面检测。在检测到平面后,用手指单击手机屏幕上已检测到的平面,将会在该平面上加载一个小立方体,如图1-29所示。至此,我们使用AR Foundation开发的Android Helloworld AR应用已成功。
▲图1-28 编译并运行应用对话框
▲图1-29 应用程序运行效果图
在AR应用开发中,很多时候都需要将应用下载安装到真机上调试。本节中,我们将设置Android手机的开发者模式,通过开发者模式直接通过USB或者Wi-Fi调试应用。然后本节还将介绍使用计算机监视手机运行的AR应用,这也是查找、排除问题的有效手段。
为了方便地将应用编译再发到手机中测试,我们需要启用手机的“Developer Option”,即开发者选项。开发者选项,顾名思义,就是供应用开发者开发调试应用的选项,通过这个功能开发者就可以通过USB接口连接手机,直接在手机上安装、调试自己的应用程序。通过开发者选项可以在计算机和手机之间复制数据、在手机上安装应用、读取日志数据而不用发送通知,也可以查看Android系统的一些数据和信息。默认情况下,开发者选项是隐藏的,但是可以通过连续七次单击手机中的“设置➤关于手机➤软件信息➤编译编号”来解锁开发者选项(需要输入手机密码才能完成)。单击时会有“您还差×步就可以打开开发者模式”的提示。在开发者选项中,我们还需要打开“USB调试”,这样我们才能通过USB接口在手机上调试运行AR应用,如图1-30所示。
注意
不同的手机打开开发者选项的方式不一样,这和手机产商有关,但操作方式大致相同。可以查看手机使用说明获取相关帮助。
(a) (b) (c)
▲图1-30 通过连续单击图1-30a中的“编译编号”解锁显示开发者选项;单击图1-30b中的开发者
选项并输入密码打开开发者选项;打开图1-30c中的“USB调试”启用USB调试功能 开发者选项中有很多参数,这些设置对应用开发者了解应用的运行状态很有帮助,详细的参数及功能说明超出本书的范围,读者可以自行搜索了解。打开开发者选项之后我们就可以通过USB连接手机与计算机来调试AR应用了。 ### 1.6.2 设置手机Wi-Fi调试 使用USB来调试AR应用确实方便很多,但AR应用测试需要四处移动手机,所以有线的方式还是会有束缚。同时,经常插拔USB线还有可能会导致USB接口损坏,而且长期给手机充放电也会损害手机电池性能,下面我们介绍利用Wi-Fi来调试AR应用。 首先需要使用的工具是adb,这是个应用工具,它在Android SDK安装目录下的platform- tools子目录内。使用Wi-Fi来调试AR应用需要手机操作系统的root权限,我们可以在手机上下载安装Android Terminal Emulator来进行辅助。 设置手机Wi-Fi调试的步骤如下。 (1)设置Android手机监听端口。 这一步需要使用shell,因此手机上要有终端模拟器,打开安装的Android Terminal Emulator终端,依次输入代码清单1-2所示代码。
代码清单1-2
1. su //获取root权限
2. setprop service.adb.tcp.port 7890 //设置监听的端口,端口号可以自定义,如7890,5555是默认的
3. stop adbd //关闭adbd
4. start adbd //重新启动adbd
(2)手机连接Wi-Fi后记下手机分配的IP地址(演示手机为192.168.2.107)。
在设置➤关于手机➤状态中可以查看手机连接Wi-Fi后分配的IP地址,如图1-31所示。
▲图1-31 查看手机分配的IP地址
(3)计算机上打开命令窗口,输入代码清单1-3所示命令。
代码清单1-3
1. adb connect 192.168.2.107:7890
2. //如果不输入端口号,默认是5555,自定义的端口号必须写明,对应第1步中自定义的端口号,例如:
192.168.168.127:7890
(4)配置成功,命令行显示:“connected to ×××××××”,然后就可以调试程序了,如代码清单1-4所示。
代码清单1-4
1. C:\Users\Root>adb connect 192.168.2.107:7890
2. connected to 192.168.2.107:7890
如需关闭Wi-Fi调试,将端口号设置为-1,并且重复第一步即可。有了Wi-Fi调试,我们就可以摆脱USB线的束缚了,这样更方便调试AR应用。
提示
采用Wi-Fi的模式调试,需要确保开发者计算机与移动设备在同一子网内。
在使用USB或者Wi-Fi调试应用时,将AR应用编译并推送到手机上需要花费很长时间,但AR应用在移动端运行之后,我们只能看到运行的结果而不能确切地知道在运行过程中发生的事情。作为开发者,我们需要知道AR应用在运行过程中到底发生了什么事情,特别是在运行结果与预期不符的时候,需要查看调试信息排查错误。
本节将介绍远程调试AR应用的方法,通过执行以下步骤,可以使用计算机远程查看运行中的AR应用程序运行状况。
首先通过USB或者Wi-Fi连接到移动设备,然后打开Android SDK安装目录,进入到SDK目录下的Tools子目录内(一般在C:\Users\Administrator\AppData\Local\Android\Sdk\tools目录),双击monitor.bat,打开Android Device Monitor(Android设备监视器)。其左侧列表中的设备即此时连接到计算机的移动设备,选择需要调试的设备,在LogCat窗口将看到AR应用信息,拖动LogCat窗口,使其成为主窗口中的一个选项卡,如图1-32所示。
▲图1-32 使用Android Device Monitor查看AR应用信息
通过查看手机输出信息,可以实时了解AR应用运行状态和调试AR应用,这给我们开发调试带来了足够的灵活性和弹性,在LogCat窗口中我们可以看到应用程序的Debug.log输出。远程调试连接可以与Android Studio一起进行,这为我们带来足够的便利,但是这里的输出信息太多了,而且很多信息我们都不关心,因此需要设置一下以筛选出我们关心的特定日志消息。
为了得到我们关心的信息并屏蔽掉其他无用信息,我们对日志消息进行过滤,过滤的操作步骤如下。
(1)转到Android设备监视器窗口。
(2)单击LogCat➤Saved Filters 面板中的绿色加号按钮创建过滤器。
(3)输入过滤器名称(如Unity)和日志标记(如Unity)创建一个新的过滤器。
(4)单击“OK”添加筛选器。
通过过滤器,我们将不关心的信息过滤掉了,日志消息界面更加清爽,如图1-33所示。在图1-33中我们还可以看到,除了使用日志标记(Log Tag)创建过滤器外,还可以通过日志消息(Log Message)、PID、应用名字(Application Name)、日志等级(Log Level)等来创建过滤器,或者联合其中的两项或多项创建复杂的过滤器,使过滤出来的信息更能符合预期。
▲图1-33 使用过滤器过滤日志消息
配置好一个带有远程连接和调试支持的Unity工作环境将使我们的工作更容易进行,有利于将主要精力投入到应用开发上。
前面我们学习了Android应用的开发环境配置与发布部署,本节主要讲解在Mac计算机上使用Unity开发AR Foundation应用的环境配置与发布部署。AR Foundation在iOS平台使用ARKit底层技术,并且Unity工程不能一次性发布成iOS包文件,Unity利用AR Foundation发布iOS AR应用需要分为两步:第一步使用Unity生成XCode工程文件;第二步利用XCode编译工程文件发布成ipa应用文件,本文假设读者已经安装Unity 2019.1及XCode 10以上版本。
创建一个新的项目,并导入AR Foundation和ARKit XR Plugin。在程序坞或者dock栏上单击Unity图标(或者Unity Hub图标)启动Unity,单击New新建一个项目,选择项目类型、填写项目名称和项目保存位置,项目命名为Helloworld,最后单击右下角“创建”按钮创建项目,如图1-34所示。
▲图1-34 新建一个工程
待Unity窗口打开后,单击Unity菜单栏Window➤Package Manager,如图1-35所示,将打开Package Manager对话框。
▲图1-35 打开Package Manager对话框
Package Manager对话框默认不显示处于preview状态的AR Foundation和ARKit XR Plugin。单击对话框中的Advanced下拉菜单,选择Show preview packages,将显示所有的preview插件,如图1-36、图1-37所示。选择所需的插件包,然后单击右下角的“Install”安装到工程中,完成插件包的导入。
▲图1-36 显示所有preview插件
▲图1-37 导入AR Foundation与ARKit XR Plugin
在Unity窗口中,按Command+Shift+B快捷键,或者在菜单栏中选择File➤Build Settings…,打开设置窗口。选择“Platform”下的“iOS”选项,然后单击“Switch Platform”按钮切换到iOS平台,当Unity标志出现在iOS选项旁边时,发布平台就切换成iOS了,如图1-38所示。
▲图1-38 切换到iOS平台
单击左下方的“Player Settings…”按钮继续后续设置。按顺序依次先选择Player,在Player栏中Company Name与Product Name中填写公司名与产品名,如图1-39所示。选择iOS平台小图标,展开Other Settings选项卡,如图1-40所示。
▲图1-39 设置应用程序信息(1)
图1-40中,在Identification栏,PackageName填写应用程序包名,建议与图1-39中Company Name和Product Name中输入的公司名和产品名一致,这个值要求唯一,因为如果它与另一个应用程序具有相同的包名,可能会导致问题。然后设置好应用程序的版本号。
继续向下滚动,填写摄像机使用信息,这会在AR应用第一次启动时向用户请求摄像头使用权限。设置好Target Device,目标设备可以是iPhone,可以是iPad,也可以为iPhone+iPad。因为我们使用真机进行应用调试,这里设置Target SDK为Device SDK。设置最低iOS版本为11.0,因为支持ARKit的最低iOS版本是11.0,最后设置处理器架构为ARM64,如图1-41所示。
▲图1-40 设置应用程序信息(2)
▲图1-41 设置应用程序信息(3)
细心的读者可能已经发现,在图1-41中有一个“Requires ARKit support”选项,这个选项可以勾选,也可以不勾选,不影响AR Foundation应用开发。至此,我们已完成了利用AR Foundation开发iOS AR应用的环境配置工作。
在完成以上设置后,我们来搭建AR Foundation开发AR应用的基础框架,这个基础框架被所有AR应用通用。在Project窗口Scenes文件夹中,我们重命名场景文件为“Helloworld”,同时为统一规范管理各类文件,在Project窗口Assets目录下新建Prefabs、Scripts两个文件夹。然后在Hierarchy窗口中删除Main Camera(AR Foundation AR Session Origin带有一个AR摄像机),而Directional Light可根据需要决定是否删除,如图1-42所示。
▲图1-42 搭建AR应用的基础框架
在Hierarchy窗口中的空白处右击,在弹出的菜单中依次选择XR➤AR Session和XR➤AR Session Origin,新建这两个AR基础组件,如图1-43所示。
▲图1-43 新建AR Session与AR Session Origin两个AR基础组件
在Hierarchy窗口中的空白处右击,在弹出的菜单中依次选择XR➤AR Default Plane,将Hierarchy窗口中生成的AR Default Plane拖动到Project窗口中的Prefabs文件夹下,制作平面预制体,如图1-44所示。完成之后删除Hierarchy窗口中的AR Default Plane对象。
▲图1-44 制作平面预制体
在Hierarchy窗口选中AR Session Origin对象,然后在Inspector窗口中单击Add Component按钮,并在弹出的搜索框中输入“arp”,然后双击搜索出来的AR Plane Manager添加该组件,如图1-45所示。
将Project窗口中Prefabs文件夹下的AR Default Plane拖到AR Plane Manager组件下的Plane Prefab属性框,设置AR Plane Manager组件属性,如图1-46所示。
至此,AR应用的基础框架已经搭建好了,这是一个AR Foundation开发iOS AR应用的基础框架,流程通用。对比Android环境搭建可以发现,在基础框架搭建上,Android开发与iOS开发几乎完全一致,后文我们也会看到,编写的代码也是完全一致的,这也是AR Foundation出现的意义,即一次开发、多平台部署,除了环境配置有所不同,其他对象设置与代码编写均完全一致,省去了开发人员开发不同平台AR应用时遇到的麻烦。
▲图1-45 添加AR Plane Manager组件
▲图1-46 设置AR Plane Manager组件属性
在Project窗口Scripts文件夹下,空白处右击,在弹出的菜单中依次选择Create➤C# Script,新建脚本文件并命名为AppController,如图1-47所示。
▲图1-47 新建AppController脚本并命名为AppController
双击AppController脚本,在Visual Studio中编辑该脚本,添加如代码清单1-5所示代码。
代码清单1-5
1. using System.Collections.Generic;
2. using UnityEngine;
3. using UnityEngine.XR.ARFoundation;
4. using UnityEngine.XR.ARSubsystems;
5.
6. [RequireComponent(typeof(ARRaycastManager))]
7. public class AppController : MonoBehaviour
8. {
9. public GameObject spawnPrefab;
10. static List<ARRaycastHit> Hits;
11. private ARRaycastManager mRaycastManager;
12. private GameObject spawnedObject = null;
13. private void Start()
14. {
15. Hits = new List<ARRaycastHit>();
16. mRaycastManager = GetComponent<ARRaycastManager>();
17. }
18.
19. void Update()
20. {
21. if (Input.touchCount == 0)
22. return;
23. var touch = Input.GetTouch(0);
24. if (mRaycastManager.Raycast(touch.position, Hits, TrackableType.PlaneWithin
Polygon | TrackableType.PlaneWithinBounds))
25. {
26. var hitPose = Hits[0].pose;
27. if (spawnedObject == null)
28. {
29. spawnedObject = Instantiate(spawnPrefab, hitPose.position, hitPose.rotation);
30. }
31. else
32. {
33. spawnedObject.transform.position = hitPose.position;
34. }
35. }
36. }
37. }
在上述代码中,首先我们使用[RequireComponent(typeof(ARRaycastManager))]属性确保添加该脚本的对象上必须有ARRaycastManager组件,因为射线检测需要用到ARRaycastManager组件。在Update()方法中,我们对手势操作进行射线检测,在检测到的平面上放置一个虚拟物体,如果该虚拟物体已存在,则将该虚拟物体移动到射线检测与平面的碰撞点。
经过以上步骤,整体AR应用框架已完全搭建起来了,为方便演示,我们在Hierarchy窗口中制作一个Sphere,为其赋上绿色材质,将其Scale缩放成(0.1,0.1,0.1),制作成Prefab并删除Hierarchy窗口中的Sphere,新建预制体如图1-48所示。
最后,在Hierarchy窗口中选中AR Session Origin,为其添加前面编写的AppController脚本(可以使用Add Component在搜索框中搜索AppController添加,也可以直接把AppController脚本拖到AR Session Origin对象上),并将上一步制作的Sphere拖到添加的AppController脚本的Spawn Prefab属性框中,挂载脚本并设置属性如图1-49所示。
至此,AR Foundation已完成Helloworld AR功能开发,但是Unity不能直接生成iOS平台的应用程序,所以还需要将Unity工程发布成XCode工程。
▲图1-48 新建Sphere预制体
▲图1-49 挂载脚本并设置属性
使iPhone通过USB或者Wi-Fi连接上计算机,直接按Command+Shift+B快捷键(或者选择File➤Build Settings)打开Build Settings对话框。在打开的对话框中确保选中当前场景,单击“Build And Run”按钮构建并生成XCode工程,如图1-50所示。建议将工程保存到另一个工程文件夹下,设置发布后的程序名,最后单击“Save”按钮开始编译生成XCode工程,如图1-51所示。生成后会自动打开XCode IDE(如果没有自动打开XCode,可以先启动XCode单击右下角的“Open another Project”,然后选择Unity发布出来的Xcode工程并打开)。
若Unity编译生成没有错误,在XCode打开生成的工程后,依次选择XCode工程图标➤工程名,然后选择真机设备,如图1-52所示,因为我们要在真机上测试应用。
▲图1-50 构建并生成XCode工程
▲图1-51 选择工程保存路径并生成XCode工程
▲图1-52 选择真机设备
在工程属性面板中,选择General选项卡,正确填写Display Name(工程名)、Bundle Identifier(包ID)、Version、Build,Bundle Identifier是我们在Unity中设置好的Bundle Identifier。如果要发布到AppStore上,Bundle Identifier必须与开发者网站上的设置一样,Version、Build也要符合按递增的要求,填写完之后还需要选择开发者证书,如图1-53所示。
▲图1-53 设置应用程序Bundle Identifier及Signing
提示
在Xcode11以后,Signing不再放在General标签下,而是放在与General同级的Signing&Capabilities标签下。
如果还没有开发者账号,可单击Team 框后的下拉菜单,选择Add an Account... 新建一个开发者账号,具体操作请参见官方说明文档,如图1-54、图1-55所示。
▲图1-54 新建开发者账号(1)
▲图1-55 新建开发者账号(2)
在XCode配置完后,单击XCode IDE左上角的编译运行图标开始编译、发布、部署、运行,如图1-56所示。
如果iPhone是第一次运行XCode应用,还需要设置开发者应用。第一步,打开手机设置➤通用,找到“设备管理”,如图1-57所示。
▲图1-56 开始编译运行程序
▲图1-57 打开设备管理
进入设备管理后,单击开发者应用,如图1-58所示。
在开发者应用管理界面单击“验证应用”,iPhone会对该开发者进行网络认证,认证通过后,应用项右方会出现“已验证”字样,至此就可以通过XCode直接将应用部署到手机并运行了,如图1-59所示。
▲图1-58 单击开发者应用
▲图1-59 验证应用程序
若整个过程没有出现问题(如果是第一次运行iOS应用很可能会出现问题,出现问题后请查阅相关资料对应解决),在Helloworld AR应用打开后,找一个相对平坦且纹理比较丰富的平面左右移动手机进行平面检测。在检测到平面后,用手指单击手机屏幕上已检测到的平面,将会在该平面上加载一个小球,如图1-60所示。至此,我们使用AR Foundation开发的iOS Helloworld AR应用已成功。
提示
iOS设备最多只能同时授权3个应用程序调试,因此,如果多于3个应用程序需要进行真机调试则应删除暂时不调试的应用。
▲图1-60 程序运行效果图