three.js 動畫系統(tǒng)

2023-02-16 17:24 更新

概述

在three.js動畫系統(tǒng)中,您可以為模型的各種屬性設置動畫: SkinnedMesh(蒙皮和裝配模型)的骨骼,morph targets(變形目標), 不同的材料屬性(顏色,不透明度,布爾運算),可見性和變換。動畫屬性可以淡入、淡出、交叉淡化和扭曲。 在相同或不同物體上同時發(fā)生的動畫的權(quán)重和時間比例的變化可以獨立地進行。 相同或不同物體的動畫也可以同步發(fā)生。

為了在一個同構(gòu)系統(tǒng)中實現(xiàn)所有這一切, three.js的動畫系統(tǒng)在2015年徹底改變(注意過時的信息!), 它現(xiàn)在有一個與Unity/虛幻4引擎類似的架構(gòu)。此頁面簡要闡述了這個系統(tǒng)中的主要組件以及它們?nèi)绾螀f(xié)同工作。

動畫片段(Animation Clips)

如果您已成功導入3D動畫對象(無論它是否有骨骼或變形目標或兩者皆有都不要緊)—— 例如使用glTF Blender exporter(glTF Blender導出器) 從Blender導出它并使用GLTFLoader將其加載到three.js場景中 —— 其中一個響應字段應該是一個名為“animations”的數(shù)組, 其中包含此模型的AnimationClips(請參閱下面可用的加載器列表)。

每個AnimationClip通常保存對象某個活動的數(shù)據(jù)。 舉個例子,假如mesh是一個角色,可能有一個AnimationClip實現(xiàn)步行循環(huán), 第二個AnimationClip實現(xiàn)跳躍,第三個AnimationClip實現(xiàn)閃避等等。

關(guān)鍵幀軌道(Keyframe Tracks)

在這樣的AnimationClip里面,每個動畫屬性的數(shù)據(jù)都存儲在一個單獨的KeyframeTrack中。 假設一個角色對象有Skeleton(骨架), 一個關(guān)鍵幀軌道可以存儲下臂骨骼位置隨時間變化的數(shù)據(jù), 另一個軌道追蹤同一塊骨骼的旋轉(zhuǎn)變化,第三個追蹤另外一塊骨骼的位置、轉(zhuǎn)角和尺寸,等等。 應該很清楚,AnimationClip可以由許多這樣的軌道組成。

假設模型具有morph Targets(變形目標)—— 例如一個變形目標顯示一個笑臉,另一個顯示憤怒的臉 —— 每個軌道都持有某個變形目標在AnimationClip運行期間產(chǎn)生的Mesh.morphTargetInfluences(變形目標影響)如何變化的信息。

動畫混合器(Animation Mixer)

存儲的數(shù)據(jù)僅構(gòu)成動畫的基礎 —— 實際播放由AnimationMixer控制。 你可以想象這不僅僅是動畫的播放器,而是作為硬件的模擬,如真正的調(diào)音臺,可以同時控制和混合若干動畫。

動畫行為(Animation Actions)

AnimationMixer本身只有很少的(大體上)屬性和方法, 因為它可以通過AnimationActions來控制。 通過配置AnimationAction,您可以決定何時播放、暫?;蛲V蛊渲幸粋€混合器中的某個AnimationClip, 這個AnimationClip是否需要重復播放以及重復的頻率, 是否需要使用淡入淡出或時間縮放,以及一些其他內(nèi)容(例如交叉漸變和同步)。

動畫對象組(Animation Object Groups)

如果您希望一組對象接收共享的動畫狀態(tài),則可以使用AnimationObjectGroup。

支持的格式和加載器(Supported Formats and Loaders)

請注意,并非所有模型格式都包含動畫(尤其是OBJ,沒有), 而且只有某些three.js加載器支持AnimationClip序列。 以下幾個確實支持此動畫類型:

請注意,3ds max和Maya當前無法直接導出多個動畫(這意味著動畫不是在同一時間線上)到一個文件中。

范例

let mesh;

// 新建一個AnimationMixer, 并取得AnimationClip實例列表
const mixer = new THREE.AnimationMixer( mesh );
const clips = mesh.animations;

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

// 播放一個特定的動畫
const clip = THREE.AnimationClip.findByName( clips, 'dance' );
const action = mixer.clipAction( clip );
action.play();

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


以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號