從零開始學習OpenGL ES之九上 – 動畫基礎和關鍵幀動畫

最初這篇教程我並不打算作爲第9章發佈,原計劃是第10章。在深入瞭解Opengl ES 2.0 和着色器之前,我想討論下更基礎的:動畫。
注意:你可以在這裏找到這篇教程的配套代碼,新版本的代碼已經在西部時間10:14更新了,更新的代碼裏面修正了一個不能動畫的錯誤。

目前爲止,想必你已經看過了opengles最基本的動畫形式。通過隨時間改變rotate, translate, scale(旋轉、移動和縮放)等,我們就可以使物體“動起來”。我們的第一個項目 the spinning icosahedron就是這種動畫的一個例子。我們把這種動畫叫做簡單動畫。然而,不要被“簡單動畫”這個名稱迷糊,你可以實現複雜的動畫,只需要隨時間改變一下矩陣變換。

但是,如何掌握更加複雜的動畫呢?比如說你想讓一個人物行走或者表現一個被擠壓正要反彈的球。

實際上這並不困難。在OpenGL了裏面有兩種主要實現方法:關鍵幀動畫和骨骼動畫。在這章裏面我們談論關於幀動畫的話題,下一章(#9b)裏面,我們將要談論的是骨骼動畫。

Interpolation & Keys

動畫只不過是隨着時間改變每個頂點的位置。這是是動畫的本質。當你移動、旋轉或縮放一個物體的時候,你實際上是移動了一個物體的所有頂點。如果你想讓一個物體有一個更復雜、精細的動畫,你需要一個方法按設置時間移動每個頂點。

兩種動畫的基本原理是存儲物體關鍵位置的每一個頂點。在關鍵幀動畫中,我們存儲獨立關鍵位置的每一個頂點。而骨骼動畫,我們存儲虛擬骨骼的位置信息,並且用一些方法指定哪個骨骼會影響動作中的哪些頂點。

那麼什麼是關鍵幀?如果要最簡單的方法說明他們,我們還得回到他們的起源,傳統逐格動畫,如經典的迪斯尼和華納兄弟的卡通。早期的動畫,一個小的團隊就能完成所有的繪畫工作。但是隨着產品的慢慢變大,那變得不可能,他們不得不進行分工。比較有經驗的漫畫師成爲lead animator(有時叫關key animator)。這些有經驗的畫師並不畫出動畫的每一格,而是繪製更重要的幀。比如說一個極端的運動或姿勢,體現一個場景的本質。如果要表現一個人物投擲一個球的動畫,關鍵幀是手臂最後端時候的幀,手臂在弧線最頂端的幀,和人物釋放球體的幀。

然後,key animator會轉移到新場景 而 另一個in-betweener(有時叫rough in-betweener)會算出關鍵幀之間的時間間隔,並完成這些關鍵幀之間幀的繪畫。比如一個一秒鐘的投擲動畫,每秒12幀,他們需要指出怎樣在首席動畫師繪製的關鍵幀中間完成剩下的9幀。

三維關鍵幀動畫的概念也是一樣。你有動作中關鍵位置的頂點數據,然後插值算法擔當rough in-betweener的角色。插值將是你在三維動畫裏面用到的最簡單的數學算法。

或許我們看一個實際的例子會更明白一點。讓我們只關注一個頂點。在第一個關鍵幀,假設是在原點(0 ,0, 0)。第二個關鍵幀,假設那是在(5、5、5),並且在這兩個關鍵幀之間的時間間隔是五秒(爲了計算方便)。

動畫的一秒鐘,我們只需要表現出這一秒前後兩個頂點在每個座標軸上的變化。所以,在我們的例子中,兩個關鍵幀在x,y,z軸總共移動了5個單位(5減去0等於5)。一秒鐘的動畫走了1/5的路程,所以我們添加5的1/5到在第一關鍵幀的x,y,z軸上面,變成(1, 1, 1)。目前數值算出來的過程並不優雅,但是數學算法是一樣的。算出總距離,算出與第一關鍵幀之間流逝的時間比例,兩種相乘再加上第一關鍵幀的座標值。

這是最簡單的插值,叫線性插值,適用於大部分情況。更加複雜的算法,要權衡動畫的長度。例如在Core Animation中,提供了幾種"ease in", "ease out", or "ease in/out"等幾種選項。也許我們會在以後的文章中討論非線性插值。不過現在,爲了保持簡單易懂,我們繼續討論線性插值。你可以通過改變關鍵幀的數量和它們的時間間隔,完成絕大多數動畫。

Keyframe Animation in OpenGLES

讓我們看一個OpenGL中簡單動畫的例子。當一個傳統的手工繪畫師被訓練以後,他們做的第一件事情就是做一個能夠被擠壓的而且正在反彈的小球。這同樣適合我們,程序會像下面這樣:

讓我們用 Blender(或者任何你想用的3d程序,如果你有方法輸出vertex , normal data的數據用人工的方法。在這個例子裏面我會用Blender export script,它能生成一個有頂點數據的頭文件)創建一個球。
我開始在原點創建一多面體,並且重新命名爲Ball1,然後我保存這個文件。使用我的腳本渲染並且輸出ball1。你可以在這裏找到這個幀的渲染文件

現在,我們按另存爲(F2)保存一個Ball2.blend的副本。我重命名爲Ball2以便於輸出腳本使用不同的名字命名數據類型。接着點擊 tab鍵進入編輯模式,點擊A移動和縮放球體上的點,直到球體被壓扁。保存壓扁的球然後輸出到Ball2.h。 你可以在這裏找到壓扁的球的資料

到這裏,我們有兩個頭文件,每個文件裏面都包包含着我的動畫裏面要用到的每個幀的頂點數據。從my OpenGL ES template開始工作,我先在 GLViewControler.h定義了一些新的值,它能幫助我追蹤小球的運動。


原文地址:OpenGL ES 從零開始系列9a:動畫基礎和關鍵幀動畫

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章