从blender合成动画到three.js解析动画的整个流程

5,249 阅读6分钟

前言

关于three.js的学习资料,网上有很多相关的demo,但基本上都是代码的实现,当你看完所有代码后,脑子里依然有很多大大的问号,没有一个全局的概念,这个模型为什么要这样子设计?模型里面的各个部件长什么样子?最终又是怎么跟解析出来的数据对应上的?更重要的是,如果工作当中让你做一个3D项目,作为一个前端工程师,你要如何主导,如何跟设计师沟通。本文将用three.js结合blender一步一步的教你实现一个3d动画的播放和切换,顺便结合材质的相关知识,实现一个换发的效果。

一、下载人物模型

首先到www.mixamo.com/ 选择一个人物模型,点击页签的Characters,翻到第三页,或者在搜索框搜索ty,选择如下这个头大身小黄头发的小男孩(如果你是个菜鸟,请务必选择这个模型,因为我们后面还有个换发的功能,要是你选择个戴帽子的还怎么换?),右侧会出现一个T字形的模型预览,然后点击右侧Download下载模型。

image.png 点击下载后会出现一个弹出框,如下图:Format请选择FBX Binary(.fbx),Pose请选择T-pose,然后点击由下角的DOWNLOAD,会下载一个fbx格式的模型。

image.png 备注:如果你要上传自己的模型,可以点击右侧的Upload Character,必须是T字型的人物模型,方便后续的骨骼绑定。

二、制作一个会走路的动画模型

回到刚刚的mixamo界面,第一步我们已经选择了一个模型,接下来点击顶部页签的Animations,此时可以看到有很多动画可供选择,我们搜索walk,然后选择第二个Walking,右侧会自动播放一个走路的动画,然后点击右侧的DOWNLOAD下载这个动画模型。

image.png 下载的选项配置按照默认的即可,这里主要注意下Skin配置,选择With Skin,意思是骨骼和皮肤一块下载,如果你不选择这个,下载的就是一把骨头,哈哈,所谓骨骼动画就是骨骼跟皮肤绑定在一起,骨骼动了,皮肤也会跟着动。

image.png

三、制作一个会跑步的动画模型

同样按照上一步的步骤,搜索run,然后选择一个跑步的动画Fast Run,最后下载。

image.png

四、合成动画

以上三个步骤我们已经下载了三个模型,一个T字型的静态模型,一个走路的动画模型,一个跑步的动画模型,接下来我们用blender将它们合成一个模型。注意,T字型的静态模型我们也把它当成一个动画。 1、打开blender(3.4版本),按键盘A,然后按键盘X,删除默认初始化的摄像机和立方体

image.png 2、点击文件->导入->FBX(.fix),选择第一步下载的静态模型

image.png

3、在物体模式下,将底部的面板往上拉高一点,点击最左侧的图标,选择编辑器类型,点击动画摄影表,再选择动作编辑器,将动画名称重命名为t_pose,最后点下推,操作步骤如下图:

image.png

4、重复上面的步骤导入走路的动画模型,此时可以按下空格键播放动画,再按空格键暂停动画,同样重复上图的步骤将新导入的动画名称改成walk,重命名后先不要点下推,观察右上角,此时有两个集合,一个Armature,一个Armature.001,选择第一个模型的集合Armature,然后在动作编辑器面板选择walk,再点下推,其实就是将walk的动画推到第一个集合Armature里,如下图

image.png

点击Armature->动画->NLA轨道,此时能看到t_pose和walk的动画都推进来了。

image.png

5、重复上面的步骤,将跑步的动画推入集合Armature,下推操作前同样要记住先选择第一个集合Armature

image.png

6、删除Armature.001和Armature.002以及自带的几个没用的mesh,如下图,最终只剩下Armature,删除方法:按ctrl键选择需要删除的项,然后右键->删除层级

image.png

7、观察合入的动画,先选择右侧的Armature集合,在动作编辑器选择相应的动画,按空格播放动画,确保三个动画都没问题。

image.png

8、导出glb格式的文件,文件->导出->glTF2.0(glb/gltf)

image.png

五、Three.js解析动画

1、通过console.log打印模型对象,观察里面的数据

有了上面导出的glb模型,用Three.js的GLTFLoader便可加载模型

loader.load( 'models/gltf/boy.glb', function ( gltf ) { console.log(gltf.scene); console.log(gltf.animations) })

gltf.scene

依次展开children对象,可以看到如下图所示的8个对象,其中一个是骨骼对象,7个是蒙皮对象(包括头发,头部,手,上身,下身,鞋子,围巾) image.png 这里的数据其实和blender集合里面的层级对应关系是一致的,也是八个,如下图:

image.png

gltf.animations

这里有三个动画,即t_pose,run,walk,与我们上面NLA轨道里面合入的动画也是一致的 image.png

image.png

2、通过model.traverse循环遍历对象,将后续需要用到的对象通过name,type等属性过滤出来,如头发对象,鞋子对象,骨骼对象

model.traverse( function ( object ) { if ( object.isMesh ) object.castShadow = true; if(object.name.toLowerCase().indexOf('hair') >= 0){ hair = object } if(object.name.toLowerCase().indexOf('shoe') >= 0){ shoe = object } if(object.type === 'Bone'){ bones[object.name] = object } } );

3、播放动画

创建一个AnimationMixer对象,循环gltf.anmations,通过clipAction方法将需要的动画剪辑出来放到一个变量里面,切换时只需要调用play方法便可播放动画,具体代码请看demo。

六、实现换发功能

1、原理

要实现换发功能,需要将头发做成材质,换发其实就是换材质,材质就是一张png图片外加颜色等属性融合在一起的东西。

2、使用blender的UV editing制作材质

image.png

如上图,在物体模式下,选择材质渲染模式,选择头发层级,点击类似啃了两口的圆饼图标,查看基础色,显示file1,这个file1其实就是原作者的png图片,切换到UV editing,把file1删掉,点击那个浅黄色的原点,选择纹理头像,点击新建,左边则会多出一个头发展开成平面的图形,点击图像->保存。

image.png

3、使用画图工具对材质图像进行修改,比如加几个五角星

image.png 4、material.map和material.color实现换发

关键代码:

var textureLoader = new THREE.TextureLoader(); let hairTexture = textureLoader.load("models/gltf/hair.png",function(img){ hair.material.map = img hair.material.color = {r:0.92,g:0.51,b:0.51} });

这里的color的rgb值是除于255后得到的值。

七、demo演示

在线预览: lwhappy.github.io/examples/we…

源码: github.com/lwhappy/lwh…

八、参考:

threejs.org/examples/#w…