11 Animation动画
這些天有些忙,導(dǎo)致一個(gè)多星期沒有更新文章,群里的小伙伴也天天催我更。為了表示歉意,我決定在現(xiàn)在的基礎(chǔ)上面增加一節(jié)Three.js核心類的相關(guān)介紹,來讓讓小伙伴們能更清楚的了解相關(guān)的基礎(chǔ)內(nèi)容。下面我們開始這一節(jié)的內(nèi)容,動(dòng)畫。
動(dòng)畫一般可以定義兩種:一種是變形動(dòng)畫,另一種是骨骼動(dòng)畫。下面,我們先介紹一下變形動(dòng)畫。
變形動(dòng)畫
變形動(dòng)畫的實(shí)現(xiàn)就是通過修改當(dāng)前模型的頂點(diǎn)位置來實(shí)現(xiàn)動(dòng)畫。就比如,一個(gè)動(dòng)畫需要變動(dòng)十次才可以實(shí)現(xiàn),那么我們就需要為當(dāng)前模型的每一個(gè)頂點(diǎn)定義每一次所在的位置,Three.js通過每一次修改實(shí)現(xiàn)最后的一個(gè)動(dòng)畫的整個(gè)流程。
為了更好的理解變形動(dòng)畫,我們創(chuàng)建了一個(gè)案例,查看地址為:點(diǎn)擊這里
這個(gè)案例是為了讓我們更好的了解變形動(dòng)畫的實(shí)現(xiàn)以及使用。在右上角,我們能發(fā)現(xiàn)兩個(gè)可切換的拖拽條,這兩個(gè)拖拽條對應(yīng)的是兩個(gè)變形目標(biāo)數(shù)組,拖拽范圍是0-1,就是當(dāng)前的變形目標(biāo)對本體的影響程度。我們進(jìn)行拖拽就可以發(fā)現(xiàn),界面中的立方體也會跟隨著變動(dòng),影響當(dāng)前的立方體。接下來我講解一下,當(dāng)前案例是如何實(shí)現(xiàn)的:
- 首先,在我們創(chuàng)建模型的幾何體時(shí),給幾何體morphTargets賦值了兩個(gè)變形目標(biāo),morphTargets是一個(gè)數(shù)組,這意味著我們可以增加很多的變形目標(biāo),在給morphTargets添加的數(shù)組,我們需要自己定義一個(gè)名稱和相關(guān)的頂點(diǎn),這個(gè)頂點(diǎn)數(shù)據(jù)必須和默認(rèn)的模型的頂點(diǎn)數(shù)據(jù)保持一致,設(shè)置完后,我們需要調(diào)用geometry的computeMorphNormals()來更新:
- 然后,當(dāng)前模型使用的材質(zhì)必須設(shè)置可以使用變形目標(biāo)變形:
- 當(dāng)我們創(chuàng)建好網(wǎng)格模型添加到場景內(nèi)后,可以在mesh對象上面找到morphTargetInfluences這一個(gè)配置項(xiàng),這里面也是一個(gè)數(shù)組,是和geometry的morphTargets相對應(yīng)的,主要就是用于設(shè)置當(dāng)前的變形目標(biāo)對本體的影響度,默認(rèn)值為0-1,0為不影響本體,1為完全影響本體:
通過上面我們手動(dòng)實(shí)現(xiàn)了一個(gè)變形動(dòng)畫,就會發(fā)現(xiàn),其實(shí)變形動(dòng)畫是一直在修改變形目標(biāo)對本體的影響尺度。我們可以通過這個(gè)原理實(shí)現(xiàn)一些變形動(dòng)畫。
當(dāng)前案例代碼查看地址:點(diǎn)擊這里
骨骼動(dòng)畫
骨骼動(dòng)畫是需要生成一個(gè)與模型相關(guān)的骨架,骨架中的骨骼也會存在對應(yīng)關(guān)系,模型的每一個(gè)需要?jiǎng)赢嫷捻旤c(diǎn)需要設(shè)置影響它的骨骼以及骨骼影響頂點(diǎn)的程度。骨骼動(dòng)畫和變形動(dòng)畫相比會比較復(fù)雜一些,但是它又有更多的靈活性。我們可以想象一下人體的骨骼,如果使用變形動(dòng)畫,需要把所有的每一次的變動(dòng)都存一個(gè)頂點(diǎn)數(shù)組,而骨骼動(dòng)畫,只需要設(shè)置骨骼的相關(guān)信息,就可以實(shí)現(xiàn)更多的動(dòng)畫。下面我們看一下骨骼動(dòng)畫的簡單案例:點(diǎn)擊這里
這是一個(gè)官方提供的案例,我經(jīng)過一些簡單的修改,也將當(dāng)前一個(gè)柱形圖形的骨骼顯示的出來,這個(gè)實(shí)現(xiàn)比較復(fù)雜,我們需要做的就是先理解它是怎么實(shí)現(xiàn)的:
- 首先, 我們創(chuàng)建了一個(gè)圓柱幾何體,然后通過圓柱的幾何體每一個(gè)頂點(diǎn)的y軸坐標(biāo)來設(shè)置需要綁定的骨骼的下標(biāo)和影響的程度:
幾何體的skinIndices屬性和skinWeights屬性就是來設(shè)置相關(guān)的綁定下標(biāo)和權(quán)重(骨骼影響程度)。
- 相應(yīng)的,我們需要設(shè)置一組相關(guān)的骨骼,骨骼具有嵌套關(guān)系,這樣才能實(shí)現(xiàn)一個(gè)骨架,由于圓柱體比較簡單,我們就創(chuàng)建一條骨骼垂直嵌套的骨骼:
- 創(chuàng)建紋理時(shí),我們還需要設(shè)置當(dāng)前紋理需要受到骨骼的影響,將材質(zhì)的skinning屬性設(shè)置為true:
- 最后,我們需要?jiǎng)?chuàng)建骨骼材質(zhì),并將模型綁定骨骼:
這樣,我們就實(shí)現(xiàn)了使用Three.js創(chuàng)建一個(gè)簡單的骨骼動(dòng)畫。使用dat.gui我們能夠修改每一個(gè)骨骼的poisition、rotation和scale并查看對當(dāng)前模型的影響。案例的源碼地址:點(diǎn)擊這里
兩種動(dòng)畫的區(qū)別
變形動(dòng)畫主要用于精度要求高的動(dòng)畫,比如人物的面部表情。優(yōu)點(diǎn)是動(dòng)畫表達(dá)會很到位,缺點(diǎn)就是擴(kuò)展性不強(qiáng),只能執(zhí)行設(shè)置好的相關(guān)動(dòng)畫。
骨骼動(dòng)畫主要用于那種精度要求低,而且需要豐富多樣的動(dòng)畫,就比如人物的走動(dòng),攻擊防御等動(dòng)畫,我們可以通過一套骨骼,修改相應(yīng)骨骼的位置的信息直接實(shí)現(xiàn)相應(yīng)的效果。確定是沒有變形動(dòng)畫的精度高,但是可以實(shí)現(xiàn)多種多樣的效果。
總結(jié):我們可以根據(jù)項(xiàng)目的需求來設(shè)置不同的動(dòng)畫,就比如一個(gè)人物模型,說話我們使用變形動(dòng)畫去實(shí)現(xiàn),而肢體動(dòng)作使用骨骼動(dòng)畫去實(shí)現(xiàn)。
導(dǎo)入模型動(dòng)畫
在Three.js的動(dòng)畫系統(tǒng)中,你可以為模型的各種屬性設(shè)置動(dòng)畫:骨骼動(dòng)畫,變形動(dòng)畫,材質(zhì)的相關(guān)屬性(顏色,透明度, 是否可見)。動(dòng)畫屬性可以設(shè)置淡入淡出效果以及各種扭曲特效。也可以單獨(dú)的改變一個(gè)對象或者多個(gè)對象上的動(dòng)畫的影響程度和動(dòng)畫時(shí)間。
為了實(shí)現(xiàn)這些,Three.js動(dòng)畫系統(tǒng)在2015年修改為了一個(gè)類似于Unity和虛幻引擎4的架構(gòu)。接下來我們了解一下這套動(dòng)畫系統(tǒng)的主要組件以及它們時(shí)如何協(xié)同工作。
動(dòng)畫片段(Animation Clips)
在我們成功導(dǎo)入模型以后,如果模型擁有相關(guān)的動(dòng)畫屬性,會在返回的模型數(shù)據(jù)中產(chǎn)生一個(gè)名為animations的數(shù)組,數(shù)組的每一個(gè)子項(xiàng)都是一個(gè)AnimationClips對象。
每一個(gè)單獨(dú)AnimationClips對象通常保存的都是模型的一個(gè)動(dòng)畫的數(shù)據(jù),假如,如果模型網(wǎng)格是一個(gè)人物角色,第一個(gè)AnimationClips對象有可能保存的是人物走動(dòng)的動(dòng)畫,第二個(gè)AnimationClips對象用于跳躍,第三個(gè)用于攻擊動(dòng)畫等等。
關(guān)鍵幀軌跡(Keyframe Tracks)
在AnimationClips對象內(nèi)部,一般會有四個(gè)屬性:
- name:當(dāng)前的動(dòng)畫的一個(gè)名稱
- uuid:一個(gè)不會重復(fù)的uuid
- duration:當(dāng)前動(dòng)畫一個(gè)循環(huán)所需要的時(shí)間
- tracks:軌跡當(dāng)前動(dòng)畫每一次切換動(dòng)作所需要的數(shù)據(jù)
假設(shè)當(dāng)前的動(dòng)畫是骨骼動(dòng)畫,在關(guān)鍵幀軌跡中存儲的數(shù)據(jù)是在每一幀骨骼隨著時(shí)間變動(dòng)的數(shù)據(jù)(位置,旋轉(zhuǎn)和縮放等)。
如果當(dāng)前動(dòng)畫是一個(gè)變形動(dòng)畫,在關(guān)鍵幀軌跡中將會把頂點(diǎn)數(shù)據(jù)的變動(dòng)存儲在其中(比如實(shí)現(xiàn)人臉的笑以及哭等動(dòng)作)。
動(dòng)畫混合器(Animation Mixer)
在動(dòng)畫片段中存儲的數(shù)據(jù)僅僅構(gòu)成了動(dòng)畫實(shí)現(xiàn)的基礎(chǔ),實(shí)際的播放權(quán)力在動(dòng)畫混合器的手中。你可以想象動(dòng)畫混合器其實(shí)不僅僅只是作為動(dòng)畫的播放器,它還可以同時(shí)控制幾個(gè)動(dòng)畫,混合它們或者合并它們。
動(dòng)畫播放器(Animation Actions)
這個(gè)英文我更樂意將它翻譯成動(dòng)畫播放器,因?yàn)槲覀冏罱K需要將數(shù)據(jù)生成一個(gè)動(dòng)畫播放器來操作當(dāng)前的動(dòng)畫執(zhí)行,暫停或者停止,是否使用淡入淡出效果或者將動(dòng)畫加快或減慢。
動(dòng)畫對象組(Animation Object Groups)
如果你希望一組模型對象共享當(dāng)前的動(dòng)畫,我們可以使用動(dòng)畫對象組來實(shí)現(xiàn)。
通過導(dǎo)入模型顯示動(dòng)畫
變形動(dòng)畫
我們首先查看一個(gè)官方的模型案例,這個(gè)案例效果是一匹馬奔跑的動(dòng)畫,我們也可以通過下面地址查看:點(diǎn)擊這里
接下來我們看一下這匹馬是如何實(shí)現(xiàn)的:
- 在模型加載成功以后,我們首先將模型創(chuàng)建出來,并將材質(zhì)的morphTargets設(shè)置為ture,可以使用變形動(dòng)畫:
- 然后我們創(chuàng)建了一個(gè)針對于該模型的混合器:
- 接著使用變形目標(biāo)數(shù)據(jù)創(chuàng)建一個(gè)動(dòng)畫片段:
- 使用混合器和動(dòng)畫片段創(chuàng)建一個(gè)動(dòng)畫播放器來播放:
- 最后,我們還需要在重新繪制循環(huán)中更新混合器,進(jìn)行動(dòng)作更新:
骨骼動(dòng)畫
骨骼動(dòng)畫模型我們使用的是gltf格式,這個(gè)模型是在Sketchfab網(wǎng)站下載,案例是一個(gè)小姐姐跳舞的一個(gè)片段,查看地址:點(diǎn)擊這里
gltf格式的模型導(dǎo)入進(jìn)來以后,我們可以直接通過animations數(shù)組創(chuàng)建播放器:
直接調(diào)用播放器的播放事件讓動(dòng)畫播放:
action.play();最后,我們還是需要在循環(huán)渲染中更新混合器,并將每一幀渲染的間隔時(shí)間傳入
function render() {control.update();var time = clock.getDelta();if (mixer) {mixer.update(time);}renderer.render(scene, camera); }總結(jié)
以上是生活随笔為你收集整理的11 Animation动画的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Java学习day08--方法引用和St
- 下一篇: 转换接头PL8000V-B 0-70MP