iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 27
0
Modern Web

網頁阿尼尛,到底是在幹尛?系列 第 27

第二十六章、燃燒吧!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 動畫的大大來互相交流一下呦!

那麼今天就先講解到這邊,我們明天見!


參考資料


上一篇
第二十五章、燃燒吧!Three.js 小宇宙!(參)
下一篇
第二十七章、燃燒吧!Three.js 小宇宙!(伍)
系列文
網頁阿尼尛,到底是在幹尛?30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言