项目背景与目标
Rokid AR 开发生态 中,JSAR 框架是开发者构建空间交互内容的核心引擎,底层集成了 SLAM 空间感知系统、三维渲染管线以及多传感器数据接口,通过统一 JavaScript API 封装呈现,使开发者能够像编写网页一样,快速创建沉浸式 AR 应用
本文以 "Solar System 行星系统" 项目为例,深入解析 JSAR 应用的技术实现逻辑,从模型加载与脚本控制,到 SLAM 空间映射与渲染协同,帮助开发者全面理解 Rokid JSAR 的底层运行机制与空间计算原理。
Rokid SLAM 核心原理
Rokid 的 SLAM 系统是一种基于视觉与惯性融合的 VIO-SLAM 技术,能够在未知环境中同时完成定位与建图。通过结合 IMU 传感器 的短时姿态估计、RGB 相机的空间特征捕获,以及 融合算法的优化计算,设备无需 GPS 或外部标识,即可实现厘米级精度的空间追踪,可以理解为设备拥有空间导航能力,即便在无 GPS 的环境中,也能感知周围环境、记忆位置并精准定位自身
🚀 高精度空间定位:实时追踪相机姿态,误差可控制在厘米级范围内
🧠 强鲁棒性融合算法:融合视觉与惯性数据,在弱光或遮挡场景下依然稳定
⚙️ 低延迟空间响应:优化的渲染与追踪同步机制,确保交互场景自然流畅
JSAR 行星系统搭建
3D 模型加载与空间结构
<xsml version="1.0"> <head> <title>Solar System</title> <link id="model" rel="mesh" type="octstream/glb" href="./model/solar-system.glb" /> <style type="text/scss"> #model { rotation: 0.4 0 0; } </style> <script src="./lib/main.ts"></script> </head> <space> <mesh id="model" ref="model" selector="__root__" /> </space> </xsml>定义 JSAR 应用的基础结构:通过 link 加载名为 solar-system.glb 的三维行星模型,在 style 中设置其初始旋转角度,通过 mesh 将模型挂载到 space 空间节点中,而 space 则代表由 SLAM 驱动的三维 AR 场景,最终由 script 引入的 main.ts 实现交互逻辑与动态渲染效果
- link rel="mesh":用来指定需要加载的 .glb 三维模型
- style:用于设定模型在空间中的姿态与旋转
- mesh:表示一个可被渲染和交互的三维对象
- space:则代表整个 AR 空间,JSAR 会自动将其与设备的 SLAM 空间追踪系统关联
模型动态控制与自转动画
import { JSAR } from '@rokid/jsar'; JSAR.init({ tracking: { enableSLAM: true } }).then(() => { console.log('SLAM initialized'); const model = JSAR.getMeshById('model'); let rotation = 0; JSAR.onUpdate(() => { rotation += 0.005; model.rotation.set(0, rotation, 0); }); });通过 JSAR.init() 启动 SLAM 空间追踪功能,在空间环境就绪后,通过 getMeshById() 获取场景中的三维模型 model,利用 onUpdate() 在每一帧中更新模型的旋转角度,使其围绕 Y 轴持续旋转,从而实现了行星系统的自转动画效果
JSAR 核心功能拆解
空间就绪事件管理
事件监听:
spaceReadyspatialDocument.addEventListener('spaceReady', () => {spatialDocument 是 JSAR 框架中的空间文档对象,负责管理整个 AR 场景的生命周期,当 Rokid 设备完成 SLAM 建图与空间初始化后,会触发 spaceReady 事件,意味设备已经成功构建了 3D 世界坐标系,此时就可以安全地加载和渲染三维模型
场景与模型节点获取
const scene = spaceDocument.scene as BABYLON.Scene; const model = scene.getNodeById('model');JSAR 底层渲染引擎基于 Babylon.js,通过 scene 获取在 .xsml 文件中定义的 id="model" 三维模型节点,用于后续的渲染与交互控制
AR 光照材质优化
model.getChildMeshes().forEach(mesh => { if (mesh.material?.getClassName() === 'PBRMaterial') { const mat = mesh.material as BABYLON.PBRMaterial; mat.metallic = 0; } });遍历模型的所有网格节点,识别 PBR 材质 并将其 metallic 参数设为 0,以消除金属反光,从而提升 AR 场景与实景光照的适配效果。这是 AR 光照优化 的常用操作
XSML 场景描述详解
<space> <mesh id="model" ref="model" selector="__root__" /> </space>xsml 是 Rokid JSAR 自定义的空间场景描述语言,其中mesh 标签通过 ref="model" 引用 link 中的 3D 模型资源,与 WebXR 的 xr-scene 类似,这里Rokid 对空间管理进行了额外的抽象和封装
JSAR 空间与渲染融合机制
Rokid 的 JSAR 框架将底层空间计算能力封装为 JSAR 对象,并与 SLAM 引擎紧密耦合,实现空间感知与渲染的无缝结合。
SLAM 启动与位姿计算
- 通过 JSAR 可以轻松启动 SLAM 功能
await JSAR.init({ tracking: { enableSLAM: true // 启用 SLAM 追踪 } });
- 底层执行流程
JS 层:JSAR.init() → Native Bridge:TrackingManager.startSLAM() → C++ 层:SLAM Engine 启动(相机 + IMU 融合) → 输出设备实时空间位姿(pose)数据系统自动完成:
- 相机与惯性传感器同步
- 构建世界坐标系
- 提供设备实时位置和旋转矩阵
这样,JS 层可以实时获取设备在空间中的位姿信息,为虚拟对象的稳定渲染提供基础
模型渲染与空间锚定
当模型加载到 space 节点中
const scene = JSAR.getScene(); const model = await JSAR.loadGLB('solar-system.glb'); scene.add(model); // 自动加入 SLAM 世界空间渲染机制特性:
- 模型位置会随设备移动同步
- SLAM 计算确保模型稳定锚定在空间中
- TypeScript 控制的旋转、缩放等属性会被渲染引擎实时应用
动态行星系统实现逻辑
前面项目中加载了静态的 solar-system.glb 模型,要实现 行星自转、公转效果,可以在 main.ts 中通过脚本扩展逻辑,将三维模型的物理运动与 SLAM 空间追踪结合,实现稳定的 AR 空间交互动画
JSAR.onUpdate(() => { const sun = JSAR.getMeshByName('Sun'); const earth = JSAR.getMeshByName('Earth'); const now = Date.now(); // 当前时间戳,用于计算平滑动画 if (sun) { // 太阳自转 sun.rotation.y += 0.001; } if (earth) { // 地球自转 earth.rotation.y += 0.01; // 地球公转轨迹(半径 2 单位) const t = now * 0.001; earth.position.x = Math.sin(t) * 2; earth.position.z = Math.cos(t) * 2; } });
利用 JSAR.onUpdate 每帧更新模型状态,实现动态效果
时间驱动运动保证帧率不稳定时仍能平滑动画
可扩展到更多天体或复杂轨道系统
项目技术总结与实践经验
Rokid JSAR 项目中,spatialDocument.addEventListener('spaceReady') 标志着 SLAM 初始化完成,设备已成功构建空间坐标系,开发者可以安全加载 3D 模型、绑定空间锚点并实现交互功能。JSAR 框架将底层 SLAM 能力进行封装与扩展,提供基于 Babylon.js 的渲染与交互接口,使模型的动态控制、旋转和空间锚定可以与设备的实时位姿同步,从而实现稳定流畅的 AR 空间交互体验。这种封装不仅简化了开发流程,也保证了虚拟对象在 AR 空间中的稳定性与自然交互体验。