1. 程式人生 > >骨骼動畫原理和優化

骨骼動畫原理和優化

用Unity做遊戲經常會用到3D角色,也就會用到骨骼動畫。骨骼動畫對效能的影響其實非常大的,在說這個問題之前,先來說說骨骼動畫的原理。
我之前做過多種骨骼動畫,包括寫過2D的骨骼動畫系統(類似於現在比較流行的龍骨系統),也在flash的stage3D裡面寫過3D的骨骼模型動畫。骨骼動畫的原理實際上都是一樣的:
首先你需要有一個模型,2D或者3D的,這些模型是由頂點組成的,2d模型的頂點就是一個個四邊形的四個頂點,3D模型的頂點就是每個Mesh網格的三角面頂點。
然後,你需要搭建一套骨骼,這些骨骼是樹形結構的,也就是有父子連線關係的,父級骨骼在做運動的時候,子級骨骼是跟隨父級骨骼運動,在這個基礎上然後子級也可以自己運動而不影響父級骨骼。
接下來,你需要把模型的頂點和骨骼做一個對應關係,這就是所謂的蒙皮權重。蒙皮要做的事情,是指定某個頂點受到多少根骨骼的影響,然後在骨骼運動的時候,頂點根據權重的百分比來跟隨骨骼運動。比如一個頂點是受到了2跟骨骼的影響,第一根骨骼的權重是30%,第二根骨骼的權重是70%。在兩根骨骼同時移動的時候,第一根骨骼向左移動了10米,第二根骨骼向右移動了10米,假若向右是正方向,那麼這個頂點實際移動的位置應該就是-10*0.3+10*0.7 = 4,也就是向右移動了4米。在實際的計算中,我們不會這麼簡單的乘以百分比,是會用矩陣來運算,分別算出正常受到每一根骨骼矩陣影響之後該頂點的最終座標,然後再乘以百分比相加。
最後再來說說骨骼父子關係。每一個子級的骨骼,需要先獲取到它的父級,通過矩陣來轉換區域性座標系,算出子級相對父級的區域性位移旋轉縮放,再將座標系轉換到世界座標系,得到子級相對於父級的位移旋轉縮放在世界座標的實際位置,得到最終在動畫中這根子骨骼的實際座標。如果一個角色的骨骼數量越多,巢狀的父子關係越複雜,那麼這個轉換座標系計算的過程就越複雜,消耗的cpu運算就越多。

針對這個骨骼消耗的問題,歷代的遊戲引擎都有自己的解決辦法。比如很早期的魔獸爭霸3的模型動畫,是使用了頂點動畫的方式。這個做法具體是這樣的,首先在3d軟體裡面先做好模型的骨骼動畫,然後在匯出的時候,逐幀或者間隔多少幀的計算每個頂點在當前幀的實際座標,最後只匯出頂點的每幀座標資訊而不匯出骨骼資訊。
這個做法的優點是在遊戲執行的時候完全不需要計算骨骼的座標關係了,直接把所有頂點的當前幀座標讀取一遍,然後設定頂點座標就解決了。所以在當年模型的頂點數很少(一個角色模型300個三角面左右),角色是固定形態(不需要區域性換裝),幀率要求不高的情況下,這樣做極大的保證了遊戲的執行效率。
但這個做法的缺點也是很明顯的。隨著角色模型面數的增大,幀率的提高,匯出的動畫檔案就增大很多倍,然後由於沒有匯出骨骼資訊,所以也不能在骨骼動畫播放的過程中修改某個骨骼的資訊做到特殊的動畫效果(比如在揮拳的時候手可以根據目標的距離伸長之類),最後也是最嚴重的,失去了骨骼動畫一個基本的作用,就是動態蒙皮換裝,每套骨骼動畫資訊只能針對一個模型的。
之後我在做stage3D的骨骼動畫的時候,參考了一部分這個做法,進行了一下改進,改為匯入執行的時候,先計算出該骨骼動畫的每幀所有骨骼實際座標,然後存起來。這樣就不需要每幀計算父子矩陣關係,只需要直接蒙皮計算。這樣做,保證了匯出檔案的容量(畢竟flash頁遊還是很講究檔案大小),也能動態的蒙皮換裝,因為固定的只是骨骼,和模型沒有關係。不過這樣做還是不能在播放過程改變骨骼資訊做特殊效果。
說了這麼多,估計對骨骼動畫的原理已經有了一定的瞭解了。那麼接下來自然就想到了影響骨骼動畫播放的一些效率問題:
1、模型本身的頂點數
從蒙皮權重的角度可以看出,如果頂點越多,在播放時需要計算每個頂點最終座標的次數就越多。
2、模型骨骼的數量和複雜程度
從骨骼父子關係的計算可以知道,骨骼越多,計算矩陣座標系的次數就越多。

