在网络浏览器中构建3D图形从未像现在这样简单明了。加入我的旅程,我们将向你展示如何使用Babylon.js创建一个基本场景。
目的
本文旨在指导你如何:
- 创建一个Vue组件
- 创建一个Babylon类
- 在画布上渲染一个场景
- 创建一个3D网格
前提条件
这篇文章是一个对初学者友好的教程,尽可能地减少麻烦。不过,我建议你对JavaScript有较强的理解,才能做到这一点。
安装
安装Vue
首先,我们需要在我们的工作区安装Vue3。要做到这一点,我们在终端输入以下命令。
npm install -g @vue/cli
(注意:你需要安装Node.js,因为在我们前进的过程中,你将需要node包管理器)。
在终端中,我们使用下面的命令来创建一个新的项目,文件夹名为bb101。
vue create bb101
在创建项目文件夹后,我们会被提示有几个选择可以选择。做以下工作:
- 首先,我们要手动选择我们想要的功能,所以我们先选择
- 然后,我们将TypeScript添加到已经存在的我们想要的功能列表中
- 接下来,我们选择3x(Vue 3)作为项目中使用的Vue.js的版本
- 我们通过输入 "n "来选择**"No**"作为对以下两个选项的回应
- 我们将使用 "ESLint 仅限防错 "和 "保存时提示 "作为我们的linter的额外提示功能。
- 为了放置ESLint的配置,我们选择 "在专门的配置文件中 "这个选项,并选择**"No "**来为将来的项目保存预设。
现在,我们等待片刻,让这些程序安装完毕。接下来,我们使用命令cd bb101 ,将终端中的目录改为我们正在进行的项目的目录,然后我们使用npm run serve ,运行我们的Vue应用程序。一旦它编译完成,我们将有一个localhost服务器在我们的浏览器中打开。

安装Babylon.js
我们需要将Babylon包安装到我们的项目中。在这个项目中,我们将利用几个Babylon包,但现在,让我们从Babylon的核心包开始。要做到这一点,我们在终端使用以下命令。
npm install @babylonjs/core
上面的命令将把babylon.js安装到我们项目的node模块文件夹中。安装完成后,我们就可以进行下一步了。
开始吧
创建Vue组件(BabylonOne.vue)
我们首先修改组件文件夹中默认的helloworld.vue文件。我们想重新使用这个组件,但名字是BabylonOne而不是HelloWorld。
在我们新命名的BabylonOne.vue文件中,我们将清除HTML部分的默认内容(开始和结束的div内的所有内容),并对HTML部分和脚本标签的部分做一点改变,用以下内容代替它们。
<template>
<div>
<h3>BabylonOne</h3>
<canvas></canvas>
</div>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
export default defineComponent({
name: 'BabylonOne',
mounted(){ //lifecycle hook
const canvas = document.querySelector("canvas")
}
});
</script>
改变初始文件名会触发一个警告,因为HelloWorld是App.vue文件中使用的名字。在App.vue文件中,我们将清除模板标签中的内容,并将之前的组件名称改为BabylonOne(在HelloWorld所在的每一行都这么做)。在我们的终端使用npm run serve ,并在我们的浏览器中运行该应用程序后,结果应该如下所示。

