Three.js變形動畫geometry.morphTargets

Three.js變形動畫geometry.morphTargets

本文是Three.js電子書的12.3節

關於變形動畫,你可以理解爲多組頂點數據,從一個狀態變化到另一個狀態,比如人的面部表情,哭的表情用一系列的頂點表示,笑的表情用一系列的頂點表示,從哭的表情過渡到笑的表情,就是表情對應的兩組頂點之間的過渡,幾何體的頂點的位置座標發生變化,從一個狀態過渡到另一個狀態自然就產生了變形動畫。

一般項目開發,變形動畫和骨骼動畫一樣,由3D美術編輯好變形動畫的模型數據,然後程序員通過Threejs相關的API解析渲染變形動畫。

爲了大家更好的理解變形動畫,下面通過Threejs程序編寫一個變形動畫,然後再解析渲染出來。

下面的變形動畫非常簡單,給一個長方體網格模型對象Mesh設置兩組頂點數據,然後從一組像另一組變化。

在這裏插入圖片描述

創建變形動畫的頂點數據

先獲取兩個變形目標box1box2的頂點數據,然後通過幾何體Geometry的變形目標屬性.morphTargets設置好變形動畫。

/**
 * 創建網格模型,並給模型的幾何體設置多個變形目標
 */
// 創建一個幾何體具有8個頂點
var geometry = new THREE.BoxGeometry(50, 50, 50); //立方體幾何對象
console.log(geometry.vertices);
// 爲geometry提供變形目標的數據
var box1 = new THREE.BoxGeometry(100, 5, 100); //爲變形目標1提供數據
var box2 = new THREE.BoxGeometry(5, 200, 5); //爲變形目標2提供數據
// 設置變形目標的數據
geometry.morphTargets[0] = {name: 'target1',vertices: box1.vertices};
geometry.morphTargets[1] = {name: 'target2',vertices: box2.vertices};
var material = new THREE.MeshLambertMaterial({
  morphTargets: true, //允許變形
  color: 0x0000ff
}); //材質對象
var mesh = new THREE.Mesh(geometry, material); //網格模型對象
scene.add(mesh); //網格模型添加到場景中

網格模型.morphTargetInfluences屬性

通過上面代碼把變形動畫頂點數據設置好以後,如果想生成變形動畫,首先要了解網格模型Mesh.morphTargetInfluences屬性。

你可以在上面代碼中分別或同時插入下面代碼進行測試,查看長方體網格模型mesh的外形變化。

//啓用變形目標並設置變形目標影響權重,範圍一般0~1
// 設置第一組頂點對幾何體形狀影響的變形係數
mesh.morphTargetInfluences[0] = 0.5;

// 設置第二組頂點對幾何體形狀影響的變形係數
mesh.morphTargetInfluences[1] = 1;

生成變形動畫

通過上面的測試,你可以發現改變morphTargetInfluences屬性的值可以改變網格模型的形狀,那麼回憶一下第11章講解的幀動畫,你只需要控制.morphTargetInfluences的屬性值生成關鍵幀數據,就可以實現關鍵幀動畫,然後播放關鍵幀動畫即可實現變形動畫。

第一步先利用關鍵幀KeyframeTrack、剪輯AnimationClip兩個類創建好幀動畫。

/**
 * 設置關鍵幀數據
 */
// 設置變形目標1對應權重隨着時間的變化
var Track1 = new THREE.KeyframeTrack('.morphTargetInfluences[0]', [0,10,20], [0,1, 0]);
// 設置變形目標2對應權重隨着時間的變化
var Track2 = new THREE.KeyframeTrack('.morphTargetInfluences[1]', [20,30, 40], [0, 1,0]);
// 創建一個剪輯clip對象,命名"default",持續時間40
var clip = new THREE.AnimationClip("default", 40, [Track1,Track2]);

第二步是使用混合器AnimationMixer播放設置好的關鍵幀動畫。

/**
 * 播放編輯好的關鍵幀數據
 */
var mixer = new THREE.AnimationMixer(mesh); //創建混合器
var AnimationAction = mixer.clipAction(clip); //返回動畫操作對象
AnimationAction.timeScale = 5; //默認1,可以調節播放速度
// AnimationAction.loop = THREE.LoopOnce; //不循環播放
// AnimationAction.clampWhenFinished=true;//暫停在最後一幀播放的狀態
AnimationAction.play(); //開始播放
...
...
// 創建一個時鐘對象Clock
var clock = new THREE.Clock();
// 渲染函數
function render() {
  renderer.render(scene, camera); //執行渲染操作
  requestAnimationFrame(render); //請求再次執行渲染函數render,渲染下一幀

  //clock.getDelta()方法獲得兩幀的時間間隔
  // 更新混合器相關的時間
  mixer.update(clock.getDelta());
}
render();
發佈了141 篇原創文章 · 獲贊 25 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章