在空间计算时代,如何让 Web 开发者快速创建 AR 建筑应用?Rokid 的 JSAR 运行时结合 Babylon.js 和 Cannon.js,让我们可以用熟悉的 Web 技术构建真实的 3D 建筑场景。本文将详细展示如何从零开始,使用积木方式搭建一个完整的房屋系统。
JSAR 项目结构
JSAR 项目采用简洁的文件结构,类似于 npm package:
JSAR4/ ├── package.json # 项目配置文件 ├── main.xsml # 场景描述文件 ├── main.ts # 主逻辑代码 └── icon.png # 项目图标
package.json 配置
{"name": "jsar-block-builder","displayName": "积木搭建器","version": "1.0.0","main": "main.xsml","files": ["icon.png", "main.xsml", "lib/*.ts"]}
这种标准化的配置方式让项目管理变得非常简单。
main.xsml 场景文件
XSML 是 JSAR 的场景描述语言,语法类似 HTML:
<xsml version="1.0"><head><title>积木搭建器 - JSAR Widget</title><script src="./lib/main.ts"></script></head><space></space></xsml>
简洁明了的声明式语法,<space> 元素代表 AR 空间场景。
核心开发:利用 JSAR 的 3D 能力
① 初始化场景
JSAR 通过 spatialDocument 全局对象提供场景访问能力:
import '@yodaos-jsar/dom'; import * as BABYLON from 'babylonjs'; import * as CANNON from 'cannon-es'; const { MeshBuilder, Vector3, Color3, StandardMaterial } = BABYLON; function initScene() { const canvas = document.querySelector('canvas') as HTMLCanvasElement; engine = new BABYLON.Engine(canvas, true, { preserveDrawingBuffer: true, stencil: true }); scene = new BABYLON.Scene(engine); scene.clearColor = new BABYLON.Color4(0.53, 0.81, 0.92, 1); }
JSAR 内置了 Babylon.js 引擎,可以直接使用其强大的 3D API。
② 相机系统
camera = new BABYLON.ArcRotateCamera( 'camera', Math.PI / 4, Math.PI / 3, 15, BABYLON.Vector3.Zero(), scene ); camera.attachControl(canvas, true); camera.lowerRadiusLimit = 5; camera.upperRadiusLimit = 30;
JSAR 自动管理相机,我们只需要设置位置和目标点即可。
③ 光照和地面
// 环境光const ambientLight = new BABYLON.HemisphericLight( 'ambient', new BABYLON.Vector3(0, 1, 0), scene ); ambientLight.intensity = 0.6; // 方向光const directionalLight = new BABYLON.DirectionalLight( 'directional', new BABYLON.Vector3(-1, -2, -1), scene ); directionalLight.intensity = 0.8; // 地面const ground = BABYLON.MeshBuilder.CreateGround( 'ground', { width: 50, height: 50 }, scene ); const groundMaterial = new BABYLON.StandardMaterial('groundMat', scene); groundMaterial.diffuseColor = BABYLON.Color3.FromHexString('#90ee90'); ground.material = groundMaterial;
通过 Babylon.js 的 MeshBuilder 创建场景基础元素非常简单直观。
④ 房屋建模策略
房屋是一个复杂的 3D 模型,我们将其拆解为多个组件:
1. 地基系统
使用循环创建 3x3 的完整地基:
for (let x = -1.5; x <= 1.5; x += 1) { for (let z = -1.5; z <= 1.5; z += 1) { const block = createBlock( { type: 'flat', size: new BABYLON.Vector3(1, 0.2, 1), color: new BABYLON.Color3(0.6, 0.6, 0.6), name: '地基' }, new BABYLON.Vector3(x, 0.1, z) ); freezeBody(block); } }
2. 墙壁系统
四面墙使用统一的米色材质:
const wallColor = new BABYLON.Color3(0.85, 0.75, 0.65); const wallHeight = 0.8; // 后墙for (let x = -1.5; x <= 1.5; x += 1) { const block = createBlock( { type: 'wall', size: new BABYLON.Vector3(1, 1, 0.2), color: wallColor, name: '后墙' }, new BABYLON.Vector3(x, wallHeight, -1.5) ); freezeBody(block); }
3. 门窗系统
通过精确定位创建门和窗户:
// 门const door = createBlock( { type: 'door', size: new BABYLON.Vector3(0.8, 0.6, 0.1), color: new BABYLON.Color3(0.4, 0.2, 0.1), name: '门' }, new BABYLON.Vector3(0, 0.5, 1.55) ); // 窗户const windowColor = new BABYLON.Color3(0.6, 0.8, 1.0); const windowLeft = createBlock( { type: 'window', size: new BABYLON.Vector3(0.1, 0.4, 0.6), color: windowColor, name: '左窗' }, new BABYLON.Vector3(-1.55, 0.8, -0.5) );
4. 屋顶系统
使用红褐色屋顶瓦片覆盖整个房屋:
const roofColor = new BABYLON.Color3(0.7, 0.3, 0.2); for (let x = -1.5; x <= 1.5; x += 1) { for (let z = -1.5; z <= 1.5; z += 1) { const roof = createBlock( { type: 'roof', size: new BABYLON.Vector3(1, 0.15, 1), color: roofColor, name: '屋顶' }, new BABYLON.Vector3(x, 1.6, z) ); freezeBody(roof); } }
5. 装饰元素
烟囱等细节提升真实感:
const chimney = createBlock( { type: 'chimney', size: new BABYLON.Vector3(0.3, 0.5, 0.3), color: new BABYLON.Color3(0.5, 0.3, 0.2), name: '烟囱' }, new BABYLON.Vector3(1, 1.95, -1) ); freezeBody(chimney);
⑤ 物理引擎集成
这是项目的核心,包含物理世界初始化和刚体创建:
// 初始化物理世界 physicsWorld = new CANNON.World({ gravity: new CANNON.Vec3(0, -9.82, 0) }); // 创建带物理的积木function createBlock(preset, position) { const mesh = BABYLON.MeshBuilder.CreateBox( `block_${blocks.length}`, { width: preset.size.x, height: preset.size.y, depth: preset.size.z }, scene ); const body = new CANNON.Body({ mass: 1, shape: new CANNON.Box(new CANNON.Vec3( preset.size.x / 2, preset.size.y / 2, preset.size.z / 2 )), position: new CANNON.Vec3(position.x, position.y, position.z) }); physicsWorld.addBody(body); physicsBodies.set(mesh, body); return mesh; }
⑥ 材质系统:打造真实感
JSAR 支持 Babylon.js 的完整材质系统:
const material = new BABYLON.StandardMaterial('mat', scene); material.diffuseColor = new BABYLON.Color3(0.85, 0.75, 0.65); // 漫反射 material.specularColor = new BABYLON.Color3(0.3, 0.3, 0.3); // 镜面反射 material.specularPower = 64; // 高光强度
通过调整这些参数,可以实现木材、石材、玻璃等不同材质效果。
⑦ 渲染循环:同步物理
JSAR 提供的渲染循环,每帧执行一次:
function animate() { const deltaTime = engine.getDeltaTime() / 1000; // 更新物理世界 physicsWorld.step(1 / 60, deltaTime, 3); // 同步 Babylon.js 网格和 Cannon.js 刚体 physicsBodies.forEach((body, mesh) => { mesh.position.set(body.position.x, body.position.y, body.position.z); mesh.rotationQuaternion = new BABYLON.Quaternion( body.quaternion.x, body.quaternion.y, body.quaternion.z, body.quaternion.w ); }); scene.render(); } engine.runRenderLoop(animate);
registerBeforeRender 是 JSAR 提供的核心 API,可以实现各种动态效果。
性能优化技巧
JSAR 场景中对象数量较多时,需要注意性能:
① 合理使用 Clone
// 好的做法:克隆已有对象const window2 = window1.clone('window-2'); // 避免:重复创建相同对象const window2 = BABYLON.MeshBuilder.CreateBox(/*...*/);
② 共享材质
// 多个对象使用同一材质const wallMat = new BABYLON.StandardMaterial('wall-mat', scene); wall1.material = wallMat; wall2.material = wallMat; wall3.material = wallMat;
③ 冻结静态物体
function freezeBody(mesh) { const body = physicsBodies.get(mesh); if (body) { body.mass = 0; body.updateMassProperties(); body.velocity.setZero(); body.angularVelocity.setZero(); } }
最终效果
通过 Console 可以看到统计信息:
房屋尺寸: 3m x 1.8m x 3m 占地面积: 9 平方米 窗户数量: 3 个 细节包含: 地基、四面墙、门窗、屋顶、烟囱等 总对象数: 38
完整房屋系统包含地基 9 块、墙壁 14 块、门窗 4 个、屋顶 9 块、烟囱 2 块。花园系统可扩展 8 棵树木和 4 朵花卉。塔楼系统支持 10 层渐变设计,包含 20 个装饰窗户和金色尖顶。
JSAR 开发心得
经过这个项目的实战,我总结了 JSAR 的几个核心优势:
Web 标准 使用 JavaScript/TypeScript,无需学习新语言,Web 开发者可快速上手。
Babylon.js 集成 强大的 3D 引擎,丰富的 API,完整的材质系统和物理引擎支持。
Chrome DevTools 完整的调试能力,实时执行代码,即时反馈,大大提升开发效率。
物理引擎 Cannon.js 集成,真实的物理模拟,支持重力、碰撞检测等。
项目结构 标准化的 npm package 格式,项目管理简单,部署方便。
总结
JSAR 为 AR 开发者提供了一个强大而易用的开发框架。通过这个房屋搭建项目,我们看到了:
使用 JavaScript/TypeScript 构建复杂 3D 建筑的能力。Chrome DevTools 带来的出色调试体验。Babylon.js 引擎提供的丰富图形能力。Cannon.js 物理引擎的真实模拟效果。自动化建筑系统的设计模式。从简单房屋到复杂塔楼的进阶路径。
如果你也对 AR 建筑应用开发感兴趣,不妨试试 JSAR。从简单的房屋开始,逐步构建你的 3D 建筑世界,相信你会和我一样,被它的优雅和强大所打动。
相关资源
• JSAR 官方文档:https://jsar.netlify.app/
• Rokid 开发者论坛:https://forum.rokid.com/
• Babylon.js 文档:https://doc.babylonjs.com/
• Cannon.js 文档:https://pmndrs.github.io/cannon-es/
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。