8 进阶功能

8.1 配置EyeBuffer大小

SDK支持响应Unreal的“vr.pixeldensity”命令,开发者可以通过该命令来配置EyeBuffer(RenderTexture)的大小。

使用方法:

方式一:打开文件 Project/Config/DefaultEngine.ini,然后在“[/Script/Engine.RendererSettings]”标签下添加字符串“vr.pixeldensity=1”,如果该命令等于一或者没有该命令,则EyeBuffer大小为Pico的默认大小,如果该值不等于一,则会在Pico默认的EyeBuffer大小的基础上进行缩放。如下图所示:

_images/8.1.png

图8.1 设置EyeBuffer大小

方式二:可以通过蓝图调用控制台命令实现该效果。使用节点“Execute Console Command”节点,调用“vr.pixeldensity 1”命令(命令中字符串和数字之间有一个空格)。同样数字部分为EyeBuffer的倍数。但是要保证该命令的执行必须足够早,建议放在关卡蓝图的EventBeginPlay后。

_images/8.2.png

图8.2 设置EyeBuffer大小

For example, if you wanted to reduce the number of pixels to render of your VR project by about 20% you would set vr.PixelDensity=sqrt(1-0.2). If you wanted to increase the number of pixels to render of your VR project by about 20%, you would input vr.PixelDensity=sqrt(1+0.2).

Tips: 建议开发者不做修改,仅在特殊需求场合使用自定义RenderTexture大小。对于该选项开发者必须了解以下两点:

  1. RT设置过小,会带来性能的提升,减少延迟,但同时也导致了分辨率降低;
  2. RT设置过大,会带来性能的降低,增加延迟,因此不建议RT设置超过硬件建议纹理尺寸;

推荐范围:0.5~2。

8.2 眼球追踪

Pico Neo3 Pro 设备支持眼球追踪, 眼球追踪可以追踪眼球注视位置,配合注视点渲染可以优化渲染性能。眼球追踪功能的开关在 项目设置 > 插件 > PicoXRSetting,勾选“EnableEyeTracking”即可打开眼球追踪功能。如图,在PicoXRSettings里设置

_images/8.3.png

图8.3 眼球追踪

可以通过蓝图节点获取眼球的位置与方向,详细说明见7.4 Eye Tracking(眼球追踪)相关函数库。

8.3 注视点渲染

注视点渲染(Foveation Rendering)可以优化VR场景的渲染,该技术通过为视野中心提供全分辨率(无损),降低周边视野(人眼焦点区域之外)分辨率的方式来达到优化渲染的目的。

这里提供了两种使用注视点渲染的方式:

方法一:在打包之前,可以在“ 项目设置 > 插件 > PicoXRSetting”中勾选“Enable FoveationRendering”开启注视点渲染功能,并在“Foveation Level”下拉框指定Level即可(SDK默认提供了4个Level:Low/Med/High/Top High)。

_images/8.4.png

图8.4 FoveationRendering设置

方法二:打包之后,可以通过蓝图节点动态的修改Foveation Rendering的level(注意:打包前,必须勾选“Enable FoveationRendering”开启注视点渲染功能),详细说明见7.5 Foveation Rendering(注视点渲染)相关函数库。

8.4 应用版权保护

为了配合开发者平台及应用商店对于开发者应用的版权保护,SDK需要在应用开发阶段及正式发布后进行许可校验,为开发者提供应用版权保护机制。

8.4.1 开发调试阶段模拟权限验证

Device SN通过Edit—>Plugins—> OnlinePicoSettings—>Platform传入,用于开发机模拟权限验证。

_images/8.5.png

图8.5 版权校验模拟

8.4.2 AppID与Public Key权限验证

AppID与Public Key权限验证通过调用“Pico Entitlement Verify App Delegate”蓝图接口实现,绑定回调事件后,通过回调可以获取版权验证结果,详细接口说明见 7.6 应用版权保护函数库章节。

注意: 模拟验证中填入SN号的开发机,在内容上线到Pico应用商店后,默认通过用户权限验证验证,不会再进行正式的权限验证。如果需要开发机在应用上线后也进行正式的用户权限验证,请在编译正式版本时,关闭“Entitlement Check Simulation”。 权限验证回调结果蓝图:

8.5 MultiView

如果想要开启MultiView,需要进入Unreal Editor > Settings > Project Settings > Engine > Rendering > VR,然后选择Mobile Multi-View。

注意 : OpenGL ES2 不支持MultiView。

_images/8.5.1.png

图8.6 开启MultiView

8.6 StereoLayer

