在 Pico Neo3 上使用原生 WebXR 开发 HelloWorld VR 应用

上周了解了 WebXR 相关的基本概念,今天来研究下如何用手上这台 Pico Neo 3 自己开发一个 HelloWorld 级别的 WebXR 应用。包括环境配置、代码编写以及运行。由于还是刚入门开发,所以就先不上 XR 框架了,等到对原生 API 有一定了解后,再学一下如何用 XR 框架结合前端框架开发比较完整的 APP 应该会比较好一些。

环境准备

  • 一台 VR 设备,我使用的是 Pico Neo 3
  • 本地 Web 应用服务器,而且必须能在 Pico 上可以访问
  • 浏览器端调试插件 webxr-api-emulator
  • VS Code
  • scrcpy 库

这次我使用了 pnpm + Vite + Vue 3 + TypeScript 的技术栈,因为更熟悉 Vue 所以写起来会相对快一些。后面使用到 XR 框架时,应该就要换成 React 了。

启动本地服务器

  1. 首先使用命令初始化一个新项目
1
pnpm create vite
  1. 简单修改一下配置,让服务能使用局域网 IP 访问
1
2
3
4
5
6
7
8
9
10
11
12
// vite.config.ts
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'

export default defineConfig({
plugins: [vue()],
server: {
host: '0.0.0.0',
port: 5000,
open: true
}
})
1
2
3
4
5
6
// package.json
"scripts": {
"dev": "vite",
"build": "vue-tsc && vite build --host", // 主要改了这一句,加上 --host
"preview": "vite preview"
},
  1. 运行pnpm run dev,查看效果

image-20221029235208143

  1. 使用 Pico 浏览器访问 URL,试试在 Pico 中能否访问

给 Pico 设置投屏到电脑

现在这样看有个问题是,我每次在 VR 上测试时都需要戴上设备,测试完再把设备摘下来,这样似乎有点麻烦。

所以我捣鼓了一下,让 Pico 可以往电脑上投屏,具体做法:

安装 scrcpy

这里用到了一个可以给 VR 设备投屏到电脑的开源库 https://github.com/Genymobile/scrcpy ,去 release 里下载最新的产物

image-20221030000934515

这里需要用到它提供的 adb 和 scrcpy,为了通过命令行访问比较舒服,将这个路径加入到环境变量里:

image-20221030001102175

在 Pico 里面打开开发者模式(方法和其他安卓机一样),打开 USB 调试

Screenshot_com.picovr.settings_2022.10.30-01.15.04.317_620

配置完后,打开 cmd 窗口,先运行下 adb usb 看看能否连接成功,没问题的话直接执行 scrcpy 就可以了

image-20221030011803314

执行效果大概是下面这样:

image-20221030012211077

但是我发现,只要一脱离头戴,显示器就会熄屏,所以需要想办法把它设置为永不熄屏才可以。

比较幸运的是,我在 B 站搜到了一个开启隐藏设置的教程:https://www.bilibili.com/video/av851770781/

大概操作步骤是:

  • 从下到上挨个按住头显右侧的按键,每个按键按 5 秒钟左右,可以激活隐藏设置
  • 找到系统设置 -> 高级 -> 用户配置
  • 在“特殊设置”中把自动休眠模式关闭
  • 在“电源策略”中先把系统休眠超时设置为永不,再设置屏幕关闭超时为永不

其他设置不建议瞎改,容易搞坏,除非你比较懂。需要注意,把熄屏时间关掉后,不使用时也不会自动关闭屏幕,会造成耗电更多(这东西本来就没什么续航,长时间开着肯定也雪上加霜了)

开发 HelloWorld XR 应用

好了,前期准备工作都已就绪,现在可以开始搞代码了。

要开发一个 WebXR 应用,需要依据 WebXR 应用的生命周期编写各个环节的代码,这里把之前总结过的生命周期列一下:

  1. 开发者:检查当前设备的浏览器是否支持所需的 XR 模式

    • 需要确保 WebXR Device API 可用,可以通过检测 window.navigator.xr 对象是否存在来判断,如果此对象不存在,那么说明用户使用的浏览器不支持 WebXR,或关闭了 WebXR 能力。
    • 调用 window.navigator.xr.isSessionSupported(mode),其中 mode 的可选值是 'inline' | 'immersive-vr' | 'immersive-ar',其中 inline 模式是指 HTML 文档中的元素的会话内容。 它返回的类型是Promise<boolean>,如果 Promise 返回了 false,那么表示当前的模式在用户的浏览器下无法使用。
    • 如果经过上述两个步骤确定 WebXR 能力可用,需要在页面上以适当方式提示用户可以激活 XR 模式,并绑定一个激活 XR 的事件。
  2. 用户:触发激活 XR 的事件,表明希望使用 XR

  3. 开发者:调用 window.navigator.xr.requestSession(mode, options),将 XRSession 设定为用户期望的模式

    • 此方法返回一个 Promise,如果它被 resolve,就可以用获得的 XRSession 运行渲染循环
  4. 开发者:调用 XRSession 的 requestAnimationFrame,调度 XR 设备的首帧渲染

    • 每一个 requestAnimationFrame 的回调都需要使用 WebGL 渲染 3D 物体

    • 持续在回调函数中调用 requestAnimationFrame,保证每一帧都正常渲染

  5. 持续生成帧,直到用户需要结束 XRSession 的时候

    • 如果用户希望退出 XR 模式,通过调用 XRSession.end() 可以手动结束会话
    • 无论通过何种方式终止会话,XRSessionend 事件都会收到通知

那么只需要对照着 MDN 提供的 WebXR Device API 将这些代码

Chrome 浏览器电脑调试

Pico Neo 3 真机调试

总结

打赏
  • 版权声明: 本博客所有文章除特别声明外,著作权归作者所有。转载请注明出处!
  • Copyrights © 2018-2023 Shawn Zhou
  • Hexo 框架强力驱动 | 主题 - Ayer
  • 访问人数: | 浏览次数:

感谢打赏~

支付宝
微信