babylonjs 分部加载模型_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地址

界面如下:

将模型文件拖拽至界面中或者点击右下角按钮选择文件即可。

这个我将要一个obj文件传入,效果如下:

然后我们点击第一个查看详情按钮,弹出左右两个弹窗。

1)Nodes

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

2)Materials

纹理文件,通过右侧面板可以添加纹理。

diffuse texture 漫反射纹理

specular texture 高光纹理

reflection texture 反射纹理

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文件:

.mtl文件

三、项目使用

下面的项目使用笔记基于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>

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中可以查看到的四个模型碎片:

其中数组的每一项中的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模型对象:

promise版本

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

...

})

7)循环渲染

engine.runRenderLoop(() => {

scene.render()

})

8)基本例子

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();

});

}

}

四、其他知识

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、灯光问题

项目中遇到的最大的困难便是模型的灯光问题,在场景中添加默认灯光的情况下,模型如下:

然而现在的模型材质没有光感,于是我在场景中再添加了一个从下往上的方向光:

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;

设置完成后的效果如下:

不过加上灯光材质之后,模型材质的感觉就不太一样的,显得很光滑。

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

参考资料

真是要加油学习呢~

[1]: 基于babylon.js的3D网页游戏从零教程

[2]: 举个例子网:babylonjs教程

你可能感兴趣的:(babylonjs,分部加载模型)