StereoLayer是UE4引擎提供的Layer组件,在VR中,可将单独的纹理发送至VR头戴,并将其重新投射到和不同于项目其他内容的单独渲染通道中。

_images/8.6.1.png

图8.7 场景中的overlay

_images/8.6.2.png

图8.8 Stereo Layer相关属性

目前仅支持该组件的以下属性:Texture、Stereo Layer Type、Stereo Layer Shape、Priority、Left Texture、Quad Size。其他属性会在后续版本中逐渐实现。

如何创建一个StereoLayer:

1、 创建一个Pawn,可以拖入到level中。

2、 选择Pawn或者打开Pawn蓝图,添加Component中的Stereo Layer。

3、 Stereo Layer的属性中可以选择Stereo Layer Type有FaceLocked、WorldLocked、TrackerLocked,暂时FaceLocked与TrackerLocked效果相同。

4、 设置Stereo Layer Shape为Quad Layer。

5、 设置Property来确定多个layer的层级关系。

注意:

建议不要把Stereo Layer添加到相机组件下。

建议使用正确的坐标位置关系放置模型和叠加层,否则会存在景深冲突,引起视觉不适。

8.7 Splash Screen

SDK提供了一个在切换场景时显示一张贴图的方式,成为SplashScreen。开启SplashScreen共有两种方式,分别是通过项目设置和使用蓝图。

方式一:使用项目设置来开启SplashScreen:

打开项目设置,依次进入:Plugins->PicoXR Settings->SplashScreen(配置界面如下):

_images/8.7.1.png

图8.9 SplashScreen相关属性

属性名 属性作用
Auto Show Splash Screen 是否自动显示(只有勾选了切场景是才会显示)
Texture Path 贴图
Transform in Maters 贴图显示的Transform属性,单位为米
Quad Size in Maters 显示贴图四边形的大小

方式二:使用蓝图来开启SplashScreen,详细说明见 7.7 SplashScreen相关函数库。

8.8 Boundary(安全区)

Pico Neo设备,默认情况下是6Dof模式,为保护用户安全,我们开发了Boundary功能,该功能的作用就是在用户划定的范围内是安全区,视为安全区。当用户离开安全区时,头戴内会显示显示世界中的内容,以防用户撞伤或出现其他意外。

SDK中开放了一些关于Boundary功能的相关接口,详细接口说明见 7.8 Boundary(安全区)相关函数库。

8.9 Platform系统

SDK继承了Unreal的OnlineSubsystem模块,实现了其中的部分功能,并开放给开发者。该模块的功能,暂时只支持成就系统。

需要使用Pico提供的OnlineSubSystem模块,需要进行以下步骤

  • Step1:启用Online SubSystem Pico 插件
_images/8.9.1.png

图8.10 开启Online Subsystem Pico 插件

  • Step2:关闭Plugin->Online Platform 下除Online Subsystem、Online Subsystem Utils插件外的其他插件
  • Step3:在[ProjectDirectory]/Config/Android/ 路径下新建AndroidEngine.ini文件,并添加以下内容:
[OnlineSubsystem]
DefaultPlatformService=Pico
  • Step4:在[ProjectDirectory]/Source/[ProjectName]/ProjectName.Build.cs文件中添加以下内容来加载必要引擎模块
PublicDependencyModuleNames.AddRange(new string[]{"OnlineSubsystem", "OnlineSubsystemPico" });
  • Step5:在项目设置->插件->OnlinePicoSettings->Payment下,填写所有信息(Is Foreign、Merchant ID、App ID、App Key、Pay Key)。

8.9.1 成就系统

准备工作

开发者可以从管理中心进入到创建应用阶段,点击创建应用,然后进入相应平台完善应用的相关信息。

开发者在接入成就系统时,需要在开发者平台创建应用并获取相应字符串。

申请流程如下:

    1. 申请成为开发者
    1. 创建应用
  • 4.创建成就信息

点击 查看 进入应用详情页。如果您还没有任何应用,请先 创建应用

开发者在接入成就系统时,需要在开发者平台创建应用并获取 应用参数 ,对应流程如下:

平台服务 菜单找到并点击 成就

_images/8.9.1.1.png

图8.9.1 开发者平台

在成就页面可以看到您已创建的所有成就。如果您还没有任何成就,请点击 创建

按要求填写成就的信息。填入的API 名称(即API Name)必须代码中的保持一致。

成就类型说明:

  • 简单类型:通过单个事件或目标完成来解锁,无成就进展
  • 计数器类型:到达指定目标个数时解锁(e.g. 完成5个解锁,target=5)
  • 位域类型:到达指定范围的指定目标个数时解锁(e.g. 完成指定7个目标中的3个解锁,Target=3,Bitfield Length=7)

