UnityAR详解(UnityARkit)

🤔


开始前准备

开发和测试环境:

  • Apple系列电脑MacOS10.13以上
  • Xcode9.3
  • 支持ARKit并具有ios11.3以上的ios设备
  • unity2017.1以上

首先我们需要在Asset store中下载Unity ARKit Plugin


Unity ARKit Plugin介绍

  1. 什么是Unity ARKit Plugin
    Unity ARKit Plugin中可以让我们在Unity项目中轻松使用几乎所有的ARKit SDK功能。这个插件向Unity开发者提供了ARKit SDK中的多个主要功能,如世界追踪,渲染相机的视频捕捉,平面检测及更新,特征点云提取,光线评估和hit 测试等等。

ARkit结构图

  1. ARKit Plugin中的示例场景
  • 在ARKit Plugin中,有如下示例场景,大家可以自行测试

  • Unity-ARKit官方提供的demon展示功能和特性解析,根据官方介绍、演示的Demon和研究实践,Unity-ARKit主要涉及到的技术有:
    1).世界跟踪
    初始化时ARKit会生成一个三维的世界坐标系(相当于unity的坐标系),定义原点(0,0,0)即为初始的ARKit摄像机对应的位置点。其他虚拟的物体空间坐标点都可以参考此为世界坐标原点进行规划。

2).实时视频渲染
ARKit默认打开设备的摄像头,可以在展示现实场景的同时渲染展示虚拟物体,如图展示的现实场景与虚拟场景结合效果。并且摄像头会把当前实时画面数据传输到ARKit SDK中进行处理,SDK处理功能包括识别返回较小特征点(feature points)数据、识别返回平面数据、识别返回环境光数据,并且这些数据是实时更新获取的,根据这些数据和功能我们就可以与unity游戏相结合,实现AR产品和创意。

3).平面估计和更新(核心特色)
摄像头会把当前实时画面数据传输到ARKit SDK中进行处理后,相关API可以获取生成的平面数据,如:平面在空间坐标矩阵的位置,大小,方向等。并且摄像机在不断扫描平面或物体时,平面的数据信息会不断更新和融合,ARKit可以扫描和生成多个平面,多个平面在扫描当中如确定是同一平面,它会把多个平面合并成一整块平面,如图

4).命中测试的API
在摄像机开启时,ARKit可以识别特征点(现实物体的平面点),图中的黄色点。示例中点击手机摄像机中的现实物体可以放置虚拟物体在平面上(不至于悬空),如图

