babylonjs使用笔记

目录

  • 一、介绍了解
    • 1、游乐场:playground
    • 2、沙盒:sanbox
      • 1)Nodes
      • 2)Materials
      • 3)Textrues
    • 3、在线例子:examples
  • 二、模型文件
  • 三、项目使用
    • 1、文件包引入
    • 2、具现实现
      • 1)创建canvas画布
      • 2)加载3d引擎
      • 3)创建场景对象
      • 4)创建相机
      • 5)创建光源
      • 6)导入模型
        • BABYLON.SceneLoader.Append
        • BABYLON.SceneLoader.ImportMesh
        • promise版本
      • 7)循环渲染
      • 8)基本例子
  • 四、其他知识
    • 1、改变场景背景颜色
    • 2、禁止镜头缩放
    • 3、禁止镜头移动
  • 五、疑难点
    • 1、灯光问题
  • 参考资料

一、介绍了解

babylonjs是用于3D网页游戏开发的WEBGL插件,微软开发和维护的web端3D引擎。

  • 官网地址
  • 中文地址

babylonjs提供了很多很好用的工具,结合这些工具使用起来会比较容易上手。

1、游乐场:playground

Babylon.js提供了一个在线编辑器,它叫做The Playground,它是制作自己场景的最快捷,最简单的方法。

playground地址

界面很简单,左侧是代码区域,右侧是场景预览区域。编写完成后点击执行代码按钮即可实时预览场景。同时还可以单击下载按钮将代码下载下来。

2、沙盒:sanbox

sanbox工具主要是用于将三维模型导入,然后通过它可以看到当前模型的s素材组成部分、或者自带动画(如果有的话),简而言之,它是一个模型预览工具。

sanboxd地址

界面如下:
babylonjs使用笔记_第1张图片
将模型文件拖拽至界面中或者点击右下角按钮选择文件即可。
这个我将要一个obj文件传入,效果如下:
babylonjs使用笔记_第2张图片
然后我们点击第一个查看详情按钮,弹出左右两个弹窗。

1)Nodes

第一个Nodes节点中我们可以看到这个模型由四部分组成:Object059、Object060、Object061、Sphere020。这里我们把第一个碎片隐藏了。在开发过程中,我们也可以通过代码去获得这几个碎片,具体代码在下面的章节进行介绍。
babylonjs使用笔记_第3张图片

2)Materials

纹理文件,通过右侧面板可以添加纹理。
diffuse texture 漫反射纹理
specular texture 高光纹理
reflection texture 反射纹理

babylonjs使用笔记_第4张图片

3)Textrues

加载的贴图文件。这里暂时不知道为什么没有在场景中显示出来。


3、在线例子:examples

babylonjs也提供了很多在线例子可以查看,可以结合文档学习。同时也可以下载项目源码,在本地网页进行查看。

在线文档和例子


二、模型文件

从上面sandbox的初始化界面的【drag and drop gltf,glb,obj or babylon files to view them】,我们可以知道,babylonjs支持gltf,glb,obj以及babylon着四种文件格式。
其中,babylonjs内置模型格式是babylon格式,不需要其他插件即可加载。但如果使用的是其他格式的文件,则需要babylonjs-loaders插件进行加载,否则网页会提示报错无法显示。

  • gltf:素材由.gltf、.bin、texture(皮肤)文件组成;
  • glb:由gltf所有文件合成一个文件,线上转换网址;
  • obj:由.obj、.mtl、texture(皮肤)文件组成;

由于我在项目中(也就是上述sandbox中使用的文件)使用的是obj模型文件,这里就记录下obj文件情况吧。
.obj文件:
babylonjs使用笔记_第5张图片
.mtl文件
babylonjs使用笔记_第6张图片


三、项目使用

下面的项目使用笔记基于vue项目。

1、文件包引入

babylon的文件包有很多,项目中可以根据自己的需要进行加载:

  • babylonjs -主包
  • babylonjs-loaders - 模型加载loader
  • babylonjs-gui -GUI用户交互页面
  • babylonjs-materials -官方提供的一些材质

