简单示例
template
js
<template>
<div class="babylon-container">
<div class="info">
<p>BabylonJS + Vue 3 示例</p>
<p>操作: 鼠标拖动旋转视角,滚轮缩放</p>
</div>
<canvas ref="renderCanvas" class="render-canvas"></canvas> // [!code focus]
</div>
</template>1. 获取 Canvas 元素
js
// 获取canvas元素的引用
const renderCanvas = ref(null);2. 创建 Engine 实例
js
// 存储BabylonJS的核心对象
let engine = null;
let sceneA = null;
// 初始化引擎
engine = new BABYLON.Engine(renderCanvas.value, true, {
precision: "highp", //渲染精度 highp(默认), mediump, lowp
renderMode: BABYLON.Engine.RENDERMODE_WEBGL2, // 渲染模式 webgl, webgl2, webgl2deferred
}); new BABYLON.Engine([canvas对象], [是否启动抗锯齿])
3. 创建场景 (Scene)
js
// 创建场景
const scene = new BABYLON.Scene(engine);
scene.clearColor = new BABYLON.Color3(0.9, 0.9, 0.9); - 场景 是所有 3D 对象的容器
- 一个 Engine 实例可以管理多个 Scene 实例,但通常情况下,一个应用对应一个场景。
4. 创建相机 (Camera)
js
// 创建相机
const camera = new BABYLON.ArcRotateCamera(
"camera1",
0,
Math.PI / 3,
10,
BABYLON.Vector3.Zero(), // 原点
scene
);
camera.attachControl(renderCanvas.value, true);- 第一个参数: 相机的名称
- 第二个参数: 水平旋转角度(弧度)
- 第三个参数: 垂直旋转角度(弧度)
- 第四个参数: 相机与目标点的距离
- 第五个参数: 目标点的位置(这里设置为原点)
- 第六个参数: 所属的场景
5. 创建光源 (Light)
js
// 创建环境光
const light = new BABYLON.HemisphericLight("light1", BABYLON.Vector3.Up(), scene);
light.intensity = 0.7;- HemisphericLight 模拟来自天空的环境光
- 第一个参数: 光源的名称。
- 第二个参数: 光源的方向(这里指向天空)
- 第三个参数: 所属的场景
6. 创建物品
js
// 往scene场景添加一个box
const box1 = BABYLON.MeshBuilder.CreateBox("box", { size: 2 }, scene);
// 往scene场景添加一个球体
const sphere = BABYLON.MeshBuilder.CreateSphere(
"sphere",
{ diameter: 2, segments: 32 },
scene
);
sphere.position.y = 1;
// 球体材质
const sphereMaterial = new BABYLON.StandardMaterial("sphereMaterial", scene);
sphereMaterial.diffuseColor = new BABYLON.Color3(0.2, 0.5, 1);
sphereMaterial.specularColor = new BABYLON.Color3(1, 1, 1);
sphereMaterial.specularPower = 32;
sphere.material = sphereMaterial;7. 启动渲染循环
js
engine.runRenderLoop(() => { // 每一帧被调用
scene.render(); // 渲染当前场景
});8. 处理窗口调整大小
js
// 当浏览器窗口大小发生变化时,调用 engine.resize() 方法来调整 Canvas 的大小
// 并重新计算相机的投影矩阵。
window.addEventListener("resize", () => {
engine.resize();
});完整简单示例
Details
html
<template>
<div class="babylon-container">
<div class="info">
<p>BabylonJS + Vue 3 示例</p>
<p>操作: 鼠标拖动旋转视角,滚轮缩放</p>
</div>
<canvas ref="renderCanvas" class="render-canvas"></canvas>
</div>
</template>
<script setup>
import { ref, onMounted, onUnmounted } from 'vue';
// 引入BabylonJS库
import * as BABYLON from 'babylonjs';
// 获取canvas元素的引用
const renderCanvas = ref(null);
// 存储BabylonJS的核心对象
let engine = null;
let sceneA = null;
// 创建3D场景
const createSceneA = () => {
// 1 初始化引擎
engine = new BABYLON.Engine(renderCanvas.value, true);
// 2 创建场景
const scene = new BABYLON.Scene(engine);
scene.clearColor = new BABYLON.Color3(0.9, 0.9, 0.9);
// 3 创建相机
const camera = new BABYLON.ArcRotateCamera(
"camera",
0,
Math.PI / 3,
10,
BABYLON.Vector3.Zero(),
scene
);
camera.attachControl(renderCanvas.value, true);
// 4 创建灯光
const light = new BABYLON.HemisphericLight("light1", BABYLON.Vector3.Up(), scene);
light.intensity = 0.7;
// 创建球体
const sphere = BABYLON.MeshBuilder.CreateSphere(
"sphere",
{ diameter: 2, segments: 32 },
scene
);
sphere.position.y = 1;
// 球体材质
const sphereMaterial = new BABYLON.StandardMaterial("sphereMaterial", scene);
sphereMaterial.diffuseColor = new BABYLON.Color3(0.2, 0.5, 1);
sphereMaterial.specularColor = new BABYLON.Color3(1, 1, 1);
sphereMaterial.specularPower = 32;
sphere.material = sphereMaterial;
const box1 = BABYLON.MeshBuilder.CreateBox("box", { size: 2 }, scene);
box1.position.x = 2;
// 创建地面
const ground = BABYLON.MeshBuilder.CreateGround(
"ground",
{ width: 10, height: 10 },
scene
);
// 地面材质
const groundMaterial = new BABYLON.StandardMaterial("groundMaterial", scene);
groundMaterial.diffuseColor = new BABYLON.Color3(0.8, 0.8, 0.8);
ground.material = groundMaterial;
// 球体旋转动画
scene.registerBeforeRender(() => {
sphere.rotation.y += 0.01;
});
return scene;
};
// 组件挂载时初始化场景
onMounted(() => {
sceneA = createSceneA();
// 启动渲染循环
engine.runRenderLoop(() => {
sceneA.render();
});
// 窗口大小变化时调整
const handleResize = () => {
engine.resize();
};
window.addEventListener('resize', handleResize);
// 组件卸载时清理事件监听
onUnmounted(() => {
window.removeEventListener('resize', handleResize);
});
});
// 组件卸载时清理资源
onUnmounted(() => {
if (engine) {
engine.dispose();
}
});
</script>
<style scoped>
.babylon-container {
position: relative;
width: 100%;
height: 520px;
background-color: #f0f0f0;
overflow: hidden;
}
.render-canvas {
width: 100%;
height: 100%;
touch-action: none;
}
.info {
position: fixed;
top: 10px;
left: 10px;
background: rgba(255, 255, 255, 0.8);
padding: 10px;
border-radius: 5px;
font-family: Arial, sans-serif;
font-size: 14px;
z-index: 100;
}
</style>