注意: 由于int32的长度限制,比特位类型的成就比特位长度不能超过10,计数类型的成就目标值不能超过2147483648。

接口调用

使用注意事项:

  • 请先使用Pico账号登陆设备,再使用成就接口和功能。
  • 为了避免由于设备账号切换、退登导致的成就数据出现误差,请在应用Resume()中重新调用一次初始化,以确保应用获取正确的用户登陆信息。
  • 开发调试阶段可以通过以下方式调试和测试:
    • Logcat;
    • 通过开发者平台-应用-成就信息页查看数据。

1、 初始化接口:

FOnlineSubsystemPico::InitWithAndroidPlatform(FPicoInitOnCompleteDelegate&& Delegate)

该接口为成就系统的初始化接口,调用该接口,可对成就系统进行初始化,接口传入一个Delegate,返回初始化是否成功。调用该接口需要用户在PUI中登录自己的账号,并需要开发者在Project -> PicoXR Settings-> Platform中填入其中的对应参数(详见 准备工作 )。为防止应用在后台是用户切换账户,该接口要求开发者在每次Resume都需要调用一次。调用示例如下:

void UAchievementWidgetClass::InitPicoOnlineSubSystem()
{
    OnlineSubsystemPico*PicoSubsystem=static_cast<FOnlineSubsystemPico*>(IOnlineSubsystem::Get());
    if (PicoSubsystem)
    {
        PicoSubsystem->InitWithAndroidPlatform(FPicoInitOnCompleteDelegate::CreateUObject(this, &UAchievementWidgetClass::OnInitPicoSubSystemComplete));
    }
}
void UAchievementWidgetClass::OnInitPicoSubSystemComplete(bool Result)
{
}

注意: 以下接口,部分接口不要求先调用初始化接口,部分接口要求初始化,对于需要初始化的接口,仅需整体初始化一次。

2、 向服务器请求所有成就定义并缓存到本地

IOnlineAchievements::QueryAchievementDescriptions( const FUniqueNetId& PlayerId, const FOnQueryAchievementsCompleteDelegate& Delegate)

该接口将定义的所有成就的信息缓存到本地,Delegate返回请求是否成功。调用该接口,不需要事先调用初始化接口。调用实例如下:

void UAchievementWidgetClass::QueryDescriptions()
{
     auto AchievementInterface = Online::GetAchievementsInterface();
     auto UserID = new FUniqueNetIdPico(0);
     if (AchievementInterface)
     {
         AchievementInterface->QueryAchievementDescriptions(*UserID, FOnQueryAchievementsCompleteDelegate::CreateUObject(this, &UAchievementWidgetClass::OnQueryDescriptionsComplete));
     }
}
void UAchievementWidgetClass::OnQueryDescriptionsComplete(const FUniqueNetId& PlayerId, const bool bWasSuccessful)
{
}

3、 向服务器请求所有成就进度并缓存到本地

IOnlineAchievements::QueryAchievements( const FUniqueNetId& PlayerId, const FOnQueryAchievementsCompleteDelegate& Delegate)

该接口可以将所有成就的进度信息缓存到本地,Delegate返回请求是否成功。调用该接口,需要事先调用初始化接口和QueryAchievementDescriptions接口。调用示例如下:

void UAchievementWidgetClass::QueryAchievement()
{
    auto AchievementInterface = Online::GetAchievementsInterface();
    auto UserID = new FUniqueNetIdPico(0);
    if (AchievementInterface)
    {
        AchievementInterface->QueryAchievements(*UserID, FOnQueryAchievementsCompleteDelegate::CreateUObject(this, &UAchievementWidgetClass::OnQueryAchievementComplete));
    }
}

void UAchievementWidgetClass::OnQueryAchievementComplete (const FUniqueNetId& PlayerId, const bool bWasSuccessful)
{

}

4、 修改成就进度

IOnlineAchievements::WriteAchievements(const FUniqueNetId& PlayerId, FOnlineAchievementsWriteRef& WriteObject, const FOnAchievementsWrittenDelegate& Delegate)

该接口可以修改成就的完成进度。通过WriteObject传入需要修改的成就的名字与要修改的进度,Delegate返回请求是否成功。调用该接口,需要事先调用初始化接口和QueryAchievementDescriptions接口。调用示例如下:

