YodaOS 首个版本发布于 19 年,它当时定位于开源智能音箱解决方案,笔者当时就作为 YodaOS 应用框架的核心维护者,为 JavaScript 开发者提供了内置的 JavaScript 语音应用框架。
时过境迁,智能音箱逐渐淡出了人们的焦点,似乎在语音助手领域的场景与 Web 生态并没那么契合,带屏音箱也让解决方案重新回到了 AOSP(Android)的生态。
而我兜兜转转 4 年过去,又回到了 Rokid,我仍然希望为 Web 开发者们找到一些有趣又足够支撑起工程师们生存的下一个增长曲线,于是便有了今天的 YodaOS JSAR —— 空间小程序。
几年时间,YodaOS 从原来的智能音箱操作系统(基于 Linux)升级为 YodaOS Master,后者是用于空间计算(AR/MR/XR)场景的操作系统,技术底座也从原来的 Linux Kernel 变为 AOSP,而 YodaOS JSAR 则是在这个系统之上构建的一套面向 Web 开发者的应用框架,可以说 YodaOS JSAR 是之前 YodaOS JavaScript Application Framework 的延续,从原来开发一个语音技能应用升级到空间小程序的开发。
就在不久前,笔者受邀参加了 OpenJS World 2023 在上海的一次小型分享会:
OpenJS World 2023 上海站研讨会
本文将结合这次研讨会上分享的内容做一次文字版本的输出,以期望给本文读者了解 YodaOS JSAR 的全貌以及背后的思考逻辑。
空间与空间计算作为背景补充,首先来了解什么是空间。
在增强现实(AR)的场景中,空间是指现实世界中的一个区域,这个区域可以是一个平面,也可以是一个立体的物体。用户通过空间小程序来获取空间的信息,比如空间的大小、空间的位置、空间的旋转角度等等,而在一般的 AR 应用开发中,我们都会使用一个场景来承载空间。
来自 Wolvic 技术文档
如上图,来自 Wolvic 的技术文档,它描述了一个浏览器在空间中的设计,可以看到浏览器之前的 Tab 现在变为了一系列环绕在用户周围的虚拟屏幕(网页),这样用户只需要通过转头即可切换要浏览的网页或应用,而功能菜单则位于虚拟屏幕的上下,可以通过手柄或者手势进行交互。
来自 YodaOS-Master 系统真机录制
而 YodaOS Master 系统也有同样的设计,用户可以在系统中打开不同的窗口,每个窗口对应一个网页或者安卓应用,用户通过手势或射线来与窗口和功能菜单进行交互。
来自 Wolvic 技术文档
用户空间描述起来就如同上图一样:用户位于空间的中心,围绕着用户的是一个圆柱曲面,用户可以将曲面中的一部分作为一块虚拟屏幕用于显示一个网页或应用,用户通过转头来切换要使用的应用。
空间小程序读者熟知的小程序一般是微信小程序,开发者通过开发小程序可以在用户无需下载应用的情况下,在微信中使用一些即开即用的功能,比如:点外卖、酒店预定、网约车等。
那空间小程序是什么呢?先来看一个演示视频:
https://ar.rokidcdn.com/web-assets/pages/yodaos-jsar-demo.mp4(这里是视频)
可以看到除了在上一小节中看到的屏幕外,还在空间中有一些可交互的 3D 物体,这就是空间小程序。
因此,空间小程序就是在原有的空间中,在屏幕之外添加一些可交互的 3D 物体,并且每个可交互物体之间是独立运行的。这就需要空间小程序具备以下特性:
安全性
从平面到立体
从窗口到空间
单从空间小程序的技术实现来说,并不一定要选择 Web,像 Lua、Python 或是其他脚本语言都可以完成,这次除了我自己对于 Web 的一腔热血外,也需要一些特别的技术优势。
Web 技术从 1993 年 HTML 1.0 发布以来,从原来的文档分享,到信息站点,再到现在的 Web 应用,我们可以抽取到大家愿意使用 Web 技术的特点就是安全性和便捷性,而这两者相辅相成、互相成就。
因此 YodaOS JSAR 希望基于安全性和便捷性设计的空间应用框架,以此来让开发者和用户可以在独立的空间应用之外,可以做一些简单、有趣、便捷的“空间小程序”,它可以很容易被分享(当然安全性是前提)和传播。
新三剑客在空间计算时代,YodaOS JSAR 给出了 Web 的新解决方案,即新的三件套 —— XSML、SCSS 和 TypeScript。
XSML它对应于 HTML,全称是 eXtensible Spatial Markup Language,即可拓展空间标记语言。
XSML 代码示例
上图是 XSML 的代码示例,熟悉 HTML 的开发者一定不陌生,几乎和今天的 HTML 类似,区别仅在于一些标签的差异,比如:
变成了
变成了
以下便是一些 YodaOS JSAR 新增的标签:
引用 3D 模型
创建一个立方体
创建一个平面
创建一个球体
创建一个胶囊形状
创建一个圆环
创建一个 3D 包围盒,类似于
上图的狮子就是通过 XSML 描述生成的:
源代码:https://github.com/M-CreativeLab/jsar-gallery-flatten-lion/blob/main/lib/lion.xsml
在线演示:https://jsar.netlify.app/playground?url=https://raw.githubusercontent.com/M-CreativeLab/jsar-gallery-flatten-lion/main/lib/lion.xsml(请确保你本地可以访问 raw.githubusercontent.com 域名)
如需了解完整的 XSML 说明,可访问:https://jsar.netlify.app/zh-CN/manual/latest/basic-concepts/intro-xsmlSCSS
它对应于 CSS,全称是 Spatial Cascading Style Sheet,即空间层叠样式表。SCSS 语法完全继承自 CSS,使用方式也相同:
通过选择器选择对应的元素
设置样式
比如:
@material red {
diffuse-color: #ff2200;
}
#box {
rotation: 0 0 180;
position: 0 1 0;
material: "red";
}
可以看到现在设置的不再是原来 CSS 的样式,而是面向 3D 空间设计的旋转、位置和材质等。通过 SCSS 可以非常容易和自然的布局空间样式,相较于脚本的方式更直观。
如需了解完整的 SCSS 说明,可访问:https://jsar.netlify.app/zh-CN/manual/latest/basic-concepts/intro-scssTypeScript
随着 Deno 和 Bun 这样的服务端运行时都默认支持了 TypeScript,YodaOS JSAR 也选择了 TypeScript 作为原生的支持语言,它在运行时内置了一个 TypeScript 编译器,在解释 script>时,会进行 TypeScript 代码的预处理后在 v8 中执行。
选择 TypeScript 的原因主要如下几个方面:
TypeScript 结合 Visual Studio Code 开发体验极好
TypeScript 可以运行 JavaScript,因此支持了 TypeScript 也意味着兼容 JavaScript
3D 开发领域,由于增加了多一个维度,复杂度也上升数倍,因此继续使用 JavaScript 来维护代码对开发者要求会增加,使用 TypeScript 可以降低这个门槛
有了类型系统的加持,可以更容易面向各类 LLM 写出效率更高、通用性更好的代码生成提示词
通过 YodaOS JSAR 的脚本系统,你可以使用 Babylon.js APIs 和 Web APIs。
Babylon.js 是一个支持多后端(WebGL、WebGPU、服务端以及 Native)的开源 3D 渲染引擎,它提供了一系列的游戏场景 API,可用于开发 3D 游戏和应用。
比如:
const scene = spatialDocument.scene as BABYLON.Scene;
YodaOS JSAR 提供了一个全局对象 spatialDocument,它类似于浏览器中的 document,你可以通过该对象访问到当前的 3D 场景。
YodaOS JSAR 基于 Babylon.js 框架构建,因此你可以直接通过 scene 访问到 Babylon.js 的其他能力,可以通过这里 https://jsar.netlify.app/zh-CN/manual/latest/runtime/babylonjs-apis 获取到 Babylon.js 的支持情况。
另外,YodaOS JSAR 也支持了一些 Web APIs,未来也会持续支持更多的 Web APIs,以下是目前我们认为可能在空间计算设备上继续发挥作用的 Web APIs:
使用 WebXR Device API 处理空间关系、获取输入数据、管理生命周期等
使用 ECMAScript Module 管理模块
使用 fetch 发送网络请求
使用 Timer 创建计时器
使用 Web Audio 处理和播放视频
使用 Web Speech 识别用户语音与生成语音
继续支持 WebAssembly
可以访问 https://jsar.netlify.app/zh-CN/manual/latest/runtime/web-apis 获取我们 Web APIs 的支持情况。
技术细节本节会介绍一些在实现 YodaOS JSAR 的技术。
与 Unity 集成首先,要回答一个问题 —— 为什么要与 Unity 集成?
无论是 Apple Vision Pro 还是 YodaOS Master 中,开发者现在可供选择的 3D 应用开发框架目前来说几乎就只有 Unity 这一个选择,比如对于 YodaOS Master 的桌面应用来说,它就是一个 Unity 应用,那么要实现上面说到的将空间小程序可以放到一个 Unity 应用的空间中,那么就需要实现与 Unity 一起来完成这项工作。
因此,这也意味着未来 Unity 开发者可以使用 YodaOS JSAR 集成到任何一个 Unity 应用并发布到其他平台。
下面就来看下是 YodaOS JSAR 是如何集成到 Unity 运行时的。
与 Unity 集成
上图中,左侧是 Unity 相关的部分,而右侧是 JavaScript 相关的部分,连接两端的是 YodaOS JSAR 的 Unity 插件包,Unity 应用通过添加该插件来获取 YodaOS JSAR 的运行时能力,它大体的工作流程如下:
Unity 应用通过 C# 调用 YodaOS JSAR 插件接口
插件执行 Node.js Embedder API 启动 Node.js 示例(在 Unity 非主线程)
在 Node.js 中请求要支持的小程序 URL,并按照设计的方式解析 XSML、SCSS 以及 TypeScript
将解析的结果创建为一个 Babylon.js Scene 并获取场景数据
将场景数据通过 Unity C++ 中的通信通道发送到 Unity C#
Unity 通过 C# 提供的 3D 对象(GameObject)动态创建的 API,将 Babylon.js 场景创建到 Unity 场景中
运行过程中,实时同步相关数据到 Unity 中
通过以上的流程,YodaOS JSAR 就可以完成将空间小程序中的代码在 Unity 中渲染的效果,并且由于最终生成的都是 Unity 的对象,因此也可以很容易通过 Unity 的交互来移动、旋转和缩放这个物体。
程序隔离性上图是 YodaOS JSAR 的架构图,通过它我们可以很方便地窥见它是如何保证程序隔离性的:
在 Unity Runtime,每个空间小程序的实体是独立的
每个实体对应于一个数据通道
在 Node.js 运行时侧,每个空间小程序对应一个 XSMLDocument ,同样每个文档对应一个独立的数据通道
基于以上的设计,就可以保证所有小程序在同一个 Node.js 线程的情况下,保证实际渲染是隔离并互不影响。
中间协议的设计YodaOS JSAR 最重要的部分之一便是 Unity 和 Node.js 侧中间数据的设计,下图是我们在定义数据层级的切入点示意图。
可以看到,OpenGL 包含了所有场景的三维坐标信息(包含基于坐标的其他数据)、着色器程序以及转换矩阵,那么要实现将物体渲染到 Unity 场景中,其实也可以通过 OpenGL 去实现,而且这种方式通用性更好,也更标准化,然而 YodaOS JSAR 坚持从场景管理切入的原因是我们希望做的不仅仅是输出渲染,而是与 Unity 框架做更好的融合,让用户可以在 Unity 场景中与空间小程序中的物体真实的交互,这就需要我们将物体的描述信息抽取出来去同步,而非更底层的顶点数据与着色器。
为了解决场景数据不标准的问题,我们也希望开放中间部分的数据格式,作为新的 Web Virtual Object Model 标准草案。
多端统一YodaOS JSAR 希望给到开发者一致的开发体验,因此多端表现一致性也是我们期望的重要特性。
首先,YodaOS JSAR 支持的渲染端包括:
Unity Runtime for Android
Unity Editor
Web Browser
JSAR DevTools for Visual Studio Code
对于 Unity Runtime 和 Unity Editor,由 Unity 保障。
对于后两者,其实本质上都是 Web 平台,在一开始有两个选择:一为通过 Babylon.js,二为通过 Unity 编译为 WebGL,最终使用了后者,原因如下:
设计上更清晰,所有的跨端都通过 Unity 保证
Babylon.js 和 Unity 在渲染底层有很大的不同,因此很难保证表现一致
Babylon.js 在 Web 上支持所有的能力,但在 YodaOS JSAR 只有部分支持,这样可能开发者在 Web 上调试完却发现在真机上不支持
得益于 Unity 在多端渲染上的良好表现,YodaOS JSAR 就得到了如下的效果:
YodaOS JSAR 的多端一致性
最 后我们希望借助 YodaOS,为 Node.js 社区补全终端开发这一版图,让我们用这门亲切的语言,再次回到我们熟悉的“端”的开发
上面这句是 YoadOS 应用框架上一直的期望,现在仍旧初心不改,希望 YodaOS JSAR 能在空间计算时代带给当下迷茫的前端开发者们更多的可能性!关于 YodaOS JSAR 的开源问题,它最终一定会以开源方式运作,但目前它的首要任务仍然是支持空间小程序开发者的需求以及壮大社区,当社区达到一定规模后,YodaOS JSAR 一定会以开源方式运作。
最后,对于 YodaOS JSAR 感兴趣的读者们,可以参与 Rokid 的开发者支持计划,通过点击阅读原文可申请 Rokid AR Studio 样机,来开始你的第一个空间小程序。
作者简介:刘亚中, 前 Node.js Collaborator, 先后就职于 SeedMail、Rokid 和淘宝技术部,期间负责过多个开源项目的开发,一直致力于 Web 及其他领域的交叉应用,如 Node.js 的 IoT 设备运行时 ShadowNode、Node.js 与 Python 跨语言调用库 Boa 等,目前供职于 Rokid 负责空间小程序框架 YodaOS JSAR 的设计、研发与推广。
今日好文推荐B 站广州研发工作室解散;外媒曝光苹果中国区丑闻;OpenAI 被曝已叫停新大模型项目 | Q 资讯“MySQL 之父”的 MariaDB 要完蛋了?叫停两款核心产品并裁员 28%,分析师:该行为无异于自毁长城