為了讓骨骼動畫流暢,一般來說,我們在遊戲裡面會規定角色模型的面數和骨骼數量。比如效果稍微好點的遊戲,主角3000面左右、小怪1000面左右之類的。然後骨骼數人形角色一般在30根左右。

在Unity引擎裡面,對於骨骼有一個優化的功能。下面舉一個實際例子說明:
我們匯入一個怪物模型,然後在Hierarchy面板,可以看到這個模型上面的所有骨骼。
這裡寫圖片描述
在project面板選擇剛才那個模型的原始fbx檔案,可以在Inspector面板看到模型匯入的設定引數,在Rig裡面有一個Optimize Game Objects的選項,把它勾上。
這裡寫圖片描述

再把模型拖到場景裡面。現在可以看到,模型下面只顯示了mesh網格,那些骨骼結構都沒有了。這時候播放,可以看到角色的動畫是可以正常播放的。
這裡寫圖片描述

這時候你會想到一個問題,如果我在某些骨骼上面加了一些控制的節點,比如我在手的骨骼上面綁了一個物體,用於武器繫結,那麼現在看不到骨骼了,不就不能這樣綁定了?其實還是有辦法的,再回到fbx匯入設定裡面:
這裡寫圖片描述
點右下角的加號,可以選擇一些你指定的骨骼排除在外,這些骨骼將不會被隱藏掉。

這裡寫圖片描述
這時候再把fbx拖到場景裡面,可以看到上面出現了我們剛才選擇的排除在外的骨骼。

這樣處理了之後,首先場景裡面不需要生成這麼多骨骼,場景物體數量就減少了很多了,然後Unity會幫你精簡骨骼計算的矩陣轉換(具體處理方式官方沒有說明,估計類似於我在Stage3D時的處理),這樣可以把骨骼動畫播放時的消耗降低。

相關推薦

骨骼動畫原理優化

用Unity做遊戲經常會用到3D角色,也就會用到骨骼動畫。骨骼動畫對效能的影響其實非常大的,在說這個問題之前,先來說說骨骼動畫的原理。 我之前做過多種骨骼動畫,包括寫過2D的骨骼動畫系統(類似於現在比較流行的龍骨系統),也在flash的stage3D裡

Nginx工作原理優化 漏洞

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

骨骼動畫原理

動畫相關理論詳解 一 、骨架 骨架由一系列具有層次關係的關節(骨骼)和關節鏈組成,是一種樹結構,選擇其中一個是根關節,其它關節是根關節的子孫,可以通過平移和旋轉根關節移動並確定整個骨架在世界空間中的位置和方向。父關節運動能影響子關節運動,但子關節運動對父關節不產生影響,因此,平移或旋轉父關節時,也會同時平

SYNPROXY抵禦DDoS攻擊的原理優化

                     序又到了週末,我又要必須寫點什麼了…  週末依然加班,感謝週末上班平日休息的老婆分擔了幾乎所有家務,一切依然…然而這些對我來講都不是個事兒,事實上我是希望取消一切節假日和週末的,所謂的週末和節假日是我一直以來覺得出自《聖經》裡面最荒唐的東西…休息時間為什麼要集中化,既

java 關於HashMap的工作原理優化

 相信大家都用過HashMap,但是可能一些新手不知它的工作原理從而導致HashMap的效能非常糟糕! 為什麼這麼說呢?效能非常好的HashMap是什麼情況下會導致效能下降那麼多呢? 首先來說說HashMap的工作原理吧: 工作原理: HashMap 是基於hashi

Lucene底層原理優化經驗分享(2)-Lucene優化經驗總結

  系統優化遵從木桶原理:一隻木桶能盛多少水,並不取決於最高的木板,而取決於最短的那塊木板。Lucene優化也一樣,找到效能瓶頸,找對解決方法,才能事半功倍,本文將從三方面闡述我們的Lucene優化經驗:   1. 找準方向 -> Lucene效能瓶頸分

Nginx 工作原理優化、漏洞

1.  Nginx的模組與工作原理 Nginx由核心和模組組成,其中,核心的設計非常微小和簡潔,完成的工作也非常簡單,僅僅通過查詢配置檔案將客戶端請求對映到一個location block(location是Nginx配置中的一個指令,用於URL匹配),而在這個location中所

骨骼動畫原理及簡單實現