void UAchievementWidgetClass::WriteAchievement(FString AchievementName, int32 Value)
{
    auto AchievementInterface = Online::GetAchievementsInterface();
    auto UserID = new FUniqueNetIdPico(0);
    if (AchievementInterface)
    {
        FOnlineAchievementsWritePtr WriteObject = MakeShareable(new FOnlineAchievementsWrite());
        WriteObject->SetIntStat(*AchievementName, Value);
        FOnlineAchievementsWriteRef WriteObjectRef = WriteObject.ToSharedRef();
        AchievementInterface->WriteAchievements(*UserID, WriteObjectRef, FOnAchievementsWrittenDelegate::CreateUObject(this, &UAchievementWidgetClass::OnAchievementsWritten));
    }
}

void UAchievementWidgetClass::OnAchievementsWritten(const FUniqueNetId& PlayerId, const bool bWasSuccessful)
{

}

5、 获取缓存到本地的所有成就的进度

IOnlineAchievements::GetCachedAchievements(const FUniqueNetId& PlayerId, TArray<FOnlineAchievement>& OutAchievements)

该接口可以获取缓存到本地的所有成就的进度。调用该接口,需要事先调用初始化接口与QueryAchievements接口。调用示例如下:

auto AchievementInterface = Online::GetAchievementsInterface();
auto UserID = new FUniqueNetIdPico(0);
TArray<FOnlineAchievement>Achievements;
if (AchievementInterface)
{
    auto State = AchievementInterface->GetCachedAchievements(*UserID, Achievements);
}

6、 通过成就名称获取缓存到本地的成就进度

IOnlineAchievements::GetCachedAchievement(const FUniqueNetId& PlayerId, const FString& AchievementId, FOnlineAchievement& OutAchievement)

该接口可以通过名字获取缓存到本地的成就的进度。调用该接口,需要事先调用初始化接口与QueryAchievements接口。调用示例如下:

auto AchievementInterface = Online::GetAchievementsInterface();
auto UserID = new FUniqueNetIdPico(0);
FOnlineAchievement Achievement;
if (AchievementInterface)
{
    auto State = AchievementInterface->GetCachedAchievement(*UserID, AchievementName, Achievement);
}

7、 通过成就名称获取缓存到本地的成就定义

IOnlineAchievements::GetCachedAchievement( const FUniqueNetId& PlayerId, const FString& AchievementId, FOnlineAchievement& OutAchievement)

该接口可以通过名字获取缓存到本地的成就的进度。调用该接口,需要事先调用初始化接口与QueryAchievements接口。调用示例如下:

auto AchievementInterface = Online::GetAchievementsInterface();
auto UserID = new FUniqueNetIdPico(0);
FOnlineAchievement Achievement;
if (AchievementInterface)
{
    auto State = AchievementInterface->GetCachedAchievement(*UserID, AchievementName, Achievement);
}

8.10 配置屏幕刷新率

SDK提供配置屏幕刷新率的功能,通过设置Display Refresh Rates相关选项来进行配置,配置方式如下:

  1. Default:系统默认
  2. RefreshRate72:刷新率上限72hz
  3. RefreshRate90:刷新率上限90hz
_images/8.10.1.png

图8.15 屏幕刷新率设置

8.11 大空间(Large Space)

使用场景: 将一台头戴创建的安全区,导出给其它头戴使用。支持最大面积10m*10m。

适用设备: Pico Neo 3 Pro/Pico Neo 3 Pro Eye

使用流程:

  1. 用户使用一台头戴创建好地图后,把地图导出、拷贝至其他设备中,可以调用PXR Save Large Space Maps接口保存大空间地图,PXR Export Maps接口导出大空间地图,PXR Import Maps接口导入大空间地图,接口详细说明见7.9 Large Space(大空间)相关函数库说明。其他设备可以共用这一套地图,处于统一坐标系中,且头戴不需要统一真实世界的某一个位置唤醒(头戴在真实世界中任一位置唤醒后,可以识别到地图,且虚拟场景中的位置与真实世界的位置一致,不会以头戴位置为坐标原点)。如下图:
_images/8.11.1.png

图 8.16 整体使用流程

  1. 进入Edit->Project Settings…,展开Plugins子项下的OnlinePico Settings,先后勾选:“Use Pico Advance Interface”、“Enable Large Space”两个选项,开启应用支持大空间,如图 8.17所示。也可以在应用中调用**PXR Set Large Space Enable**蓝图接口,实时开启应用支持大空间,接口详细说明见7.9 Large Space(大空间)相关函数库说明 。
_images/8.11.2.png

图 8.17 应用支持大空间设置

  1. 应用中调用 PXR Switch Large Space Scene 蓝图接口,实时开启设备的大空间功能,接口详细说明见7.9 Large Space(大空间)相关函数库说明 。