babylonjs官网:www.babylonjs.com/
无论你是创建一个完整的世界或只是放置一个模型到一个网页,你需要一个 场景包含世界或模型, 相机来观察它, 灯光照亮它,当然,至少有一个可视对象作为模型。所有的模型,无论是一个方块或一个复杂的字符,都是由三角形或面的 网格。
HTML模板
xml
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title>Babylon Template</title>
<style>
html, body {
overflow: hidden;
width: 100%;
height: 100%;
margin: 0;
padding: 0;
}
#renderCanvas {
width: 100%;
height: 100%;
touch-action: none;
}
</style>
<!-- 引入Babylonjs -->
<script src="https://cdn.babylonjs.com/babylon.js"></script>
</head>
<body>
//画布
<canvas id="renderCanvas"></canvas>
<script>
const canvas = document.getElementById("renderCanvas"); // 获取画布
const engine = new BABYLON.Engine(canvas, true); // // 创建渲染引擎
const createScene = function () {
const scene = new BABYLON.Scene(engine);//创建场景
/*创建一个弧形旋转摄像机
*"Camera": 摄像机名称
* 第一个 Math.PI / 2 : alpha, 可理解为水平角度
* 第二个 Math.PI / 2 : beta, 可理解为垂直角度
* 2: radius, 半径
* new BABYLON.Vector3(0, 0, 5)目标点的三维位置,可理解为中心.这是一个向量类的实例
* scene: scene,场景变量.
* UniversalCamera通用相机,ArcRotateCamera弧形旋转摄像机,FollowCamera跟随相机,
* AnaglyphUniversalCamera立体通用相机,AnaglyphArcRotateCamera立体弧形旋转相机等
*/
const camera = new BABYLON.ArcRotateCamera("Camera", Math.PI / 2, Math.PI / 2, 2, new BABYLON.Vector3(0, 0, 5), scene);
camera.attachControl(canvas, true);//让相机控制画布
/*创建灯光
* 第一个参数: name. 名字.
* 第二个参数: direction, 方向,是一个向量的实例.
* 第三个参数: scene, 场景.
* HemisphericLight半球形光源,PointLight点光源,DirectionalLight平行光,SpotLight聚光灯
*/
const light = new BABYLON.HemisphericLight("light", new BABYLON.Vector3(0, 1, 0), scene);//创建灯光
/*创建网格
* 第一个参数 name: 物体名称
* 第二个参数 options: 参数对象,可以为物体设置长宽,体积等
* 第三个参数 scene: 加入到的场景
* CreateBox立方体,CreateSphere球体,CreatePlane平面,CreateGround地面
*/
const sphere = BABYLON.MeshBuilder.CreateSphere("sphere", {diameter: 2, segments: 32}, scene);
const ground = BABYLON.MeshBuilder.CreateGround("ground", {width: 6, height: 6}, scene);
return scene;
};
const scene = createScene();
//调用engine的runRenderLoop方案,执行scene.render()渲染场景
engine.runRenderLoop(function () {
scene.render();
});
//监听浏览器改变大小的事件,通过调用engine.resize()来自适应窗口大小
window.addEventListener("resize", function () {
engine.resize();
});
</script>
</body>
</html>
可用软件包
- @ babylonjs / core-巴比伦的核心。
- @ babylonjs / materials-一个由巴比伦支持的高级材料的集合。
- @babylonjs/loaders - 所有巴比伦的官方装载机(OBJ,STL,glTF)。
- @babylonjs/post-processes - 巴比伦的后期处理。
- @babylonjs/procedural-textures - 官方支持的程序纹理。
- @babylonjs/serializers - 场景/网格序列化器。
- @babylonjs/gui - 可用于web3D的用户界面的UI组件库。
- @babylonjs/inspector - 独立的Babylon.js查看器。
vue中使用BabylobJS
安装babylonjs软件包
npm install @babylonjs/core
npm install @babylonjs/gui
...
依次安装即可
vue3模板
1.目录下创建一个名为 scenes
的文件夹,在该文件夹中创建babylon场景文件(.js文件)
2.babylon场景文件中的代码
javascript
import {
Engine,
Scene,
FreeCamera,
Vector3,
MeshBuilder,
StandardMaterial,
Color3,
HemisphericLight,
} from '@babylonjs/core'
const createScene = (canvas) => {
const engine = new Engine(canvas) //渲染引擎
const scene = new Scene(engine) //场景
const camera = new FreeCamera('camera1', new Vector3(0, 5, -10), scene) //相机
camera.setTarget(Vector3.Zero()) //相机定位到原点
camera.attachControl(canvas, true) //相机控制画布
new HemisphericLight('light', Vector3.Up(), scene) //创建半球形光源
const box = MeshBuilder.CreateBox('box', { size: 2 }, scene) //创建盒子网格
//设置材质纹理
const material = new StandardMaterial('box-material', scene)
material.diffuseColor = Color3.Blue()
box.material = material
// 渲染场景
engine.runRenderLoop(() => {
scene.render()
})
}
export { createScene }
3. .vue文件中的代码(我们将构建一个可复用的Vue组件,它可用于显示BabylonJS场景。)
xml
<template>
<canvas ref="bjsCanvas" width="500" height="500" />
</template>
<script setup lang="ts">
import { ref, onMounted } from 'vue'
import { createScene } from '../../scenes/my-first-scene'
const bjsCanvas = ref(null)
onMounted(() => {
if (bjsCanvas.value) {
createScene(bjsCanvas.value)
}
})
</script>
<style scoped></style>
效果如图:
vue3+ts模板
1.目录下创建一个名为 scenes
的文件夹,在该文件夹中创建babylon场景文件(.ts文件)
2.babylon场景文件中的代码
arduino
import {
Engine,
Scene,
ArcRotateCamera,
FreeCamera,
Vector3,
MeshBuilder,
StandardMaterial,
Color3,
HemisphericLight,
} from '@babylonjs/core'
//创建一个名为 BabylonScene 的类
export class BabylonScene {
engine: Engine
scene: Scene
//private将属性或方法标记为私有,表示它们只能在类的内部被访问,外部无法直接访问。
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) // 创建场景
//创建相机
const camera = new ArcRotateCamera(
'camera',
Math.PI / 8,
Math.PI / 8,
10,
new Vector3(0, 0, 0)
)
camera.attachControl(this.canvas, true) //让相机控制画布
const light = new HemisphericLight('light', new Vector3(0, 1, 0), scene) // 创建半球形光源
light.intensity = 0.7 // 将灯光调暗
// 创建球形
const sphere = MeshBuilder.CreateSphere(
'sphere',
{ diameter: 2, segments: 32 },
scene
)
// 将球向上移动球高度的1/2
sphere.position.y = 1
sphere.position.x = 2
//创建立方体
const box = MeshBuilder.CreateBox(
'box',
{ height: 2, width: 2, depth: 2 },
scene
)
//位移
box.position.y = 1
box.position.x = -2
const myMaterial = new StandardMaterial('material', scene)
/*设置材质颜色
*漫反射颜色diffuseColor、镜面颜色specularColor、自发光颜色emissiveColor、环境颜色ambientColor
*/
// myMaterial.diffuseColor = new Color3(1,0,1)
myMaterial.diffuseColor = Color3.Red()
myMaterial.alpha = 0.7
box.material = myMaterial
// 内置"地面"形状。
const ground = MeshBuilder.CreateGround(
'ground',
{ width: 6, height: 6 },
scene
)
return scene
}
}
3. .vue文件中的代码
xml
<template>
<canvas ref="bjsCanvas" touch-action="none" width="500" height="500"></canvas>
</template>
<script setup lang="ts">
import { ref, Ref, onMounted } from 'vue'
import { BabylonScene } from '../../scenes/my-first-scene'
const bjsCanvas = ref(null)
onMounted(() => {
new BabylonScene(bjsCanvas.value!)
})
</script>
<style scoped></style>
效果如图:
导入资产
场景加载器SceneLoader使用前要先引入相应文件的loaders插件,这一步很重要
javascript
xml
<script src="https://preview.babylonjs.com/babylon.js"></script>
<script src="https://cdn.babylonjs.com/loaders/babylonjs.loaders.min.js"></script>
vue
arduino
import '@babylonjs/loaders/glTF'
import '@babylonjs/loaders/STL'
import '@babylonjs/loaders/OBJ'
步骤1,3同上
2.babylon场景文件中的代码
javascript
import {
Engine,
Scene,
ArcRotateCamera,
FreeCamera,
Vector3,
MeshBuilder,
StandardMaterial,
Color3,
HemisphericLight,
CubeTexture,
SceneLoader,
} from '@babylonjs/core'
import '@babylonjs/loaders/glTF'
//创建一个名为 BabylonScene 的类
export class BabylonScene {
engine: Engine
scene: Scene
//private将属性或方法标记为私有,表示它们只能在类的内部被访问,外部无法直接访问。
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) // 创建场景
//创建并返回由工具根据预过滤数据创建的纹理
const hdrTexture = CubeTexture.CreateFromPrefilteredData(
'/3d/textures/environment.dds',
scene
)
//创建默认天空盒
const currentSkybox = scene.createDefaultSkybox(
hdrTexture,
true,
undefined,
0.25,
true
)
//创建相机
const camera = new ArcRotateCamera(
'camera',
Math.PI / 8,
Math.PI / 8,
10,
new Vector3(0, 0, 0)
)
camera.attachControl(this.canvas, true) //让相机控制画布
const light = new HemisphericLight('light', new Vector3(0, 1, 0), scene) // 创建半球形光源
light.intensity = 0.7 // 将灯光调暗
/**
* 一、从文件文件夹中加载所有资源并附加到场景中
* 配置项:文件夹路径,资源名称,场景对象,回调函数
*/
// SceneLoader.Append(
// '/public/3d/common_assets/',
// 'WaterBottle.glb',
// scene,
// function (scene) {}
// )
/**
* 二、从文件中加载所有资源并创建一个新场景
* 配置项:文件夹路径,资源名称,引擎对象,回调函数
*/
// SceneLoader.Load(
// '/public/3d/common_assets/',
// 'WaterBottle.glb',
// engine,
// function (newScene) {}
// )
/**
* 三、从文件中加载网格并将其附加到场景
* 配置项:将要添加到场景中的模型名称或为空(将所有模型或者骨骼加载),文件夹路径,资源名称,场景对象,回调函数
*/
// SceneLoader.ImportMesh(
// '',
// '/public/3d/common_assets/',
// 'WaterBottle.glb',
// scene,
// function (scene) {}
// )
/**
* 四、从文件文件夹中加载所有资源但不会自动添加到场景中
* 回调函数会返回一个容器对象container,里面包含所有模型加载的资源光源,模型,相机等等。
* 配置项:文件夹路径,资源名称,场景对象,回调函数
*/
SceneLoader.LoadAssetContainer(
'/public/3d/common_assets/',
'WaterBottle.glb',
scene,
function (container) {
//手动加载所有资产到场景中
container.addAllToScene()
// //将添加的资产从场景中删除
// container.removeAllFromScene()
}
)
//五、使用Async函数来实现链式回调
// SceneLoader.LoadAssetContainerAsync(
// '/public/3d/common_assets/',
// 'WaterBottle.glb',
// scene
// ).then((container) => {
// //加载所有资产到场景中
// container.addAllToScene()
// //将添加的资产从场景中删除
// container.removeAllFromScene()
// })
return scene
}
}
效果如图: