一个简单的场景
首先我们用最少的代码构建一个简单的3D场景,让各位读者对Babylon构建场景的代码复杂度有个初步的认知。
代码采用vue3+ts的方式构建,其中Babylon部分单独使用ts文件抽离出来。
最终效果
ts部分代码(Babylon)
typescript
import {
Engine, // 引擎
Scene, // 场景
ArcRotateCamera, // 角旋转相机
Vector3, // 三维向量
HemisphericLight, // 方向光
AxesViewer // 辅助坐标轴
} from "@babylonjs/core";
export default class {
engine: Engine;
scene: Scene;
camera: ArcRotateCamera;
light: HemisphericLight;
constructor(canvas: HTMLCanvasElement) {
// 构建渲染引擎, 传入canvas画布,是否开启抗锯齿
this.engine = new Engine(canvas, true);
// 创建一个场景, 传入引擎
this.scene = new Scene(this.engine);
// 创建一个相机,设定参数,传入场景
this.camera = new ArcRotateCamera(
"camera1", // 相机名称
0, // 定义相机沿经度轴的旋转角度
0, // 定义相机沿纬度轴的旋转角度
10, // 定义相机距离目标点的距离
Vector3.Zero(), // 定义相机目标点,这里使用0向量,即0,0,0点
this.scene // 定义相机所属的场景
);
/**
* 为相机启动鼠标控制,第一个参数是为了兼容历史版本保留的,
* 现在无用,如果要使用第二个参数,第一个参数传入null即可,
* 第二个参数是是否在鼠标事件触发时不调用preventdefault,
* 传入true则不调用,默认undefined也就是false。
*/
this.camera.attachControl(null, false);
// 设置相机位置
this.camera.setPosition(new Vector3(50, 40, 15));
// 定义一个方向光, 传入光源名称,方向向量,所属场景
this.light = new HemisphericLight(
"light1",
new Vector3(3, 2, 1),
this.scene
);
// 给场景加入坐标系辅助,传入所属场景和坐标轴线长度,无需保存到全局变量中
new AxesViewer(this.scene, 10);
// 调用渲染函数
this.run();
}
run(){
// 调用引擎的循环渲染函数,在函数中调用场景的渲染函数
this.engine.runRenderLoop(() => {
this.scene.render();
})
// 监听窗口变化,调用resize函数
window.addEventListener('resize', () => {
this.engine.resize();
})
}
}
vue部分(调用ts文件构建场景)
typescript
<template>
<div style="width: 100vw; height: 100vh">
<canvas ref="canvasRef" style="height: 100%; width: 100%"></canvas>
</div>
</template>
<script setup lang="ts">
import { Ref, ref, onMounted } from "vue";
import Demo from "./babylonDemo01.ts";
const canvasRef: Ref<HTMLCanvasElement | undefined> = ref();
onMounted(() => {
new Demo(canvasRef.value!);
});
</script>
<style scoped lang="postcss"></style>
结合代码中的注释,我们还是很容易看懂每一步的意义的。
其中引擎、场景、相机是必不可少的基本要素,缺少任意一个就无法渲染出图像。
引擎
typescript
// 构建渲染引擎, 传入canvas画布,是否开启抗锯齿
this.engine = new Engine(canvas, true);
场景
typescript
// 创建一个场景, 传入引擎
this.scene = new Scene(this.engine);
相机
typescript
// 创建一个相机,设定参数,传入场景
this.camera = new ArcRotateCamera(
"camera1", // 相机名称
0, // 定义相机沿经度轴的旋转角度
0, // 定义相机沿纬度轴的旋转角度
10, // 定义相机距离目标点的距离
Vector3.Zero(), // 定义相机目标点,这里使用0向量,即0,0,0点
this.scene // 定义相机所属的场景
);
剩余的光线,坐标轴等就不再赘述。
下面我们试着添加一个立方体,以下代码追加到构造函数的尾部。
typescript
import {
Engine,
Scene,
ArcRotateCamera,
Vector3,
HemisphericLight,
AxesViewer,
MeshBuilder,
StandardMaterial,
Color3
} from "@babylonjs/core";
// 以上是更新后的import
...
this.run();
// 以上是之前的构造函数
// 以下是创建立方体的步骤
// 创建一个立方体,传入尺寸参数和所属场景
const box = MeshBuilder.CreateBox('box1', {
height: 5,
width: 6,
depth: 7
}, this.scene);
// 创建一个材质,传入所属场景
const material = new StandardMaterial('boxMat', this.scene);
// 设置材质的漫反射颜色
material.diffuseColor = Color3.Blue();
// 将立方体的材质设为上面定义的材质
box.material = material;
}
...