创建Babylon类
在这一部分,我们要为Babylon创建一个TypeScript类。要做到这一点,我们将在src文件夹中创建一个子文件夹,名为BabylonOne。
在这个文件夹中,我们将创建一个名为BabylonScene的新TypeScript文件。在这个文件中,我们将从我们的Babylon核心包中导入Scene和Engine,并且我们将创建一个名为BabylonScene的类。
在这个类中,我们将创建一个场景和引擎变量以及一个构造函数,在创建该类的实例时自动调用。我们需要这个构造函数来抓取我们Vue组件中创建的画布元素。
在我们的场景变量中,我们指定类型为场景,引擎变量的类型为引擎。接下来,我们将引擎变量添加到我们的构造函数中,并将抗锯齿设置为真。
我们将在构造函数之外创建一个单独的方法,并将其分配给场景变量的Scene变量。最后,我们希望在引擎运行时同时渲染我们的场景。因此,我们将use runRenderLoop 来做这件事。下面是上述内容的一个实现。
import { Scene, Engine } from "@babylonjs/core"
export class BabylonScene {
scene: Scene;
engine: Engine;
constructor(private canvas: HTMLCanvasElement) {
this.engine = new Engine(this.canvas, true);
this.scene = this.CreateScene();
this.engine.runRenderLoop(() => {
this.scene.render();
});
}
CreateScene(): Scene {
const scene = new Scene(this.engine);
return scene;
}
}
在Vue中渲染场景
要做到这一点,我们回到BabylonOne文件,从BabylonScene.ts文件中导入BabylonScene类。在安装中,我们用参数 "canvas "来调用BabylonScene类。下面是脚本标签此刻的样子。
<script lang="ts">
import { defineComponent } from 'vue';
import { BabylonScene } from '@/BabylonOne/BabylonScene';
export default defineComponent({
name: 'BabylonOne',
mounted(){ //lifecycle hook
const canvas = document.querySelector("canvas")!;
new BabylonScene(canvas)
}
});
</script>
(注意:在canvas变量的闭合括号后面添加一个感叹号)
完成后,我们将在终端进行测试,结果如下。

修改CSS并添加摄像头和半球形灯光
我们希望画布的尺寸约为屏幕尺寸的70-80%。我们要创建一个宽度和高度为70%的画布CSS。一旦我们实现了上述内容,我们的画布将如下图所示。
现在,我们想在画布中看到东西--因此,我们将添加一个摄像头、一盏灯和一些3D物体(一个地面和一个球体)。要做到这一点,我们在BabylonScene.ts文件中的CreateScene方法中添加以下代码。
const Camera = new FreeCamera("camera", new Vector3(0,1,-5), this.scene);
Camera.attachControl();
const light = new HemisphericLight("light", new Vector3(0,1,0), this.scene);
light.intensity = 0.5;
//3D Object
const ground = MeshBuilder.CreateGround("ground", {width: 10, height:10}, this.scene);
const sphereball = MeshBuilder.CreateSphere("sphereball", {diameter:1}, this.scene);
sphereball.position = new Vector3(0,1,0)
解释代码片断
当创建一个摄像机变量时,我们将其值指定为FreeCamera,并将其名称、起始位置和场景分别定义为camera, new Vector3(0,1,-5),this.scene。为了用我们的鼠标控制摄像机,我们使用attachControl 方法。
为了让相机工作,我们需要添加光线来看到我们环境中的物体。为了实现这一点,我们将创建一个光线变量,并将其值指定为HemisphericLight。我们将添加一个与摄像机变量类似的名称、起始位置和场景。
最后,我们将添加强度来调整HemisphericLight的亮度(注意,默认情况下,强度被设置为1,使得环境太亮)。
对于三维物体,我们将创建一个地面和一个球体来代表我们环境中的三维物体。为了创建一个地面,我们创建一个地面变量并赋值为MeshBuilder.CreateGround ,同时设置名称、宽度和高度以及场景。
我们还使用Meshbuilder方法来创建一个球体,同时设置名称、直径和场景。为了修改球的位置,我们将使用position方法并将其分配到一个起始位置。
在实现上述代码后,我们应该有如下的结果。

结论
Babylon.js是一个多功能的3D JavaScript库,能够用3D做任何可以想象的事情。
Babylon.js是一个完美的3D库,它唯一的缺点是包的大小。
在这个教程中,我们向你展示了如何创建一个Vue组件,一个Babylon类,在画布上渲染一个场景并创建一个3D网格。
谢谢你的阅读,祝你编码愉快