• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            永遠也不完美的程序

            不斷學習,不斷實踐,不斷的重構……

            常用鏈接

            統計

            積分與排名

            好友鏈接

            最新評論

            骨骼動畫導論(轉)

            轉自http://blog.csai.cn/user1/261/archives/2008/28536.html

            先說明,這篇文章由我翻譯自Evan Pipho的<<Focus On 3D Models>>一書的內關于骨骼動畫第五章的內容,去掉了前面的說明和最后的Demo說明,包含了所有的理論內容,轉載請注明出處,謝謝!

            理解骨骼動畫

            骨骼動畫是使用骨頭來運動一個模型而不是通過手動編輯和移動每個頂點或面而實現的動畫.每個頂點被附著到一根骨頭(或有時是多根骨頭).一根骨頭或一個關節只是一組頂點的一個控制點.這些概念類似于我們身體里的關節,例如我們的膝關節或腕關節等.當骨頭運動時,每個附著在它上的頂點也跟著運動,如圖5.2顯示的那樣.甚至骨頭自身的運動也會導致其它骨頭的運動.這使得模型運動起來比較適當合理,因為在真實的生活中,身體的一部分運動會影響到身體的其它部分.所以,程序員需要能利用骨頭來計算單個頂點的變換.雖然這會帶來較多的工作量,可是結果證明這是值得的.

            <!--[if !vml]--><!--[endif]-->

            5.2 頂點動畫需要你移動每個頂點,而骨骼動畫使你只需移動模型中的一根骨頭,頂點將能隨之而變.

            骨骼動畫的優點

            骨格動畫比傳統的頂點變換型動畫有很多優點,正如你在前面章節里看到的那樣.

            首先,也是對于玩家最直觀的一點便是要增加真實感.基于骨骼運動的角色更趨于真實性,并常出現在比傳統模型要求和周圍事物有更強交互性的地方.要使模型更趨于運動真實性,則對基于骨骼的模型來說確是件簡單的事.在傳統的關鍵幀動畫中,游戲會在兩個位置中間進行線性插值.然而,在這種情況下,關節實際上并沒有旋轉,這對于生命體以旋轉方式運動會有問題.

            這對用戶而言,并不那么明顯,但對程序員來說,那樣的動畫是否占用了較少的存儲空間是非常重要的.用于代替為每幀動畫都存儲一組新的頂點,所有我們需要存儲的只是骨頭的旋轉和平移信息.這可以節省巨大的存儲空間,你僅僅只要加入骨頭頂點骨頭附著信息.

            這因骨骼動畫需要而多加的一點存儲空間可以用于保存更細致的模型,加入額外的支運動幀,或甚至可經適當改進后,用于游戲的其它地方.你能夠添加更多細節至游戲的世界中,改進A.I.來提供一個更刺激的游戲,或者加入一些很酷的東東或復活節彩蛋,而這些都是原來你很想加入卻因涉及空間問題而不能加入的.

            而另一個優點表現在那些創建游戲3D內容的美工上.一個好的骨骼動畫系統將縮減美工做模型動畫的時間.幾乎每一個好的動畫程序都已使用骨骼動畫來確保模型運動的過程從美工到程序員,再到游戲,最后到玩家的平滑過渡.這加速了游戲內容的創建過程,也確保了當模型被導出成游戲所使用的格式時沒有動畫或特征的失真.

            一個更長遠的優點是對程序員的另一個好處(這越來越好了,不是嗎?).因為骨骼的自由性,這使得你可以隨心所欲地實時定位它們,也可以實現在運行時創建動畫.就相當于提供了一個更多樣化的動畫庫.你甚至能夠讓游戲控制當身體碰到一個物體時的動作,或從一個斜坡上滑下來.這種技術是在玩的時候即時產生的,Unreal Tournament 2003’s Physics系統(http://www.epicgames.com)里就有這樣一個值得注意的例子.角色和模型在環境里面真實交互,包括從斜坡上滑下和靠在上面徐徐移動.

            骨骼動畫有一個缺點就是相對于傳統的關鍵幀動畫,它不容易被理解和實現.本章將幫助你緩解任何你對骨骼動畫的擔心.

            骨骼動畫的原理

            首先來看看你的手臂.將你的手臂在你胸前展開并觀察它.你的手臂有許多骨頭,兩根主要的大骨頭(two main ones),還有手掌(譯注:這里指腕關節到指尖的所有部分,下面說的手掌也一樣)和手指上的一些骨頭.

            移動你的手指,是不是它們移動?只移動你的手指,而你手臂上的其它部分并不會因此而移動.現在彎曲你的肘關節,不僅你的手臂移動了,而且你的手指和手掌也同樣跟著移動了.如果不是這樣的,那你的手臂和你的手掌及手指就變得斷開了,且每部分都孤立得懸掛在空中,這可不太好.

            如何將這個手臂和骨骼動畫關聯在一起運動呢?你的手臂代表了3D模型的一部分,你的手指,手掌,以及手臂的上下各部分都是這個模型的一部分.不同的關節和骨頭貫穿了你的手臂,如肩關節,肘關節,腕關節,還有指關節.

            這就是說,當你移動手臂上游的一根骨頭時,任何在這根骨頭的下游部分也都會跟著移動.這就是骨骼動畫最基本的概念.

            這樣就有一個美妙之處是:它可以允許你移動模型上的任何一根骨頭,并滲透到下面的移動,應用到以這個移動為原點的下面的任何事物. 例如,這允許你只需移動角色的肩膀,不需擔心肘和手的移動位置,因為它們會自動移到正確位置.你也能夠通過復位以確保它們會被自動更新.5.3顯示了一個關節和附著在這些關節上的頂點的例子.

            <!--[if !vml]--><!--[endif]-->

            5.3 當執行骨骼動畫時,你不必擔心關節,或骨頭之間的結合點.每個頂點實際上是附著(關聯)到關節點的,而不是骨頭.

            根關節

            根關節是一個模型中的終端關節.任何其它關節都以自己的路徑最終關聯到根關節.任何對根關節的操作,如不論是平移或是旋轉,都會影響到模型中的每個頂點.你可以認為根關節是控制所有其它關節的關節.簡單修改根關節,你能使角色直立行走,或旋轉他以讓他倒過來在天花板上行走所做的只是一個簡單的調用.

            在每個模型里只有一個根關節,它沒有父關節.根關節通常是許多骨頭連接的地方,而不是需要一個小動畫的地方.例如包括中部和下后部,但沒有明確要求根關節一定要在模型中的某個準確位置.只要你愿意,每個模型都可以不同.5.4顯示了當根節點的位置和朝向被修改后會發生的變化.

            <!--[if !vml]--><!--[endif]-->

            5.4 旋轉或平移根關節將影響模型中其他所有的關節和項點.

            先說明,這篇文章由我翻譯自Evan Pipho的<<Focus On 3D Models>>一書的內關于骨骼動畫第五章的內容,去掉了前面的說明和最后的Demo說明,包含了所有的理論內容,轉載請注明出處,謝謝!

            父關節和子關節

            一個關節可以有父關節和子關節.其父關節會影響到它做任何事情.父關節的旋轉和平移會影響計算當前關節的新位置.再拿手臂的例子來說,肘關節是手掌的父關節.移動肘則影響手掌.在簡單的骨骼動畫里,每個關節只有一個父關節,如果有的話.

            但是,一個關節可以有許多子關節.子關節是相對于父關節來說的.任何你對父關節做的事都會滲透到子關節.換個角度來說就是,當前關節是所有在它下面的關節的父關節.

            <!--[if !vml]--><!--[endif]-->

            5.5 -子關節的關系

            骨骼動畫的關鍵幀

            常規關鍵幀動畫保存了多份頂點拷貝,骨骼動畫系統也有關鍵幀.關鍵幀的再現是一個模型位置的瞬時狀態.

            然而,不同于每個關鍵幀都包含其自身所有頂點的拷貝的方式,骨骼動畫的關鍵幀或叫骨骼幀(boneframe)包含了旋轉和平移的變換信息,一般平移是一個X,Y,Z值的形式,和三個分別包含了按X,Y,Z軸旋轉的值.正如常規頂點關鍵幀一樣,這些骨骼幀必須被插值來提供平滑的動畫效果.

            位置或平移的值可以在兩個之間進行線性插值,就像你在傳統關鍵幀動畫里對頂點的操作一樣.但旋轉則有問題,簡單的在兩個值之間進行平移那樣的插值會產生奇怪的效果.旋轉將不是平滑的,它可能會加速和減速,這依賴于其自身的位置.如果兩個旋轉信息之間的差異比較大,模型可能像膠在一起的方塊那樣出現滲出(ooze)”.這是因為使用線性插值,所有的東西都是沿著直線插值的,如果這用這種方式執行旋轉就會產生奇怪的效果,因為旋轉是沿著弧插值而不是直線.對弧形路徑按兩端點的直線方式而不是沿弧的路徑方式就會產行滲出效果.

            解決這個問題的最好方法就是采用四元數.這你在第二章就學會過了.”介紹四元數”,四元數最大的優點之一是他們可以容易地進行插值.不僅容易插值,而且能很容易地進行球面線性插值.

            球面線性插值在球面上的兩點之前進行插值.然而,相對于在兩點之間以直線方式逼近,球面線性插值是沿著球表面的曲面的.你可以設想撿起一只球,比如一個籃球,并在上面標上兩點,然后,用你的手指找出這兩點間最短的路徑.因為你的手指不能進入球的內部,于是這條在兩點間的路徑將是一條弧.這就是SLERP的處理方式.使用SLERP函數,旋轉就可以沿著弧進行插值,創建出一個比較平滑的,順眼的效果.

            計算位置

            利用你在上面己經閱讀到的信息,你可能想嘗試實現骨骼動畫了.然而,你還沒有學習關于父關節是如何影響子關節的具體內容.簡單地使用關鍵幀將使每個關節獨立地移動,很可能產生一個奇怪的,扭曲的網格.

            這部分內容將告訴你關于如何更改它以使關節之間能正常運動.首先你要做的就是創建一個變換矩陣,該矩陣用于每一個使用了不同旋轉和平移關鍵幀數據(關鍵幀).這個變換矩陣可以通過先生成三個旋轉矩陣(譯注:x,y,z三個方向的旋轉矩陣)和平移矩陣,這在第一章已經學過了, 再將這三個矩陣相乘就會生成了最終的變換矩陣.你也可以使用matrix類的SetRotationSetTranslation函數來避免你自己做矩陣乘法.這個生成的矩陣叫做相對矩陣(relative matrix).

            下一步你需要計算出一個絕對矩陣(absolute matrix).絕對矩陣是關節的相對矩陣乘上它的父關節的絕對矩陣得到的.絕對矩陣告訴你關節的絕對變換(譯注:就是將關節的本地坐標變換為世界坐標).這包括了自身的相對變換,除此之外,層次結構中所有在它之前的關節的變換都已計算完成.這允許其他關節的移動作為移動關節鏈上游關節的結果.細想一下,例如,當你移動肩膀時肘又是怎么移動的,這引出了一個問題:你如何計算最初的絕對矩陣?記住,根關節是沒有父關節的,因此,它的絕對矩陣就是它的相對矩陣.

            假如你以正確的順序遍歷了各關節,同時按此順序計算出各個絕對矩陣,每個關節(的絕對矩陣)將會包含它父關節的變換,以及它父關節的父關節的變換等等.5.6顯示了當你變換一個關節前顧及所有先前(關節)的變換時發生的情況.

            <!--[if !vml]--><!--[endif]-->

            5.6 遍歷各關節,并顧及其所有前面的變換.注意哪怕只有一個關節要移動,在它下面的關節也得跟著移動,這很像移動你的臀部,則你的膝和踝也得跟著移動一樣.

            你是否只存儲了子關節的索引,而沒有儲存關節的父關節索引?你立即要訪問的索引集依賴于模型的格式.一些格式像MS3D同時給你每個關節的父關節索引,其它格式則可能給你子關節索引.使用子關節索引需要一個明顯不同于使用父索引的方法,但一點都不會比后者難.你再次從根關節開始,在計算了根關節的變換矩陣之后,通過一個類似于glPushMatrix的命令將一個新的矩陣壓入棧內.就創建了一個新的世界變換矩陣(world matrix)的拷貝,這個世界變換矩陣是在被顯示前執行了所有的幾何變換的矩陣.現在用你的新矩陣乘以根關節的本地矩陣.結果就是世界變換矩陣,它在下一個骨頭被畫出之前將所有事物放置到正確位置,父關節的變換也被考慮在內了.舉個例子,角色的臀部的旋轉可能是某些動作的總合.因為膝關節和踝關節是臀關節的子關節,它們也要被旋轉.

            繪制函數像這樣遞歸,它對自己的子關節繼續調用繪制函數,每個子關節又對自己的子關節調用渲染函數,以此類推直到到達終端關節(沒有子關節的關節),復位棧用一個glPopMatrix這樣的命令.例如,當要繪制一個角色的一條腿時,新的矩陣被壓入棧內用于計算膝關節,踝關節和腳關節.但是,如果要開始計算手臂時,你應該出格到處理腿之前的棧狀態,否則,每當你移動腿時,手臂也將跟著移動了.

            5.7顯示了一個遞歸渲染函數.

            <!--[if !vml]--><!--[endif]-->

            5.7 渲染用子索引代替父索引存儲的關節

            將網格附著到骨骼

            當你的關節己能平滑運動的時候,也是該將網格附著到骨骼的時候.網格(mesh)組成了模型的形狀,它是由一組使模型具有立體感和細節的頂點和三角形組成,沒有網格,基于骨骼運動的模型只是一個簡單的骨架.每個網格的頂點存儲了一個指向關節數組的索引,用于指示它被附著到某根骨頭.現在,存儲關節的方式決定了這些頂點的變換和渲染的方法.

            如果每個關節存儲時帶有其父關節的索引,同時你已經遍歷和計算了最終的絕對矩陣,那么附著網格是很簡單的.確保變換后的頂點保存到一個專門的地方,不要覆蓋原始的頂點.這是因為在絕大多數格式里,骨骼幀不會被累積,每幀保存了從起點起的特定關節的旋轉和平移的信息.如果你不回退到原始頂點,那么當每次計算新頂點位置時,模型將會飄乎不定得運動.5.8中可以看出每個頂點單獨附著到一個關節是什么意思.

            <!--[if !vml]--><!--[endif]-->

            5.8頂點附著到關節

             

            現在你很可能在對自己說,”好的,我能運動一個模型的頂點,那三角形,法線,以及紋理坐標怎么處理呢”? 這也正是骨骼模型真正開始閃光的地方.每個模型包含了一個紋理坐標的集合和一個三角形信息的集合.僅因為頂點的位置變更并不意味著三角形頂點索引和紋理坐標也會變化.這意思是說,當你第一次設置好它們之后就根本不需要再擔心它們.

            法線則是另一回事了,因為多邊形的朝向和頂點的位置更改了,因此法線也相應更改了.如果你正在使用面法線,那么你在每一幀將他們傳給渲染器之前都需要重新計算.然而,如果你一開始就計算了頂點法線,那么你很幸運,頂點法線不必在變換后都完全重新計算,它們能利用和頂點相同的變換矩陣來進行變換.唯一不同的是,你不需要考慮平移.使用matrix類的Transform3()函數將旋轉你的頂點法向量,同時仍能保留其原始大小.

            如果關節保存了子關節的索引,并且你使用glPushMatrix將當前的變換矩陣壓入棧內,那么渲染模型就會變得十分容易.對這種情況,沒有必要在顯示之前變換每個頂點.不管渲染任何東西都沒有更改的必要.任何你要渲染的現在將被適當變換,甚至面法線.另一個需要考慮的問題是,頂點如何附著到多于一根的骨頭.此時,每根骨頭將被賦予一個權重,這個權重決定它影響關節點的比重.最終的變換是所有這些被附著的骨頭的變換的加權平均.

            posted on 2010-01-18 10:57 狂爛球 閱讀(2474) 評論(0)  編輯 收藏 引用 所屬分類: 圖形編程

            久久精品国产亚洲7777| 国产精品一久久香蕉产线看| 久久天天躁狠狠躁夜夜av浪潮| 久久精品无码一区二区app| 日韩中文久久| 88久久精品无码一区二区毛片| 色综合久久中文字幕综合网| 大伊人青草狠狠久久| 久久嫩草影院免费看夜色| 91久久精一区二区三区大全| 一级做a爰片久久毛片看看| 久久久中文字幕| 日本欧美久久久久免费播放网| 久久综合成人网| 国产激情久久久久影院老熟女| 国内精品综合久久久40p| 7777久久久国产精品消防器材| 久久婷婷五月综合色奶水99啪| 青青青青久久精品国产| 国产亚洲精久久久久久无码77777| 久久99亚洲综合精品首页| 久久久久久a亚洲欧洲aⅴ| 久久婷婷五月综合色奶水99啪| 久久久久久久久66精品片| 久久久久国产一区二区 | 91精品国产91久久| 无码精品久久久天天影视| 久久久久久久免费视频| 久久久久国产精品麻豆AR影院| 69国产成人综合久久精品| 国产精品一区二区久久国产| 新狼窝色AV性久久久久久| 亚洲女久久久噜噜噜熟女| 国产精品久久久久久久久久影院 | 色欲久久久天天天综合网精品| 久久亚洲精品国产亚洲老地址 | A级毛片无码久久精品免费| 国产成人综合久久精品红| 无码人妻精品一区二区三区久久| 亚洲综合伊人久久大杳蕉| 久久精品国产清高在天天线|