如何

使用WebVR体验助手


如何使用WebVR体验助手

介绍

WebVR Experience Helper提供了一种将WebVR支持添加到巴比伦场景的快速方法。

功能包括:

  1. WebVR摄像机和非WebVR摄像机初始化
  2. 输入WebVR按钮
  3. 世界上的隐形传送和旋转
  4. 通过HMD和控制器选择网格进行注视跟踪

设定

可以直接从场景创建VRExperienceHelper。

var scene = new BABYLON.Scene(engine);
var vrHelper = scene.createDefaultVRExperience();

这将在场景中初始化WebVR摄像机和非WebVR摄像机。它还将在屏幕的右下方创建一个enterVR按钮,单击该按钮将开始渲染到HMD。

选项

  • reateDeviceOrientationCamera(默认:true):如果应该创建非WebVR摄像机。要使用现有相机,请创建它,然后在构造函数中将其设置为false来初始化帮助器。
  • createFallbackVRDeviceOrientationFreeCamera(默认值:true):当未连接HMD时,此标志指定VR摄像机是否应回退到VRDeviceOrientationFreeCamera,它将在屏幕上呈现每只眼睛。可以将其设置为false以仅在连接了HMD的情况下才允许进入VR。

传送和旋转

要在场景中启用传送,请创建用户应该能够传送到的网格,然后使用该网格的名称启用传送。

var ground = BABYLON.Mesh.CreateGround("ground", 6, 6, 2, scene);
vrHelper.enableTeleportation({floorMeshName: "ground"});

要进行传送,请按住操纵杆以显示用户将被传送到的位置,然后释放以进行传送。要旋转,请向左或向右移动操纵杆。

连接了WebVR控制器后,隐形传送将基于控制器所指向的位置。

当未连接WebVR控制器时,用户将传送到用户正在寻找的位置,并且可以使用Xbox控制器触发传送。

传送事件

传送可以订阅两个观察值:

onBeforeCameraTeleport:当请求传送时接收到的Vector3位置作为参数,则引发Observable。

vrHelper.onBeforeCameraTeleport.add((targetPosition) => {
     //Raised before camera is teleported
});

onAfterCameraTeleport:隐形传送动画结束时引发Observable,将目标Vector3位置作为参数接收:

vrHelper.onAfterCameraTeleport.add((targetPosition) => {
     //Raised after teleportation animation finishes
});

要在场景中启用传送,请创建用户应该能够传送到的网格,然后使用该网格的名称启用传送。

var ground = BABYLON.Mesh.CreateGround("ground", 6, 6, 2, scene);
vrHelper.enableTeleportation({floorMeshName: "ground"});

启用/禁用传送

可以根据需要使用属性teleportationEnabled启用或禁用传送。


// Enable teleportation
vrHelper.teleportationEnabled = true;

//Disable teleportation (teleportation mesh will not be displayed)
vrHelper.teleportationEnabled = false;

要自定义隐形传送目标网格,可以将以下属性设置为您要使用的网格:

vrHelper.teleportationTarget = BABYLON.Mesh.CreateSphere("sphere1", 4, 0.1, scene);

存取相机

可以从助手访问VR和非VR摄像机,以处理任何特定于应用程序的逻辑。

// Initial camera before the user enters VR
vrHelper.deviceOrientationCamera;
// WebVR camera used after the user enters VR
vrHelper.webVRCamera;
// One of the 2 cameras above depending on which one is in use
vrHelper.currentVRCamera;

访问控制器

可以从助手中访问控制器以处理任何特定于应用程序的逻辑。

vrHelper.onControllerMeshLoaded.add((webVRController)=>{
    var controllerMesh = webVRController.mesh;
    webVRController.onTriggerStateChangedObservable.add(()=>{
        // Trigger pressed event
    });
});

请注意,Microsoft控制器正在使用GLB文件格式,并且需要 GLTF Loader.

访问VR设备的位置和旋转

可以通过webVR摄像机的devicePosition和deviceRotationQuaternion访问巴比伦空间中的位置和旋转

// Left and right hand position/rotation
if(vrHelper.webVRCamera.leftController){
    leftHand.position = vrHelper.webVRCamera.leftController.devicePosition.clone()
    leftHand.rotationQuaternion = vrHelper.webVRCamera.leftController.deviceRotationQuaternion.clone()
}
if(vrHelper.webVRCamera.rightController){
    rightHand.position = vrHelper.webVRCamera.rightController.devicePosition.clone()
    rightHand.rotationQuaternion = vrHelper.webVRCamera.rightController.deviceRotationQuaternion.clone()
}

// Head position/rotation
head.position = vrHelper.webVRCamera.devicePosition.clone()
head.rotationQuaternion = vrHelper.webVRCamera.deviceRotationQuaternion.clone()

参见示例 -


注视与互动

凝视和交互可以通过enableInteractions方法启用。参见示例 -


vrHelper.enableInteractions();

这将开始从用户的相机或控制器投射光线。在此光线与场景中的网格相交的地方,将放置一个小的凝视网格以向用户指示当前选择的内容。

要过滤凝视可以与哪些网格相交,可以使用raySelectionPredicate:

vrHelper.raySelectionPredicate = (mesh) => {
    if (mesh.name.indexOf("Flags") !== -1) {
        return true;
    }
    return false;
};

这将导致用户的视线穿过任何网格,从而导致raySelectionPredicate返回false。

当用户以目光在网格之间移动时,将发生onNewMeshSelected事件。注意:这仅在启用交互后才有效。

vrHelper.onNewMeshSelected.add((mesh)=>{
    // Mesh has been selected
});

这将返回所选的最接近的单个网格。

在onNewMeshSelected之前,如果基于meshSelectionPredicate成功评估选择了网格,则会引发名为onNewMeshPicked的事件。此可观察的对象将PickingInfo对象通知给订户。

vrHelper.onNewMeshPicked.add((pickingInfo) => {
    //Callback receiving ray cast picking info
});

当用户取消选择带有其视线或控制器的网格时,将发生onSelectedMeshUnselected事件。

vrHelper.onSelectedMeshUnselected.add((mesh) => {
    // Mesh has been unselected
});

您可以使用meshSelectionPredicate添加自己的过滤逻辑。注意:这将在raySelectionPredicate之后应用。

vrHelper.meshSelectionPredicate = (mesh) => {
    if (mesh.name.indexOf("Flags01") !== -1) {
        return true;
    }
    return false;
};

raySelectionPredicate,meshSelectionPredicate,onNewMeshPicked,onNewMeshSelected的逻辑顺序如下:

  1. 光线从控制器投射
  2. 当光线撞击物体时,将调用raySelectionPredicate;如果为true,则光线将在那里碰撞并停止,否则光线将通过物体
  3. 果碰撞也是地面网格物体,则将传送目标位置更新为射线碰撞的位置
  4. 如果未在最后一帧上与碰撞对象发生碰撞,则检查meshSelectionPredicate,如果它返回true,则触发onNewMeshPicked事件,然后触发onNewMeshSelected

凝视跟踪器可以通过设置gazeTrackerMesh进行自定义范例 -


vrHelper.gazeTrackerMesh = BABYLON.Mesh.CreateSphere("sphere1", 4, 0.1, scene);

多视点

要将渲染性能提高2倍,请尝试使用Multiview它将在一次渲染过程中渲染两只眼睛

例子

场景:

游戏: