stage3d 骨骼优化
用過Away3D的朋友估計(jì)都會(huì)發(fā)現(xiàn),,在Away3D里面使用超過一定骨骼數(shù)量的角色,當(dāng)場景里面角色的數(shù)量稍微多一點(diǎn),整個(gè)場景就會(huì)很卡。 對于這個(gè)現(xiàn)象,我之前得出的結(jié)論是。Stage3D的VC緩存器數(shù)量的限制,造成了對需要占用VC的骨骼信息有限制。對于超過了限制數(shù)量的骨骼部分,Stage3D會(huì)把數(shù)據(jù)退回CPU計(jì)算。 這里存在幾個(gè)誤區(qū): 1、退回CPU的處理不是Stage3D做的,而是away3D本身做的。 原生的Stage3D對于超過能允許數(shù)量的骨骼,因?yàn)槌隽?28個(gè)vc,不會(huì)做其他處理,只會(huì)直接報(bào)錯(cuò): ArgumentError: Error #3615: AGAL 驗(yàn)證失敗: 程序大小小于? 程序的最小長度。 2、不是部分的退回,是通過一個(gè)開關(guān)判斷是否需要退回,全部退回。 開關(guān)是變量usesCPU。一開始給材質(zhì)賦值的時(shí)候,會(huì)判斷該模型是否需要退回cpu計(jì)算。假如不需要,就全部推到GPU計(jì)算,即使沒有動(dòng)畫信息的時(shí)候,頂點(diǎn)著色器也會(huì)使用蒙皮計(jì)算的一套。假如需要退回cpu計(jì)算,那么就不會(huì)再使用蒙皮動(dòng)畫的頂點(diǎn)程序,而直接用最根基的頂點(diǎn)程序計(jì)算。 在明白了這兩點(diǎn)之后,看看Away3D對這個(gè)是否超出長度的功能做了什么處理: 1、通過對AnimationSetBase.cancelGPUCompatibility斷點(diǎn),發(fā)現(xiàn)了在SkeletonAnimator.testGPUCompatibility法子里面有檢查是否需要退回CPU的判斷。其判斷的條件是: if (!_useCondensedIndices && (_forceCPU || _jointsPerVertex > 4 || pass.numUsedVertexConstants + _numJoints * 3 > 128)) 可以看出: 除了_useCondensedIndices ==false,還需要 1._forceCPU == true 2.一個(gè)頂點(diǎn)受到大于4個(gè)骨骼的影響。 因?yàn)槊總€(gè)va只能存xyzw四個(gè)數(shù),按照Away3D的頂點(diǎn)著色器的處理,就只能最多一個(gè)頂點(diǎn)受到4根骨骼的影響。 3.已經(jīng)使用的Vc,加上骨骼占用的VC,要少于128個(gè)。 由于Away對于骨骼 Transform推入GPU的計(jì)算是三個(gè)基向量,也就是占用3個(gè)緩存器,所以需要 骨骼數(shù)*3 后兩個(gè)條件,出現(xiàn)了優(yōu)化的空間: 首先,一般頂點(diǎn)最多受到3根骨骼影響已經(jīng)很足夠了。超過4根的信息可以考慮判斷其影響大小,將超出的而且權(quán)重小的部分排除掉。 然后,可以考慮一下怎樣減少輸入的vc數(shù)量,把三個(gè)基向量看有沒有辦法變成2個(gè)四維向量分別傳入位移和旋轉(zhuǎn)信息。由于Away3D使用的md5動(dòng)畫款式本身就沒有導(dǎo)出縮放的,所以在沒有自己再寫解析器的情況下,沒有必要處理縮放的信息。 2、對于沒有超出允許范圍的情況,Away3D會(huì)通過代碼解析器組成頂點(diǎn)程序,然后每幀推入骨骼的三個(gè)基向量給agal計(jì)算。 在SkeletonAnimator.setRenderState法子里面,把計(jì)算出的所有骨骼的信息(_globalMatrices)傳入GPU,_numJoints是骨骼的數(shù)量。vertexConstantOffset是VC偏移量。也就是說,在vertexConstantOffset之前是其他頂點(diǎn)程序需要的VC,從vertexConstantOffset開始往后的所有VC都是骨骼信息使用的。由于每根骨骼有三個(gè)基向量,所以是_numJoints*3。 所以最終推入GPU的數(shù)據(jù)是這樣的: stage3DProxy._context3D.setProgramConstantsFromVector(Context3DProgramType.VERTEX, vertexConstantOffset, _globalMatrices, _numJoints*3); 3、對于返回cpu的情況,頂點(diǎn)程序是最簡單的m44 op,va0,vc0,不需要推送骨骼信息進(jìn)入vc, 而是在SkeletonAnimator.setRenderState法子里面判斷了if (_animationSet.usesCPU), 然后在SkeletonAnimator.morphGeometry法子里面在CPU模擬了一次GPU里面逐個(gè)頂點(diǎn)分別乘以受到影響的骨骼的基向量再乘以權(quán)重最后相加的過程,求出了每個(gè)頂點(diǎn)在每一幀實(shí)際的位置坐標(biāo),然后返回。 如果角色多、頂點(diǎn)多的情況下,這個(gè)過程在CPU算明顯是超級(jí)大的負(fù)荷,難怪幾個(gè)人物就卡死了。 這里又出現(xiàn)了優(yōu)化點(diǎn)了,寧愿對美術(shù)資源進(jìn)行限制,也不要用CPU來渲染。Away3D這個(gè)功能明顯是雞肋,只是為了做得全面,適應(yīng)各種沒有限制的模型,沒有項(xiàng)目可行性。 Away3D骨骼優(yōu)化的多種嘗試及結(jié)果
之前針對stage3d支持骨骼數(shù)量的優(yōu)化方案,做出過2個(gè)可能性的分析: 1、減少vc的推送,把transform拆分成一個(gè)四元數(shù)和一個(gè)三維向量。 2、拆分模型網(wǎng)格,把超出的部分拆分后分別推送。 之后的這段時(shí)間,我對這兩種法子都做出了嘗試。接下來談一下結(jié)論: 第一種法子: 通過向VC推送四元數(shù)和三維向量,結(jié)合骨骼的bindpose矩陣,是可以算出頂點(diǎn)在動(dòng)畫之后的位置。之前有位朋友評(píng)論說在agal里面不能用四元數(shù)計(jì)算。這個(gè)說法不能算錯(cuò),因?yàn)閍gal的確沒有供給直接的四元數(shù)計(jì)算。但假如對3d圖形數(shù)學(xué)熟悉的朋友,就可以直接把運(yùn)算的公式在agal里面重現(xiàn)一下,就可以了。 這種做法的優(yōu)點(diǎn)是cpu計(jì)算實(shí)在很少,比如在解析動(dòng)畫之后可以直接把動(dòng)畫關(guān)鍵幀保存成四元數(shù)和三維向量。然后需要計(jì)算動(dòng)畫的時(shí)候,直接獲取然后推送就行了。但缺點(diǎn)是公式在agal里面運(yùn)算會(huì)比較麻煩,一條點(diǎn)積的公式,在agal里面就需要拆分成好幾行。而agal是有限制的,不能超過200行。我嘗試的每個(gè)點(diǎn)受4根骨骼影響的情況,生成的agal代碼已經(jīng)有192行了。這是比較危險(xiǎn)的情況了。假如我們的代碼還需要做其他的處理,那么行數(shù)可能就不夠了。 第二種法子: 我進(jìn)行的嘗試是把各個(gè)蒙皮模型的子模型的信息進(jìn)行提取,獲取到該網(wǎng)格實(shí)際受到哪些骨骼的影響,然后推送vc的時(shí)候,只推受到影響的骨骼。 這樣做是從一個(gè)側(cè)面的解決這個(gè)問題。我們做人物模型的時(shí)候就不能整個(gè)模型合并完再一起蒙皮,必須單獨(dú)逐個(gè)部分的做,然后每個(gè)部分只蒙受到影響的骨骼。 這樣做的結(jié)果是只要每個(gè)部位蒙皮的骨骼不超過一定量,整個(gè)人物就可以支持很多很多的骨骼。 不過這樣做也是有缺點(diǎn)的。由于是把模型拆分了,所以原先每個(gè)人物每一幀只需要獲取一次的骨骼信息,就變成要獲取多次了。這樣就變成加大了cpu的運(yùn)算量。而且由于模型數(shù)量多了,渲染的實(shí)際次數(shù)也多了。 對于這種情況,我稍微優(yōu)化了一下提取信息的法子,讓他還是同一個(gè)角色同一幀只獲取一次骨骼信息。 在沒優(yōu)化之前,由于超出骨骼數(shù)量會(huì)退回cpu運(yùn)算,一個(gè)2000多面的角色帶有40多根骨骼,away3d只能同屏運(yùn)算10個(gè)左右就掉幀了。現(xiàn)在同樣的面數(shù)和骨骼的人物,可以支持同屏80-90個(gè)左右而保持在30幀。 對于這個(gè)優(yōu)化結(jié)果,我覺得還是不能實(shí)際的應(yīng)用在項(xiàng)目中。或者我還是需要在很多地方找一下優(yōu)化的可能性。因?yàn)樵跊]有優(yōu)化之前,對于2000多面的角色,但骨骼減少到20多根的情況下,同屏是可以跑100個(gè)而保持30幀的。如果是湊合著來做項(xiàng)目的情況下,其實(shí)直接讓美工減少骨骼數(shù)量會(huì)是更快的解決法子。不過這樣做,游戲的效果就被限制得很厲害了,很多好看的效果和服裝就表現(xiàn)不出來了。
轉(zhuǎn)載于:https://www.cnblogs.com/jiangjieqim/p/5445255.html
總結(jié)
以上是生活随笔為你收集整理的stage3d 骨骼优化的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Android深度探索(卷1)HAL与驱
- 下一篇: servle 3.0 新特性之一 对上传