5).环境光估计
ARKit可以收集摄像机现实的光源信息并返回,所以调用相关API表现为虚拟物体随着现实化境的光照强度改变,它会变亮或产生阴影。

  1. ARKit Plugin中的重要文件
    在ARKit Plugin中有几个非常重要的文件,具体参考,这里举例介绍:
  • ARSessionNative.mm

    /Plugins/iOS/UnityARKit/NativeInterface/ARSessionNative.mm
    该文件是用于跟ARKit SDK实际交互的Objective-C代码

  • UnityARSessionNativeInterface.cs

    /Plugins/iOS/UnityARKit/NativeInterface/UnityARSessionNativeInterface.cs
    该文件提供了到ARKit的脚本API,同时也提供了对于原生代码的解释说明。
    其中包含以下API:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    public void RunWithConfigAndOptions(ARKitWorldTackingSessionConfiguration config, UnityARSessionRunOption runOptions)
    public void RunWithConfig(ARKitWorldTackingSessionConfiguration config)
    public void Pause()
    public List<ARHitTestResult> HitTest(ARPoint point, ARHitTestResultType types)
    public ARTextureHandles GetARVideoTextureHandles()
    public float GetARAmbientIntensity()
    public int GetARTrackingQuality()

    此外其中也包含了一些可以提供代理的事件:

    public delegate void ARFrameUpdate(UnityARCamera camera)
    public delegate void ARAnchorAdded(ARPlaneAnchor anchorData)
    public delegate void ARAnchorUpdated(ARPlaneAnchor anchorData)
    public delegate void ARAnchorRemoved(ARPlaneAnchor anchorData)
    public delegate void ARSessionFailed(string error)

    以及我们可以订阅的事件列表:

    public static event ARFrameUpdate ARFrameUpdatedEvent;
    public static event ARAnchorAdded ARAnchorAddedEvent;
    public static event ARAnchorUpdated ARAnchorUpdatedEvent;
    public static event ARAnchorRemoved ARAnchorRemovedEvent;
    public static event ARAnchorAdded ARUserAnchorAddedEvent;
    public static event ARAnchorUpdated ARUserAnchorUpdatedEvent;
    public static event ARAnchorRemoved ARUserAnchorRemovedEvent;
    public static event ARSessionCallback ARSessionInterruptedEvent;
    public static event ARSessionCallback ARSessioninterruptionEndedEvent;
    public static event ARSessionTrackingChanged ARSessionTrackingChangedEvent;
  • 在NativeInterface文件夹中,以AR开头的cs文件是和ARKit中所提供的数据结构相对应的API

  • UnityARAnchorManager.cs

    /Plugins/iOS/UnityARKit/Helpers/UnityARAnchorManager.cs
    该文件用于管理ARKit中的anchor更新信息,并据此创建相对应的Unity游戏对象

  • UnityARCameraManager.cs

    /Plugins/iOS/UnityARKit/Helpers/ UnityARCameraManager.cs
    该组件应该被放置在场景的游戏对象上,代表想要通过ARKit来控制的摄像机。它会基于ARKit的更新来控制摄像机的位置和旋转角度,并提供投射矩阵。
    该组件中还包含了用于初始化ARKit 进程的代码。

  • UnityARVideo.cs

    /Plugins/iOS/UnityARKit/Helpers/UnityARVideo.cs
    该组件应该放置在摄像机上,以抓取用于渲染视频的纹理,并将其设置在用于backbuffer的材质上,同时还将设置用于完成blit的Command Buffers

  • UnityARUserAnchorComponent.cs

    /Plugins/iOS/UnityARKit/Helpers/UnityARUserAnchorComponent.cs
    该组件将基于其所依附的游戏对象的生命周期,从ARKit中添加和删除Anchor。

  • UnityARCameraNearFar

    /Plugins/iOS/UnityARKit/Helpers/UnityARCameraNearFar
    获取相机的距离,更新far和near,剪裁平面,物体和相机距离小于最近和大于最远都看不到

  • 在ARkit2.0的最新更新中,还加入了许多实用的新功能:

1.在最新的arkit2.0中,加入了全新的USDZ文件格式,该文件格式由苹果与Adobe共同推出,同时ARkit也将于Valve合作,从而增加Mac对 SteamVR的支持。

2.加入了ARWorldMap技术,ARWorldMap是ARKit 2一个非常有用的新功能,可支持AR体验的持续性和多人AR体验。随着你移动并检测到更多的特征点,每次会话都将建立一个ARWorldMap。你可以从C#的会话中获取当前的ARWorldMap,并将其保存到Application.persistence DataPath上的某个位置。你同时可以从保存的地方加载保存的ARWorldMap。这允许虚拟对象维持在相同的坐标空间中。ARWorldMap可以序列化为一个字节数组,并通过WiFi,蓝牙或其他共享方式发送至另一台设备。它同时可以反序列化,并用于将其他设备重新定位到与第一个设备相同的世界映射,这样你就可以拥有一种共享的多人游戏体验。无论通过加载,还是说从另一个设备接收,一旦拥有了ARWorldMap,设备就可以利用这个ARWorldMap共享坐标系,方法是将其设置为配置中的参数,并使用这个配置来重置ARSession。这将重设会话,而随着你的移动,它将尝试匹配ARWorldMap中的特征点与其在环境中检测到的特征点。当彼此匹配时,它将重新定位你的设备坐标,从而匹配保存在ARWorldMap中的坐标。

3.ARReferenceObjectandARObjectAnchor,与ARKit1.5中用于图像识别的ARReferenceImage和ARImageAnchor类似,我们现在有了ARReferenceObject和ARObjectAnchor来进行对象识别。

