Babylon.js 3D 引擎:功能完备的 Web 3D 库
Babylon.js 3D引擎完全入门指南:从零构建你的第一个Web交互场景
Babylon.js 是一个功能完备、基于 WebGL 的开源 3D 渲染引擎,专为浏览器打造。它允许你在无需安装任何插件的情况下,直接在网页中创建游戏、产品展示、数据可视化或沉浸式体验。本教程将带你从零基础顺利入门,掌握 Babylon.js 的核心概念与实战技能。
为什么选择 Babylon.js?
与其他 Web 3D 库相比,Babylon.js 具有以下显著优势:
- 开箱即用的完整工具链:场景编辑器、材质编辑器、节点材质编辑器、GUI 系统、物理引擎,全内置。
- 优秀的 TypeScript 支持:从源代码开始就是用 TypeScript 编写的,智能提示极佳。
- 丰富的学习资源:官方文档、Playground 在线调试、社区活跃,降低学习门槛。
- 卓越的性能:支持实例化、视锥剔除、WebGPU(实验性)、场景优化器等优化手段。
- 强大的跨平台能力:支持 Web、移动端、甚至能够导出为 Native 应用。
准备工作:搭建第一个场景
引入 Babylon.js
你可以通过 CDN、NPM 或官方 Playground 进行开发。最简单的开始方式是使用 CDN:
<!DOCTYPE html>
<html>
<head>
<title>My First Babylon Scene</title>
<script src="https://cdn.babylonjs.com/babylon.js"></script>
</head>
<body>
<canvas id="renderCanvas" style="width: 100%; height: 100%;"></canvas>
<script>
// 你的代码将写在这里
</script>
</body>
</html>
如果需要 ES6 模块安装方式:
npm install @babylonjs/core
创建引擎与场景
引擎是 Babylon.js 的核心,负责渲染循环。场景则包含所有 3D 对象。
const canvas = document.getElementById("renderCanvas");
const engine = new BABYLON.Engine(canvas, true); // 第二个参数启用抗锯齿
const createScene = function () {
const scene = new BABYLON.Scene(engine);
// 设置背景色
scene.clearColor = new BABYLON.Color3(0.2, 0.3, 0.4);
return scene;
};
const scene = createScene();
// 渲染循环
engine.runRenderLoop(function () {
scene.render();
});
// 监听窗口大小变化
window.addEventListener("resize", function () {
engine.resize();
});
现在你有了一个深蓝色的空白画布,准备好填充物体了。
核心概念:场景、相机、光源、网格
相机(Camera)
相机决定观察点。最常用的是 ArcRotateCamera(环绕旋转)和 FreeCamera(自由移动)。
ArcRotateCamera 适合产品展示:
const camera = new BABYLON.ArcRotateCamera(
"camera",
-Math.PI / 2, // alpha(水平角度)
Math.PI / 2.5, // beta(垂直角度)
10, // 半径
BABYLON.Vector3.Zero(), // 目标点
scene
);
camera.attachControl(canvas, true); // 允许鼠标/触控控制
光源(Light)
没有光,一切都将漆黑一片。常用光源:
- HemisphericLight:模拟环境光 + 天光,适合基础照明。
- DirectionalLight:平行光,适合模拟太阳。
- PointLight:点光源,类似灯泡。
- SpotLight:聚光灯。
const light = new BABYLON.HemisphericLight(
"light",
new BABYLON.Vector3(1, 1, 0), // 方向
scene
);
网格(Mesh)与基本几何体
Babylon.js 内置了丰富的几何体创建方法,例如盒子、球体、平面等。
// 创建一个红色立方体
const box = BABYLON.MeshBuilder.CreateBox("box", { size: 2 }, scene);
box.position.y = 1;
// 为立方体添加简单颜色材质
const material = new BABYLON.StandardMaterial("boxMat", scene);
material.diffuseColor = new BABYLON.Color3(0.8, 0.2, 0.2);
box.material = material;
至此,你应该能在浏览器中看到并拖拽旋转这个立方体。
材质与纹理进阶
StandardMaterial 核心属性
StandardMaterial 是最常用的 PBR(物理渲染)材质,它支持:
- diffuseColor / diffuseTexture:固有色或贴图。
- specularColor:高光颜色。
- emissiveColor:自发光颜色。
- ambientColor:环境光反射。
- alpha:透明度。
给立方体贴一张纹理:
material.diffuseTexture = new BABYLON.Texture("https://assets.babylonjs.com/textures/wood.jpg", scene);
PBRMaterial 实现物理精确渲染
PBR 材质能模拟金属、粗糙度等真实材质感。
const pbr = new BABYLON.PBRMaterial("pbrMat", scene);
pbr.albedoColor = new BABYLON.Color3(0.2, 0.6, 0.9);
pbr.metallic = 0.8;
pbr.roughness = 0.3;
sphere.material = pbr;
多材质与子网格
一个网格可以拥有多个材质,通过子网格实现:
const multiMat = new BABYLON.MultiMaterial("multi", scene);
multiMat.subMaterials.push(redMat);
multiMat.subMaterials.push(blueMat);
box.subMeshes = [];
// 需要借助 Babylon.js 的子网格设置,可查阅文档
更简单的方式是使用 MeshBuilder 的 faceColors 或直接操作 subMaterials。
动画:让场景动起来
Babylon.js 动画系统功能强大,支持属性动画、关键帧、缓动函数。
简单位移动画
将立方体沿 Y 轴上下移动:
const frameRate = 30;
const animation = new BABYLON.Animation(
"boxAnimation", // 名称
"position.y", // 目标属性
frameRate, // 帧率
BABYLON.Animation.ANIMATIONTYPE_FLOAT,
BABYLON.Animation.ANIMATIONLOOPMODE_CYCLE
);
// 关键帧数组
const keys = [
{ frame: 0, value: 0 },
{ frame: 30, value: 5 },
{ frame: 60, value: 0 }
];
animation.setKeys(keys);
// 将动画添加到立方体
box.animations = [];
box.animations.push(animation);
// 播放动画
scene.beginAnimation(box, 0, 60, true);
使用动画组与动画混合
对于角色动画,通常使用从 3D 软件导入的骨骼动画,通过 AnimationGroup 控制。
交互:响应用户操作
点击拾取(Picking)
让场景中的物体可被点击:
box.actionManager = new BABYLON.ActionManager(scene);
box.actionManager.registerAction(
new BABYLON.ExecuteCodeAction(
BABYLON.ActionManager.OnPickTrigger,
function () {
// 点击时随机改变颜色
material.diffuseColor = new BABYLON.Color3(Math.random(), Math.random(), Math.random());
}
)
);
GUI 系统
Babylon.js 拥有独立的 GUI 库,可以创建按钮、文本、图像等 HUD 元素。
<script src="https://cdn.babylonjs.com/gui/babylon.gui.min.js"></script>
const advancedTexture = BABYLON.GUI.AdvancedDynamicTexture.CreateFullscreenUI("UI");
const button = BABYLON.GUI.Button.CreateSimpleButton("btn", "Click Me");
button.width = "150px";
button.height = "40px";
button.color = "white";
button.background = "green";
button.onPointerUpObservable.add(function () {
alert("Hello from GUI!");
});
advancedTexture.addControl(button);
物理引擎集成
Babylon.js 内置了 Cannon.js 和 Ammo.js(Bullet 物理引擎的 WASM 版本)插件。
启用物理引擎
<script src="https://cdn.babylonjs.com/cannon.js"></script>
或者在 NPM 中安装 @babylonjs/core 与 cannon。
const gravityVector = new BABYLON.Vector3(0, -9.81, 0);
const physicsPlugin = new BABYLON.CannonJSPlugin();
scene.enablePhysics(gravityVector, physicsPlugin);
创建物理碰撞体
// 将立方体变为物理刚体
box.physicsImpostor = new BABYLON.PhysicsImpostor(
box,
BABYLON.PhysicsImpostor.BoxImpostor,
{ mass: 1, restitution: 0.9 },
scene
);
// 创建地面(静态刚体)
const ground = BABYLON.MeshBuilder.CreatePlane("ground", { size: 10 }, scene);
ground.position.y = -2;
ground.rotation.x = Math.PI / 2;
ground.physicsImpostor = new BABYLON.PhysicsImpostor(
ground,
BABYLON.PhysicsImpostor.PlaneImpostor,
{ mass: 0, restitution: 0.9 },
scene
);
现在立方体将受到重力影响并掉落到地面上。
高级特性速览
粒子系统(Particles)
用于火焰、烟雾、雨雪等效果。
const particleSystem = new BABYLON.ParticleSystem("particles", 2000, scene);
particleSystem.particleTexture = new BABYLON.Texture("https://assets.babylonjs.com/textures/flare.png", scene);
particleSystem.emitter = box; // 从立方体上发射
particleSystem.minEmitBox = new BABYLON.Vector3(-0.5, 0, -0.5);
particleSystem.maxEmitBox = new BABYLON.Vector3(0.5, 0, 0.5);
particleSystem.color1 = new BABYLON.Color4(0.7, 0.8, 1.0, 1.0);
particleSystem.color2 = new BABYLON.Color4(0.2, 0.5, 1.0, 1.0);
particleSystem.minSize = 0.1;
particleSystem.maxSize = 0.5;
particleSystem.start();
后期处理(PostProcess)
全屏特效,如泛光、色调映射等。
const pipeline = new BABYLON.DefaultRenderingPipeline(
"defaultPipeline", // 名称
true, // hdr
scene,
[camera]
);
pipeline.bloomEnabled = true;
pipeline.bloomThreshold = 0.8;
pipeline.bloomWeight = 0.5;
环境贴图与天空盒
为场景添加环境反射和天空背景。
const hdrTexture = BABYLON.CubeTexture.CreateFromPrefilteredData("environment.env", scene);
scene.environmentTexture = hdrTexture;
scene.createDefaultSkybox(hdrTexture, true, 1000);
加载 3D 模型
Babylon.js 支持 .glTF/.glb、.obj、.babylon 等格式。
BABYLON.SceneLoader.ImportMesh("", "models/", "character.glb", scene, function (meshes) {
const character = meshes[0];
character.position.y = 0.5;
});
完整实例:可交互的产品展示台
下面整合所有知识,创建一个带有旋转汽车模型(使用占位球体代替)、GUI 按钮切换材质、粒子背景和物理地面的小型展示台。为了简便,我们使用内置几何体替代真实模型。
const createShowcaseScene = function () {
const scene = new BABYLON.Scene(engine);
scene.clearColor = new BABYLON.Color3(0.1, 0.1, 0.15);
const camera = new BABYLON.ArcRotateCamera("cam", -0.5, 0.8, 8, BABYLON.Vector3.Zero(), scene);
camera.attachControl(canvas, true);
camera.lowerRadiusLimit = 3;
camera.upperRadiusLimit = 15;
const light = new BABYLON.HemisphericLight("light", new BABYLON.Vector3(0, 1, 0), scene);
light.intensity = 0.7;
// 展示物体(球体)
const product = BABYLON.MeshBuilder.CreateSphere("product", { diameter: 2 }, scene);
product.position.y = 1;
// 两种材质
const material1 = new BABYLON.StandardMaterial("mat1", scene);
material1.diffuseColor = new BABYLON.Color3(0.9, 0.5, 0.2);
const material2 = new BABYLON.StandardMaterial("mat2", scene);
material2.diffuseColor = new BABYLON.Color3(0.2, 0.7, 0.9);
product.material = material1;
// 自动缓慢旋转
scene.onBeforeRenderObservable.add(() => {
product.rotation.y += 0.01;
});
// GUI 切换材质按钮
const gui = BABYLON.GUI.AdvancedDynamicTexture.CreateFullscreenUI("GUI");
const switchBtn = BABYLON.GUI.Button.CreateSimpleButton("switch", "切换颜色");
switchBtn.width = "150px";
switchBtn.height = "50px";
switchBtn.color = "white";
switchBtn.background = "#222266";
switchBtn.horizontalAlignment = BABYLON.GUI.Control.HORIZONTAL_ALIGNMENT_RIGHT;
switchBtn.verticalAlignment = BABYLON.GUI.Control.VERTICAL_ALIGNMENT_BOTTOM;
switchBtn.onPointerClickObservable.add(() => {
if (product.material === material1) {
product.material = material2;
} else {
product.material = material1;
}
});
gui.addControl(switchBtn);
// 粒子背景
const particles = new BABYLON.ParticleSystem("particles", 500, scene);
particles.particleTexture = new BABYLON.Texture("https://assets.babylonjs.com/textures/flare.png", scene);
particles.emitter = BABYLON.Vector3.Zero();
particles.minEmitBox = new BABYLON.Vector3(-3, 0, -3);
particles.maxEmitBox = new BABYLON.Vector3(3, 4, 3);
particles.color1 = new BABYLON.Color4(1, 0.8, 0.5, 1);
particles.color2 = new BABYLON.Color4(0.5, 0.5, 1, 1);
particles.minSize = 0.05;
particles.maxSize = 0.2;
particles.emitRate = 100;
particles.blendMode = BABYLON.ParticleSystem.BLENDMODE_ADD;
particles.start();
// 地面
const ground = BABYLON.MeshBuilder.CreateGround("ground", { width: 20, height: 20 }, scene);
const groundMat = new BABYLON.StandardMaterial("groundMat", scene);
groundMat.diffuseColor = new BABYLON.Color3(0.2, 0.2, 0.2);
ground.material = groundMat;
ground.receiveShadows = true;
// 物理(如果不安装 Cannon,注释掉即可)
// scene.enablePhysics(new BABYLON.Vector3(0, -9.81, 0), new BABYLON.CannonJSPlugin());
return scene;
};
const showcaseScene = createShowcaseScene();
engine.runRenderLoop(() => { showcaseScene.render(); });
性能优化小贴士
- 实例化(Instances):大量相同网格使用
mesh.createInstance()代替克隆,降低绘制调用。 - 场景优化器:
BABYLON.SceneOptimizer可根据帧率自动调整渲染质量。 - 遮挡剔除:启用
scene.occlusion或使用BABYLON.OcclusionHelper。 - 纹理压缩:使用
.ktx2等格式,减小内存占用。 - 冻结世界矩阵:对于静态物体,调用
mesh.freezeWorldMatrix()提升性能。
下一步学习路线
- 官方 Playground:直接在浏览器中修改示例并查看效果,适合快速实验。
- 节点材质编辑器:可视化的材质创建,无需编写代码。
- BABYLON.GUI:深入定制 UI 界面。
- WebXR 支持:打造沉浸式 VR/AR 体验。
- 与前端框架集成:Babylon.js 可以无缝嵌入 React、Vue 等框架。
你还可以探索官方文档中的案例库,找到与你的项目相近的起点项目。
总结
至此,你已经掌握了 Babylon.js 的基础构造、材质、动画、交互、物理和高级特效。这个引擎的强大之处在于它的模块化和全栈式解决方案,无论你想创建一个简单的 3D 产品轮播,还是一个复杂的多人游戏,它都能提供强力支持。接下来,开始动手,用代码构建属于你的三维世界吧!