还有很多其他的可以在官网上进行查阅。

而我在项目中主要用到:

import * as BABYLON from "babylonjs"; // 主包
import "babylonjs-loaders"; // 用于加载obj模型

2、具现实现

1)创建canvas画布

html中创建canvas元素作为挂载:

<canvas id="renderCanvas">canvas>

2)加载3d引擎

const canvas = document.getElementById("imgCanvas");
const engine = new BABYLON.Engine(canvas, true, {
	preserveDrawingBuffer: true,
	stencil: true
});

3)创建场景对象

const scene = new BABYLON.Scene(engine);

4)创建相机

// 相机有几种(可查看官网),此处我创建的是是旋转相机
const camera = new BABYLON.ArcRotateCamera("Camera", 0, 0, 10, BABYLON.Vector3.Zero(0, 0, 0), scene);

camera.attachControl(canvas, true); 

5)创建光源

// 点光源
const light1 = new BABYLON.PointLight("pointLight", new BABYLON.Vector3(1, 10, 1), scene);
// 方向光
const light2 = new BABYLON.DirectionalLight("DirectionalLight", new BABYLON.Vector3(0, -1, 0), scene);
// 聚光灯
const light3 = new BABYLON.SpotLight("spotLight", new BABYLON.Vector3(0, 30, -10), new BABYLON.Vector3(0, -1, 0), Math.PI / 3, 2, scene);
// 环境光
const light4 = new BABYLON.HemisphericLight("HemiLight", new BABYLON.Vector3(0, 1, 0), scene);

6)导入模型

导入模型也是项目中最重要的部分。导入模型有两种方法:

BABYLON.SceneLoader.Append

模型相关文件都放在一个文件夹中,也就是a.obj、a.jpg、a.mtl在同一文件夹路径。

配置项:
文件夹路径,资源名称,场景对象,成功回调函数

BABYLON.SceneLoader.Append("./", "a.obj", scene, function (scene) {
	// 模型添加成功后的回调函数
	console.log(scene);
});

这里我们将scene场景对象打印出来,对象上有很多属性和方法:cameras场景相机、lights场景灯光、meshes模型碎片、animationGroups动画等等…
其中meshes就是我们在sanbox中可以查看到的四个模型碎片:
babylonjs使用笔记_第7张图片
其中数组的每一项中的id属性值即该碎片的名字。

既然可以拿到这些属性,那我们就可以对其进行一些操作:

BABYLON.SceneLoader.Append("./obj/", "a.obj", scene, function (scene) {
	// 模型添加成功后的回调函数 返回scene场景对象
	console.log(scene);
	
	const animation = scene.animationGroups;
	animation[0].stop(); // 停止动画
	animation[0].start(); // 开始动画
	
	const meshes = scene.meshes;
	meshes[0].isVisible = false; // 隐藏Sphere020碎片
	meshes[0].isVisible = true; // 显示Object059碎片
	
	meshes[1].rotation.x = 2; // 将碎片进行旋转
	meshes[2].position.y = 2; // 改变位置
	
	// ...
	// 还有很多可操作项目 可查看官方文档
	
});

BABYLON.SceneLoader.ImportMesh

importMesh和append最大的不同的地方是,append返回的是scene场景对象,而importMesh返回的是模型对象。

配置项:
素材名称(为空表示所有模型或者骨骼)、文件夹路径、资源名称、场景对象、成功回调函数

BABYLON.SceneLoader.ImportMesh("", "./obj/", "a.obj", scene, function (meshes, particleSystems, skeletons) => {
    // 模型添加成功后的回调函数 返回meshes模型对象、粒子、骨架
	console.log(meshes);
})

我们在控制台查看到meshes模型对象:
babylonjs使用笔记_第8张图片

promise版本

BABYLON.SceneLoader.AppendAsync("./obj/", "a.obj", scene).then(newScene => {
    ...
})

7)循环渲染

engine.runRenderLoop(() => {
    scene.render()
})

8)基本例子

<template>
	<div class="play">
    	<canvas id="imgCanvas"></canvas>
	</div>
</template>

