8 进阶功能¶
8.1 配置EyeBuffer大小¶
SDK支持响应Unreal的“vr.pixeldensity”命令,开发者可以通过该命令来配置EyeBuffer(RenderTexture)的大小。
使用方法:
方式一:打开文件 Project/Config/DefaultEngine.ini,然后在“[/Script/Engine.RendererSettings]”标签下添加字符串“vr.pixeldensity=1”,如果该命令等于一或者没有该命令,则EyeBuffer大小为Pico的默认大小,如果该值不等于一,则会在Pico默认的EyeBuffer大小的基础上进行缩放。如下图所示:

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

图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大小。对于该选项开发者必须了解以下两点:
- RT设置过小,会带来性能的提升,减少延迟,但同时也导致了分辨率降低;
- RT设置过大,会带来性能的降低,增加延迟,因此不建议RT设置超过硬件建议纹理尺寸;
推荐范围:0.5~2。
8.2 眼球追踪¶
Pico Neo3 Pro 设备支持眼球追踪, 眼球追踪可以追踪眼球注视位置,配合注视点渲染可以优化渲染性能。眼球追踪功能的开关在 项目设置 > 插件 > PicoXRSetting,勾选“EnableEyeTracking”即可打开眼球追踪功能。如图,在PicoXRSettings里设置

图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)。

图8.4 FoveationRendering设置
方法二:打包之后,可以通过蓝图节点动态的修改Foveation Rendering的level(注意:打包前,必须勾选“Enable FoveationRendering”开启注视点渲染功能),详细说明见7.5 Foveation Rendering(注视点渲染)相关函数库。
8.4 应用版权保护¶
为了配合开发者平台及应用商店对于开发者应用的版权保护,SDK需要在应用开发阶段及正式发布后进行许可校验,为开发者提供应用版权保护机制。
8.4.1 开发调试阶段模拟权限验证¶
Device SN通过Edit—>Plugins—> OnlinePicoSettings—>Platform传入,用于开发机模拟权限验证。

图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。

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

图8.7 场景中的overlay

图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(配置界面如下):

图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 插件

图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 成就系统¶
准备工作
开发者可以从管理中心进入到创建应用阶段,点击创建应用,然后进入相应平台完善应用的相关信息。
开发者在接入成就系统时,需要在开发者平台创建应用并获取相应字符串。
申请流程如下:
- 在 Pico 开发者平台 页点击 成为开发者 按钮。
- 申请成为开发者
- 创建应用
- 4.创建成就信息
点击 查看 进入应用详情页。如果您还没有任何应用,请先 创建应用。
开发者在接入成就系统时,需要在开发者平台创建应用并获取 应用参数 ,对应流程如下:
在 平台服务 菜单找到并点击 成就 。

图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相关选项来进行配置,配置方式如下:
- Default:系统默认
- RefreshRate72:刷新率上限72hz
- RefreshRate90:刷新率上限90hz

图8.15 屏幕刷新率设置
8.11 大空间(Large Space)¶
使用场景: 将一台头戴创建的安全区,导出给其它头戴使用。支持最大面积10m*10m。
适用设备: Pico Neo 3 Pro/Pico Neo 3 Pro Eye
使用流程:
- 用户使用一台头戴创建好地图后,把地图导出、拷贝至其他设备中,可以调用PXR Save Large Space Maps接口保存大空间地图,PXR Export Maps接口导出大空间地图,PXR Import Maps接口导入大空间地图,接口详细说明见7.9 Large Space(大空间)相关函数库说明。其他设备可以共用这一套地图,处于统一坐标系中,且头戴不需要统一真实世界的某一个位置唤醒(头戴在真实世界中任一位置唤醒后,可以识别到地图,且虚拟场景中的位置与真实世界的位置一致,不会以头戴位置为坐标原点)。如下图:

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

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