4.UnityARObjectAnchor,这个示例假设你已经拥有了.arobject文件来描述希望识别的对象。你可以通过下面介绍的UnityObjectScanner示例,或者是苹果的ARKit Object Scanner应用程序来创建.arobject文件,这两者都可以生成相同格式的文件。与ARReferenceImage非常相似,我们将设置一个ARReferenceObjectsSetAsset,它包含对ARReferenceObjectAssets的引用。接下来,我们将为ARSession的配置添加对ARReferenceObjectsSetAsset的引用,从而在会话中尝试检测集合中的ARReferenceObjects。所有这一切都可以通过Unity Editor来完成。每当识别出一个对象时,系统将创建一个ARObjectAnchor,而就像是其他锚定一样,你可以订阅一个告诉你什么时候添加,更新或删除了锚定的活动。当活动触发时,你可以自行决定要执行的操作(比如在这个位置创建一个预制件)。

5.UnityObjectScanner,Examples/ARKit2.0/UnityARObjectScanner/UnityARObjectScanner.unity是一个更为完整的示例,它既可使用可选边界框来创建对象,也使用进行对象检测。你可以保存使用该示例扫描的.arobjects,然后使用iTunesFileSharing将它们传输至Mac。当文件出现在Mac时,你就可以重命名它们,然后再放入Unity项目之中。这个示例有不同的模式:扫描模式和检测模式。对于扫描模式,我们菜肴能够ARKitObjectScanningSessionConfiguration,这将能对场景进行更为详细的探索,但会使用更多的CPU和功率。利用这个配置,对于你希望扫描的对象,你可以轻触其附近的平面以生成一个红色的边界框。你可以操作方框来覆盖目标对象。接下来,扫描方框的周围,尽可能多地获取对象上的特征点。然后通过轻触按钮来创建一个ARReferenceObject。创建的对象将保存到一个列表中。按下Detect按钮将进入检测模式,而这个模式的工作原理与上面的对象锚定示例类似,但采用一种将arreferenceobject动态添加到被检测对象列表中的函数。按下Save按钮,将至今扫描到的所有对象都保存至设备上的文件夹。这会把它们保存为.arobjects,并可以使用iTunesFileSharing将它们传输到Mac上。当文件出现在Mac后,你就可以重命名它们,然后再放到Unity项目中。

6.AREnvironmentProbeAnchor,AREnvironmentProbeAnchor是一种新的锚定,它可以自动生成,而你也可以指定在哪里创建它。这个锚定将根据ARKit视频帧和世界追踪数据来创建,并更新区域的反射环境映射。它同时采用了机器学习算法,对尚未看到的场景部分近似算出环境纹理。
会话配置中有一个新的参数来控制这个功能,而它将有以下三个值中的一个:UnityAREnvironmentTexturingNone、UnityAREnvironmentTexturingManual或UnityAREnvironmentTexturingAutomatic。对于UnityAREnvironmentTexturingManual模式,你必须自行创建一个AREnvironmentProbeAnchor,但ARKit将更新从环境中捕获的纹理。如果你使用的是UnityAREnvironmentTexturingAutomatic模式,ARKit将根据它从会话中输入的数据和你在空间中的运动,以空间间隔地生成AREnvironmentProbeAnchor。这两个示例都生成一个包含Unity ReflectionProbe组件的预制件,并使用来自AREnvironmentProbeAnchor的环境纹理更新它。这个ReflectionProbe现在加入至标准的Unity渲染管道,并将增强使用它的任何GameObject。

7.图像追踪,参考图像与ARKit 1.5中的工作原理相同,但现在ARKit不仅只是识别图像,它同时允许你追踪它们:当你移动参考图像时,与它们相关的ARImageAnchor将与图像一起移动,这样你就可以移动与这些移动图像锚定的内容。会话配置中有一个额外的参数,它可以通过说明你希望在会话期间同时追踪多少图像来实现这一点。现有的示例已经进行了更新以支持使用这个新功能。

8.面部追踪优化,ARKit 2同时优化了iPhoneX的人脸追踪功能。首先,有一个名为TongueOut的额外混合变形系数。取决于ARKit2人脸追踪所能感知的舌头伸出程度,这将返回0.0到1.0之间的值。苹果在WWDC上展示了他们的Animojis,而这看起来很受观众的欢迎。另一项改进是,它现在可以追踪眼睛注视点。你会接收到一个描述每只眼睛指向的变换,以及注视对象的位置。

宇 wechat
扫描二维码,订阅微信公众号