使用 JSAR 搭建 3D 积木房屋:从基础到完整建筑系统
在空间计算时代,如何让 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/
更多推荐


所有评论(0)