第二十六章、燃烧吧!Three.js 小宇宙!(肆)

简介

在 Three.js 动画中我们可以透过以下三种方式来制作动画:

  • SkinnedMesh 骨骼蒙皮动画
  • Geometry.morphTargets 变形动画
  • 属性变化动画(光影 / 材质 / boolean运算)

同样的我们可以给予这几种动画属性开始与结束关键帧、中间动画过度帧,来串接动画。而这三种动画的帧数资料都是不一样的。

另外我们还可以透过先前在 Canvas 所提到的 requestAnimationFrame 以每秒 60帧 的速率在 render() 内更新动画。

而在 2015 年後,Three.js 大幅度的更新 Animation system,让整个动画系统更加接近 Unity 或 Unreal Engine 4 系统。接下来就让我们来聊聊 Three.js 的动画系统以及他的相关模组吧~

Animation Clips

AnimationClip(name, duration, tracks)
名称 说明
name 动画名称
duration 动画持续时间,若值为负数,传入时间将会由回传进阵列的数值计算
tracks 一组由 KeyframeTracks 回传数值的阵列

假设我们已经透过 glTF Blender exporter 将 animation 3D 物件,从 Blender 导出,并 用 GLTFLoader 将物件渲染到 Three.js 环境中。这一整个过程就包含了 Animation Clips

通常 Animation Clips 会保留物件的特定活动数据。举例来说:若有一个动画角色,那麽 Animation Clips 则会保存该动画叫角色的 「1. 走路周期 2. 跳耀动作 3. 回避动作」以此类推。

Keyframe Tracks

KeyframeTrack(name, times, values, interpolation)
名称 说明
name KeyframeTrack 名称
times 关键帧回传的阵列,其值会被计算转变为 Float32Array
values 由时间相关的值回传的阵列,其值会被计算转变为 Float32Array
interpolation KeyframeTrack 的一种插件值,预设值为 InterpolateLinear

在每一个 Animation Clips 会将每一个动画属性储存在 Keyframe Tracks 中。
Keyframe Tracks 中会有两个数值,time 按照顺序储存该 Tracks 的所有关键帧时间值、values 包含了动画属性相对的更改值。

举例来说:若有一动画角色拥有 Skeleton(骨架) 系统,那麽 会有一组 Keyframe Tracks 将会储存下臂骨架的位置变化数据、另一组 Keyframe Tracks 储存下臂骨架的旋转变化数据。

Animation Mixer

AnimationMixer(rootObject)
名称 说明
rootObject Mixer 所播放的动画物件

储存所有动画构成的数据,其行为不仅仅只是播放动画,而是真正的混合器控制台,可以同时混合多组动画。

Animation Actions

AnimationAction(mixer, clip, localRoot)
名称 说明
mixer 被 Animation Actions 所控制的混合器
clip Animation Clip 内所保存得动画片段
localRoot 动作执行的 root 物件

在官网文件上我们可以看到 Animation Mixer 比较没有 properties 或 methods,是因为我们都可以透过 Animation Actions 来控制。我们可以透过 Animation Actions 来决定播放、暂停、终止某个 Animation Clip,以及决定某个 Animation Clip 是否需要重复播放、播放频率、是否需要键入件出货时间延迟及其他动画属性。

要注意的是,我们应该要使用 AnimationMixer.clipAction 来实例化一组 Animation Actions 而不是直接呼叫该 function 来使用。因为这个方法提供了缓存以提高动画的性能。

Animation Object Groups

AnimationObjectGroup( obj1, obj2, obj3, ... )
名称 说明
obj 共享动画属性的物件

若我们需要将多个物件共享同一组动画属性,我们就可以使用 Animation Object Groups

我们将作为 root 物件传入的 constructor 或 AnimationMixer 的 clipAction method 先组成一个 Animation Object Groups 後,再将整组 Animation Object Groups 当作 root 物件传出去使用。

而这些动画属性都必须要让群组内的物件所兼容共用。

动画范例程序码

var mesh;

// 实例化 AnimationMixer,并且取得 AnimationClip 的instances
var mixer = new THREE.AnimationMixer( mesh );
var clips = mesh.animations;

// 在每一帧中更新 mixer
function update () {
	mixer.update( deltaSeconds );
}

// 播放 dance 这组动画
var clip = THREE.AnimationClip.findByName( clips, 'dance' );
var action = mixer.clipAction( clip );
action.play();

// 播放所有动画
clips.forEach( function ( clip ) {
	mixer.clipAction( clip ).play();
} );

由於 Three.js 动画在学习资源上较少,因此在官网更新时好像比较没有人有详细讲解 Three.js 得动画语法,因此在这边稍微介绍。

不知道大家对於今天的动画讲解有无疑问呢?也欢迎有研究 Three.js 动画的大大来互相交流一下呦!

那麽今天就先讲解到这边,我们明天见!


参考资料


<<:  Day27 laravel todolist 建立使用者群组

>>:  【Day 29】适合和 React 搭配的第三方套件

Day 22 | 状态管理套件 MobX - 基本使用

昨天稍微提到了状态管理及 MobX 的基本介绍那今天就要来说明 MobX 中的核心概念。 MobX ...

流程与制度 - 打造一个「人」的系统

谈过故事、人、与文化,我们要到最後的一个元素 — 流程与制度。最後来谈流程与制度,并不是因为他们不...

【Day 21】 实作 - 启用 AWS CloudFront 日志

前几天我们已经将 AWS VPC 日志启用并将其资料转换让 BI 工具可以进行视觉化仪表板的建置,那...

MSP430 在 linux 上的环境设定

如果是 debian 了话,要在 /etc/apt/source.list 加入 deb http:...

Unity自主学习(二十四):物件移动(3)

今天接着把物件移动写出来吧!昨天知道了Down和Up的差别之後,接下来就是要了解要将程序码写在哪里 ...