<script>
import * as BABYLON from "babylonjs";
import "babylonjs-loaders";

export default {
  name: "Play",
  mounted() {
    this.scene();
  },
  methods: {
  	scene() {
		const canvas = document.getElementById("imgCanvas");
		// 加载3D引擎
		const engine = new BABYLON.Engine(canvas, true, {
	        preserveDrawingBuffer: true,
			stencil: true
		});

		// 创建场景对象
		const scene = new BABYLON.Scene(engine);

		// 创建旋转相机
		const camera = new BABYLON.ArcRotateCamera(
        	"Camera", 0, 0, 10, BABYLON.Vector3.Zero(0, 0, 0), scene
		);
		camera.attachControl(canvas, true);
		
		BABYLON.SceneLoader.Append("./obj/", 'a.obj', scene, scene  => { 
        	scene.createDefaultCameraOrLight(true, true, true); // 默认光源
			// ...
	    });

		// 画布上重复渲染场景
		engine.runRenderLoop(() => {
        	scene.render();
		});
	}
}
</script>

四、其他知识

1、改变场景背景颜色

场景默为蓝色背景,通过clearColor可以改变背景颜色,此处我将背景颜色opacity值设为0,达到透明背景的效果。

scene.clearColor = new BABYLON.Color4(0, 0, 0, 0);

2、禁止镜头缩放

默然情况下,场景镜头是可以缩放的。在移动端上通过双指触摸可看到放大缩小效果。如果想禁止此功能,可以通过camera镜头上的属性进行设置。

let myCamera = scene.cameras[0];
myCamera.lowerRadiusLimit = myCamera.radius;
myCamera.upperRadiusLimit = myCamera.radius;

3、禁止镜头移动

默认情况下,场景镜头是可以移动的。在移动端上通过双指触摸可看到画布移动效果。

scene.activeCamera.panningSensibility = 0;

五、疑难点

1、灯光问题

项目中遇到的最大的困难便是模型的灯光问题,在场景中添加默认灯光的情况下,模型如下:
babylonjs使用笔记_第9张图片
然而现在的模型材质没有光感,于是我在场景中再添加了一个从下往上的方向光:

let light = new BABYLON.DirectionalLight("Dir0", new BABYLON.Vector3(0, 1, 0), scene); // 方向y: 1 从下往上

但是场景中却没有什么变化,即使换成其他类型的光、其它方向的光也没有效果。

这个问题着实困扰到自己了,经过各种查询,才找到大致问题所在,那就是材质对光的反应。

使用diffuseTexture、specularTexture、emissiveTexture以及ambientTexture等属性中的一个或多个来设置一个材质的纹理。其中,ambientTexture只有在没有设置场景环境颜色的时候才被使用。

  • 漫反射(Diffuse)—— 在光线下观察的材料的基本颜色或质地;
  • 镜面,也叫高光(Specular)—— 光线给材质的亮点;
  • 发光(Emissive)—— 发光材料的颜色或质地,如自发光;
  • 环境(Ambient)—— 由环境背景光照明的材料的颜色或质地。
var myMaterial = new BABYLON.StandardMaterial("myMaterial", scene);
 
myMaterial.diffuseTexture = new BABYLON.Texture("a.jpg", scene);
myMaterial.specularTexture = new BABYLON.Texture("a.jpg", scene);
myMaterial.emissiveTexture = new BABYLON.Texture("a.jpg", scene);
myMaterial.ambientTexture = new BABYLON.Texture("a.jpg", scene);

scene.ambientColor = new BABYLON.Color3(1, 1, 1); // 场景环境颜色 
 
mesh.material = myMaterial;

设置完成后的效果如下:
babylonjs使用笔记_第10张图片
不过加上灯光材质之后,模型材质的感觉就不太一样的,显得很光滑。

个人觉得灯光这块还有很多没有弄明白的地方,希望以后的项目中能进一步学习到吧~

参考资料

真是要加油学习呢~
[1]: 基于babylon.js的3D网页游戏从零教程
[2]: 举个例子网:babylonjs教程

你可能感兴趣的:(前端相关)