Blender3D模型 - 陈帅华的独立作品

Blender 是一款非常优秀的免费开源 3D 创意软件,支持 Windows、macOS 和 Linux 界面操作系统,支持众多常见的导入和导出格式。Three.js 是一款由 JavaScript 语言编写的用于 Web 端展示的优秀 3D 开源库,常在 Web 游戏、可视化、真实场景模拟等领域中被使用。两款优秀且开源的 3D 创意工具的碰撞,必定能为产品、设计师和前端工程师带来无限创造力。

格式哪些支持

Blender 支持情况:

下方左右两侧截图分别展示了 Blender2.8 支持的导入和导出格式,其中右侧的导出格式列表中,请留意下最后一项 glTF2.0(.glb/.gltf) ,我将在下边的示例中使用这个格式导出“塔”的 3D 模型:
Blender 支持的导入和导出格式

Three.js 支持情况:

除了内置的简单几何体,比如立方体、锥体、圆柱体等等,Three.js 支持从外部加载 3D 模型,这使得在 Web 端展示复杂场景成为可能。Three.js 中包含了面向对象的思维,Loader 类是加载器子类的父类。我们一般并不会在项目中用到全部加载器,至少加载 glTF 格式模型的加载器在这篇文章中不可缺少。除了用于加载 3D 模型的加载器,Three.js 中还有加载各种资源的加载器,比如声音、图像等。新版本的 Three.js 将模型加载器剥离出代码,我们可以按需从官方示例代码中引用特定的加载器。

在 Three.js 官方文档介绍 glTF 加载器的部分,开发者需要自行在项目中引入 examples/js/loaders/GLTFLoader.js

  1. dae格式支持导出动画;
  2. obj格式不支持导出动画;
  3. mtl专门存储材质贴图;
  4. glb/gltf为推荐格式,支持导出动画导出材质贴图。

从 Blender2.8 开始,支持导出 glTF 格式模型。glTF(gl传输格式)是一种开放格式的规范 (open format specification),用于更高效地传输、加载3D内容。该类文件以JSON(.glft)格式或二进制(.glb)格式提供, 外部文件存储贴图(.jpg、.png)和额外的二进制数据(.bin)。一个glTF组件可传输一个或多个场景, 包括网格、材质、贴图、蒙皮、骨架、变形目标、动画、灯光以及摄像机。

我用Blender搞过人造卫星

借着写这篇想法的兴致,我从云盘“翻箱倒柜”找到2016年为某项目用 Blender 制作人造卫星 3D 模型,源文件已经找不到了,但是模型可以正常导入目前最新版本的 Blender 中。

blender造一个人造卫星 - 陈帅华

Three.js加载glTF导出

glb和gltf只是格式和存储网格模型数据的方式不同,但导入Threejs项目中后得到的对象完全相同。使用GLTFLoader加载器加载glb和gltf格式的文件,加载成功后在回调函数中得到一个表示glb或gltf中的数据的对象,对象中包括以下属性字段:

  1. animations,动画数据
  2. asset,包括作者署名、导出glb/gltf格式的插件名称及版本号
  3. cameras,包含场景中的摄像机信息
  4. parser,解析glb/gltf格式文件的解析器对象
  5. scene,当前场景,包含场景中的所有物体
  6. scenes,场景数组
  7. userData,用户在blender中自定义的数据

Three.js项目导入glTF文件

Blender建模一个“塔”

每次新创建一个blender项目,场景中都会出现一个小立方体。可以将这个立方体删除创建其他物体,但我要保留这个小立方体,并用它来开始一座简易灯塔的建模。

从物体模式切换至编辑模式,开始对小立方体进行建模。通过一系列的挤出、缩放与移动变换操作,一座简易的塔就完成了。这座塔共有64个点、124条边和62个面。这些点、线和面越少,当然也就越省性能。在保证效果的基础上尽可能减少模型面数,能节省内存占用提升性能。

使用blender建模一座塔 - 陈帅华

我想暂时不给模型添加贴图,而是仅导出几何模型,仅保留几何数据。导出为 glTF 格式文件,导出后的文件大小为 5KB。

将模型导入Threejs项目中后,得到一个表示所导入数据的对象,其中我要的模型就在scene场景中。scene继承THREEJS的Object3D基类,所以包含children属性,从中找到塔这个网格模型。然后是材质,我临时使用Threejs提供的MeshNormalMaterial材质,这款材质能清晰的反应3D模型的立体几何外观。

blender能够自动展开模型的UV。但是为了让展开的UV更清楚,需要人工的标记展开切缝。进入编辑模式后,选择线编辑模式,然后将要展开的缝隙切开,再展开UV。展开后的UV布局图就可以导出成图像了。导入到图像编辑软件中绘制贴图,然后再将贴图导入进blender中,即完成了UV贴图的制作。

blender中场景的显示模式包括线框、实体、视觉预览、渲染。这里选择视觉预览模式,就可以看到附加在模型上的UV贴图。开启渲染模式,则会加入灯光的作用。

最后导出带材质的模型到THREEJS项目中即可。如果使用blender导出的材质和贴图,记得要在Threejs场景中添加一种灯光,可以是环境光、电光源或其他灯光类型。这样blender和threejs之间的协作方式就一目了然了。

坐标系差别

Blender中的3D坐标系与Threejs中的3D坐标系不同,简单来说:

  1. X轴指向相同;
  2. Y轴/Z轴对调。

动画支持

事先在blender中创建简单的关键帧动画。

如果要Threejs中应用动画,时间总是起到关键作用。Threejs提供了一个Clock类像时钟那样记录时间。

var clock = new THREE.Clock();

假设已经在场景中创建了一个网格物体(这个物体通常是从glb文件获取的,这样才能和动画匹配),这里变量名为mesh。

var mesh;
var mixer = new THREE.AnimationMixer( mesh );
var animations = glb.animations; // 获取
var animation = THREE.AnimationClip.findByName(animations, "tower");
var action = mixer.clipAction( animation );
action.play();

动画开始播放了,但是并没有实时渲染到场景中,此时将以下代码加入到requestAnimationFrame中即可在渲染场景时更新动画。

mixer.update( clock.getDelta() );

这样就能看到在blender中创建的动画在Threejs中的渲染效果了。我在blender中创建了塔在平面上移动的简单动画。