骨骼動畫的含義,一句話,骨骼的朝向和位置,影響頂點的位置。 骨骼動畫的計算方法,一句話,頂點在骨骼空間裡的座標,不受骨骼本身變化影響。 因此,我們只要先將頂點從模型空間變換到骨骼空間,在骨骼發生旋轉位移後,再把骨骼空間的座標變換回模型空間即可。 這方面的詳細介紹已經有很多

jvm出現OutOfMemoryError時處理方法/jvm原理優化參考

The heap stores all of the objects created by your java program.The heap's contents is monitored by the garbage collector,which frees me

JVM原理優化

JVM工作原理和特點主要是指作業系統裝入JVM是通過jdk中Java.exe來完成,通過下面4步來完成JVM環境. 1.建立JVM裝載環境和配置 2.裝載JVM.dll 3.初始化JVM.dll並掛界到JNIENV(JNI呼叫介面)例項 4.呼叫JNIE

Fragment的原理優化

 fragment 管理框架升級到了 0.1.0, 添加了一個新的介面 startFragmentAndDestroyCurrent, 可以方便的完成類似 startActivity 之後 finish 的效果 FragmentTransition#addToBackSta

一個3D骨骼動畫 2D版超精簡Demo,原理實現幾乎同3D一致

以前看D3D的時候,就發現骨骼動畫是個有點難以掌握的東西。但是也可以說,骨骼動畫是3D齊次空間變換的集大成者,掌握了骨骼動畫,差不多3D空間變換你也就掌握了。其他所有的層級變換,基本上都不會脫離骨骼動畫需要你瞭解的東西。網上骨骼動畫的demo多如牛毛,我空間想象能力不行,看過無數資料都不大明白骨骼怎麼

layaAir引擎制作遊戲的圖集動畫、時間軸動畫骨骼動畫總結二

var 拖拽 資源 轉化 post 類型 amp 按鈕動畫 let 一、角色序列幀.ani動畫的制作 1、在項目管理器中創建動畫文件 2.創建動畫模板,編輯動效名稱 3.編輯序列幀動畫 .ani格式動畫的代碼控制 1.動畫加載loadAnmition() 2.播放與停止、動

索引原理SQL優化(轉載待整理)

索引的本質 MySQL官方對索引的定義為:索引(Index)是幫助MySQL高效獲取資料的資料結構。提取句子主幹,就可以得到索引的本質:索引是資料結構。 我們知道,資料庫查詢是資料庫的最主要功能之一。我們都希望查詢資料的速度能儘可能的快,因此資料庫系統的設計者會從查詢演算法的角度進行優化。最

Spark Shuffle原理Shuffle的問題解決優化

摘要: 1 shuffle原理   1.1 mapreduce的shuffle原理     1.1.1 map task端操作     1.1.2 reduce task端操作    1.2 spark現在的SortShuffleManager 2 Shuffle操作

資料結構演算法 | 氣泡排序演算法原理及實現優化

氣泡排序(Bubble Sort)是排序演算法裡面比較簡單的一個排序。它重複地走訪要排序的數列,一次比較兩個資料元素,如果順序不對則進行交換,並一直重複這樣的走訪操作,直到沒有要交換的資料元素為止。 氣泡排序的原理 為了更深入地理解氣泡排序的操作步驟,我們現在

資料結構演算法 | 插入排序演算法原理及實現優化

插入排序演算法是所有排序方法中最簡單的一種演算法,其主要的實現思想是將資料按照一定的順序一個一個的插入到有序的表中,最終得到的序列就是已經排序好的資料。 直接插入排序是插入排序演算法中的一種,採用的方法是:在新增新的記錄時,使用順序查詢的方式找到其要插入的位置,

排序演算法 | 希爾排序演算法原理及實現優化

希爾排序也是一種插入排序演算法,也叫作縮小增量排序,是直接插入排序的一種更高效的改進演算法。 希爾排序因其設計者希爾(Donald Shell)的名字而得名,該演算法在 1959 年被公佈。一些老版本的教科書和參考手冊把該演算法命名為 Shell-Metzner

資料結構演算法 | 歸併排序演算法原理及實現優化

歸併排序(MERGE-SORT)是建立在歸併操作上的一種有效的排序演算法,該演算法是採用分治法(Divide and Conquer)的一個非常典型的應用。將已有序的子序列合併,得到完全有序的序列;即先使每個子序列有序,再使子序列段間有序。 歸併排序的原理 歸

MySQL之索引原理慢查詢優化

1. 索引介紹 需求:   一般的應用系統,讀寫比例在10:1左右,而且插入操作和一般的更新操作很少出現效能問題,在生產環境中,我們遇到最多的,也是最容易出問題的,還是一些複雜的查詢操作,因此對查詢語句的優化顯然是重中之重。說起加速查詢,就不得不提到索引了。 索引:    簡單的說,相當於