本节摘要:WebXR 把渲染流水线送进头显——为左右眼各画一帧、由头部追踪驱动视角、用手柄射线替代鼠标拾取。本节讲沉浸会话的申请、VR 基础体验的搭建、手柄射线交互与舒适度纪律,并算清双目渲染的帧预算账。承接 4.2 的拾取与 6.1 的呈现,是流水线压力测试的极限形态。
戴上头显的那一刻,帧流水线被加了三重压力。第一重,双目渲染:左右眼各要一帧略有视差的画面,绘制量近乎翻倍。第二重,帧率下限上移:普通屏幕掉到 30 帧只是卡,头显里掉帧直接引发眩晕,90 帧是多数设备的舒适底线。第三重,视角失控:用户想看哪儿看哪儿,2.2 节"先摆相机"的权力移交给了头部追踪——你的场景必须在任何角度都成立,背面也得是完整的。
进入 XR 的入口是"沉浸会话":浏览器向设备申请一个沉浸式环境,拿到许可后引擎接管双目渲染与追踪:
// XR 体验的入口:异步会话申请与基础环境 const xr = await scene.createDefaultXRExperienceAsync({ floorMeshes: [ground], // 地面网格:锚定玩家所在高度 disableTeleportation: false, // 传送移动:默认开启,防晕第一招 }); // 会话状态的两端 xr.baseExperience.onStateChangedObservable.add((state) => { if (state === BABYLON.WebXRState.IN_XR) { console.log("进入头显:双目渲染启动,帧预算翻倍计价"); } if (state === BABYLON.WebXRState.NOT_IN_XR) { console.log("退回头显外:恢复单目渲染"); } });
没有头显也能开发:主流浏览器提供 XR 模拟模式,开发者工具里可虚拟头部姿态与手柄输入,流程与真机完全一致——XR 开发的第一课是"先在模拟器里把逻辑跑对,再上真机调舒适度"。
第一件,地面与尺度。XR 里"米"是真实单位,玩家身高约 1.7 米,物体尺寸按现实摆——桌面 0.75 米高、门 2 米高。尺度错了,体验立刻"玩具化"或"压迫感",这是 XR 场景最常见的翻车点。
第二件,移动。摇杆直接平移相机是眩晕制造机:视觉说在动、前庭说没动,冲突即晕。工程上的替代是传送(点地瞬移)与隧道化(移动时视野收窄),默认体验里的传送就是为此预置的:
// 传送移动的微调:落点标记与有效范围 const teleport = xr.teleportation; teleport.parabolicRayEnabled = true; // 抛物线落点:像扔石子探路,直观 teleport.tintColor = BABYLON.Color3.FromHexString("#3d6fa8"); teleport.isValidMeshVisible = true; // 无效落点(如墙内)标记变红,防玩家摔出世界
第三件,控制器与射线拾取。手柄在三维世界里是一对带姿态的"手",4.2 节的拾取射线从鼠标换成手柄发射:
// 手柄射线:XR 世界里的鼠标指针 xr.input.onControllerAddedObservable.add((controller) => { controller.onMotionControllerInitObservable.add((motion) => { const ids = motion.getComponentIds(); for (const id of ids) { const comp = motion.getComponent(id); if (comp.type === BABYLON.XRControllerComponent.TRIGGER) { comp.onButtonStateChangedObservable.add(() => { if (comp.changed && comp.pressed) { // 扣扳机瞬间做拾取:射线从手柄出发(引擎的默认射线拾取已接好) console.log("扳机扣下,执行 4.2 节的拾取逻辑"); } }); } } }); });
舒适度是 XR 的隐形需求清单,违反任何一条都比"画面丑"严重:移动用传送或隧道化;视角永远不受代码控制(别替用户转头); UI 跟随视线时带平滑阻尼(瞬移的界面晃眼);文本字号加大一档(透镜畸变吃掉锐度)。
预算账按第5章的思路重算一遍。双目近翻倍的绘制量先砍一半安全垫:桌面 60 帧的预算到头显里当 30 帧用,所以 XR 场景从设计起就要按"中端手机档"配置——5.1 的三板斧、5.2 的纹理分档、6.1 的后期裁剪全部用上,多视图渲染这类单遍画双目的优化手段(一次遍历两份投影)在新版引擎里逐步可用,立项时值得评估。一张速查表:
| 项目 | 普通屏幕 | XR 头显 | 手段 |
|---|---|---|---|
| 目标帧率 | 60 | 90 | 预算砍半起步 |
| 绘制量 | 单目 | 近双倍 | 单遍多视图、LOD |
| 输入 | 鼠标键盘 | 手柄射线 | 4.2 拾取换发射源 |
| 移动 | 直接平移 | 传送优先 | 防眩晕纪律 |
⚠️ 常见坑:把桌面版的相机控制代码带进 XR——attachControl 与追踪系统抢相机所有权(4.1 的老问题在相机上的翻版),XR 会话里一律让追踪接管。
没有头显怎么验收 XR 项目? 浏览器的 XR 模拟模式覆盖逻辑验收——会话状态、射线拾取、传送落点都能虚拟;但舒适度必须在真机过一遍,模拟器里不晕不代表头显里不晕,视觉与前庭的冲突只有真人戴上设备才会复现。工程惯例是模拟器做日常开发、真机做里程碑验收。
AR 与 VR 要分开写两套吗? 会话类型不同(全沉浸对虚实融合),但引擎的会话接口把差异吸收了大半:射线、控制器、地面锚定原样复用,新增的诉求主要是虚实光照匹配与平面检测。先按 VR 把整条管线跑通,AR 是同一副骨架上加能力——这也是本节只按 VR 展开、AR 项目照样适用的原因。
帧的所有出口都打通了。下一章没有新零件——把前六章的一切装配成一个能玩的小游戏,流水线地图的毕业答辩。