Away3D骨骼動畫處理方法、Away3D骨骼優(yōu)化的多種嘗試及結(jié)果

用過Away3D的朋友估計都會發(fā)現(xiàn),在Away3D里面使用超過一定骨骼數(shù)量的角色,當場景里面角色的數(shù)量稍微多一點,整個場景就會很卡。
對于這個現(xiàn)象,我之前得出的結(jié)論是。Stage3D的VC緩存器數(shù)量的限制,造成了對需要占用VC的骨骼信息有限制。對于超過了限制數(shù)量的骨骼部分,Stage3D會把數(shù)據(jù)退回CPU計算。
這里存在幾個誤區(qū):
1、退回CPU的處理不是Stage3D做的,而是away3D本身做的。
原生的Stage3D對于超過能允許數(shù)量的骨骼,因為超出了128個vc,不會做其他處理,只會直接報錯:
ArgumentError: Error #3615: AGAL 驗證失敗: 程序大小小于 程序的最小長度。
2、不是部分的退回,是通過一個開關(guān)判斷是否需要退回,全部退回。
開關(guān)是變量usesCPU。一開始給材質(zhì)賦值的時候,會判斷該模型是否需要退回cpu計算。假如不需要,就全部推到GPU計算,即使沒有動畫信息的時候,頂點著色器也會使用蒙皮計算的一套。假如需要退回cpu計算,那么就不會再使用蒙皮動畫的頂點程序,而直接用最基礎(chǔ)的頂點程序計算。
在明白了這兩點之后,看看Away3D對這個是否超出長度的功能做了什么處理:
1、通過對AnimationSetBase.cancelGPUCompatibility斷點,發(fā)現(xiàn)了在SkeletonAnimator.testGPUCompatibility方法里面有檢查是否需要退回CPU的判斷。其判斷的條件是:
if (!_useCondensedIndices && (_forceCPU || _jointsPerVertex > 4 || pass.numUsedVertexConstants + _numJoints * 3 > 128))
可以看出:
除了_useCondensedIndices ==false,還需要
1._forceCPU == true
2.一個頂點受到大于4個骨骼的影響。
因為每個va只能存xyzw四個數(shù),按照Away3D的頂點著色器的處理,就只能最多一個頂點受到4根骨骼的影響。
3.已經(jīng)使用的Vc,加上骨骼占用的VC,要少于128個。
由于Away對于骨骼 Transform推入GPU的計算是三個基向量,也就是占用3個緩存器,所以需要 骨骼數(shù)*3
后兩個條件,出現(xiàn)了優(yōu)化的空間:
首先,一般頂點最多受到3根骨骼影響已經(jīng)很足夠了。超過4根的信息可以考慮判斷其影響大小,將超出的而且權(quán)重小的部分排除掉。
然后,可以考慮一下怎樣減少輸入的vc數(shù)量,把三個基向量看有沒有辦法變成2個四維向量分別傳入位移和旋轉(zhuǎn)信息。由于Away3D使用的md5動畫格式本身就沒有導出縮放的,所以在沒有自己再寫解析器的情況下,沒有必要處理縮放的信息。
2、對于沒有超出允許范圍的情況,Away3D會通過代碼解析器組成頂點程序,然后每幀推入骨骼的三個基向量給agal計算。
在SkeletonAnimator.setRenderState方法里面,把計算出的所有骨骼的信息(_globalMatrices)傳入GPU,_numJoints是骨骼的數(shù)量。vertexConstantOffset是VC偏移量。也就是說,在vertexConstantOffset之前是其他頂點程序需要的VC,從vertexConstantOffset開始往后的所有VC都是骨骼信息使用的。由于每根骨骼有三個基向量,所以是_numJoints*3。
所以最終推入GPU的數(shù)據(jù)是這樣的:
stage3DProxy._context3D.setProgramConstantsFromVector(Context3DProgramType.VERTEX, vertexConstantOffset, _globalMatrices, _numJoints*3);
3、對于返回cpu的情況,頂點程序是最簡單的m44 op,va0,vc0,不需要推送骨骼信息進入vc,
而是在SkeletonAnimator.setRenderState方法里面判斷了if (_animationSet.usesCPU),
然后在SkeletonAnimator.morphGeometry方法里面在CPU模擬了一次GPU里面逐個頂點分別乘以受到影響的骨骼的基向量再乘以權(quán)重最后相加的過程,求出了每個頂點在每一幀實際的位置坐標,然后返回。
如果角色多、頂點多的情況下,這個過程在CPU算明顯是超級大的負荷,難怪幾個人物就卡死了。
這里又出現(xiàn)了優(yōu)化點了,寧愿對美術(shù)資源進行限制,也不要用CPU來渲染。Away3D這個功能明顯是雞肋,只是為了做得全面,適應各種沒有限制的模型,沒有項目可行性。
Away3D骨骼優(yōu)化的多種嘗試及結(jié)果
之前針對stage3d支持骨骼數(shù)量的優(yōu)化方案,做出過2個可能性的分析:
1、減少vc的推送,把transform拆分成一個四元數(shù)和一個三維向量。
2、拆分模型網(wǎng)格,把超出的部分拆分后分別推送。
之后的這段時間,我對這兩種方法都做出了嘗試。接下來談一下結(jié)論:
第一種方法:
通過向VC推送四元數(shù)和三維向量,結(jié)合骨骼的bindpose矩陣,是可以算出頂點在動畫之后的位置。之前有位朋友評論說在agal里面不能用四元數(shù)計算。這個說法不能算錯,因為agal的確沒有提供直接的四元數(shù)計算。但假如對3d圖形數(shù)學熟悉的朋友,就可以直接把運算的公式在agal里面重現(xiàn)一下,就可以了。
這種做法的優(yōu)點是cpu計算實在很少,比如在解析動畫之后可以直接把動畫關(guān)鍵幀保存成四元數(shù)和三維向量。然后需要計算動畫的時候,直接獲取然后推送就行了。但缺點是公式在agal里面運算會比較麻煩,一條點積的公式,在agal里面就需要拆分成好幾行。而agal是有限制的,不能超過200行。我嘗試的每個點受4根骨骼影響的情況,生成的agal代碼已經(jīng)有192行了。這是比較危險的情況了。假如我們的代碼還需要做其他的處理,那么行數(shù)可能就不夠了。
第二種方法:
我進行的嘗試是把各個蒙皮模型的子模型的信息進行提取,獲取到該網(wǎng)格實際受到哪些骨骼的影響,然后推送vc的時候,只推受到影響的骨骼。
這樣做是從一個側(cè)面的解決這個問題。我們做人物模型的時候就不能整個模型合并完再一起蒙皮,必須單獨逐個部分的做,然后每個部分只蒙受到影響的骨骼。
這樣做的結(jié)果是只要每個部位蒙皮的骨骼不超過一定量,整個人物就可以支持很多很多的骨骼。
不過這樣做也是有缺點的。由于是把模型拆分了,所以本來每個人物每一幀只需要獲取一次的骨骼信息,就變成要獲取多次了。這樣就變成加大了cpu的運算量。而且由于模型數(shù)量多了,渲染的實際次數(shù)也多了。
對于這種情況,我稍微優(yōu)化了一下提取信息的方法,讓他還是同一個角色同一幀只獲取一次骨骼信息。
在沒優(yōu)化之前,由于超出骨骼數(shù)量會退回cpu運算,一個2000多面的角色帶有40多根骨骼,away3d只能同屏運算10個左右就掉幀了?,F(xiàn)在同樣的面數(shù)和骨骼的人物,可以支持同屏80-90個左右而保持在30幀。
對于這個優(yōu)化結(jié)果,我覺得還是不能實際的應用在項目中?;蛘呶疫€是需要在很多地方找一下優(yōu)化的可能性。因為在沒有優(yōu)化之前,對于2000多面的角色,但骨骼減少到20多根的情況下,同屏是可以跑100個而保持30幀的。如果是湊合著來做項目的情況下,其實直接讓美工減少骨骼數(shù)量會是更快的解決方法。不過這樣做,游戲的效果就被限制得很厲害了,很多好看的效果和服裝就表現(xiàn)不出來了。
相關(guān)文章
只需3步! DeepSeek配合Xmind自動生成思維導圖詳細指南
最近,DeepSeek可謂是風靡全網(wǎng),無數(shù)小伙伴體驗后都贊不絕口,直呼太好用了!不過,很多小伙伴也提出了一個很實用的問題:如何結(jié)合XMind打造思維導圖的超酷組合?詳細請看2025-02-25- 很多朋友在問美圖秀秀模板拼圖白色邊框怎么去掉,其實方法很簡單哦,下面我們分享兩種方法,詳細入下2025-01-22
- Blender作為一款強大的3D建模軟件,內(nèi)置了許多實用的小技巧,讓創(chuàng)作過程更加高效,以下是其中10個不可或缺的快捷操作,詳細請看下文介紹2024-10-17
用Blender手搓P(guān)S5 Pro? 從建模到渲染的全攻略
索尼推出的PS5 Pro引發(fā)了游戲圈的熱議,盡管其昂貴的價格備受爭議,但妥妥的科技魅力吸引了大批玩家的關(guān)注,今天,我們就來探討如何使用Blender這款免費開源的3D建模軟件,2024-10-17- 圖案填充是一種常用的功能,用于在指定區(qū)域內(nèi)填充不同的圖案或顏色,以增強圖形的可讀性和美觀度,本文將詳細介紹如何在CAD中進行圖案填充操作2024-10-02
cad怎么畫逼真的草莓模型? 浩辰cad建模三維立體3D草莓的技巧
很喜歡吃草莓,想要使用cad建模一款立體漂亮且逼真的草莓模型,該怎么建模呢?下面我們就來看看cad畫草莓的方法2024-10-02怎能用cad設(shè)計玫瑰花和愛心圖案? 浩辰CAD建模玫瑰與愛心的技巧
很喜歡玫瑰與愛心,想要自己設(shè)計一款唯一的圖紙送給那個ta,該怎么繪制呢?下面我們就來看看使用浩辰cad繪制愛心和玫瑰的技巧2024-10-023D標準件螺栓太長或太短怎么辦? 浩辰cad調(diào)整3d標準件螺栓長短的技巧
cad圖紙繪制的時候,直接插入3D標準件螺栓發(fā)現(xiàn)長度不合適,該怎么調(diào)節(jié)長短呢?下面我們就來看看使用浩辰cad調(diào)整3d標準件螺栓長短的技巧2024-10-02用浩辰CAD如何畫立交橋? 一文講透CAD立交橋設(shè)計技巧
隨著計算機技術(shù)的不斷發(fā)展,CAD軟件已經(jīng)成為道路橋梁設(shè)計中不可或缺的工具,如何用CAD軟件畫立交橋呢?浩辰CAD這兩個步驟幫你輕松搞定2024-10-02CAD工程圖丟失鏈接怎么辦? 浩辰cad高效重新鏈接參考的解決技巧
浩辰cad中的工程圖紙丟失了參考鏈接,該怎么重新找回呢?下面我們就來看看參考鏈接丟失原因以及解決辦法2024-09-30