用過Away3D的朋友估計都會發現,在Away3D里面使用超過一定骨骼數量的角色,當場景里面角色的數量稍微多一點,整個場景就會很卡。
對于這個現象,我之前得出的結論是。Stage3D的VC緩存器數量的限制,造成了對需要占用VC的骨骼信息有限制。對于超過了限制數量的骨骼部分,Stage3D會把數據退回CPU計算。
這里存在幾個誤區:
1、退回CPU的處理不是Stage3D做的,而是away3D本身做的。
原生的Stage3D對于超過能允許數量的骨骼,因為超出了128個vc,不會做其他處理,只會直接報錯:
ArgumentError: Error #3615: AGAL 驗證失敗: 程序大小小于 程序的最小長度。
2、不是部分的退回,是通過一個開關判斷是否需要退回,全部退回。
開關是變量usesCPU。一開始給材質賦值的時候,會判斷該模型是否需要退回cpu計算。假如不需要,就全部推到GPU計算,即使沒有動畫信息的時候,頂點著色器也會使用蒙皮計算的一套。假如需要退回cpu計算,那么就不會再使用蒙皮動畫的頂點程序,而直接用最基礎的頂點程序計算。
在明白了這兩點之后,看看Away3D對這個是否超出長度的功能做了什么處理:
1、通過對AnimationSetBase.cancelGPUCompatibility斷點,發現了在SkeletonAnimator.testGPUCompatibility方法里面有檢查是否需要退回CPU的判斷。其判斷的條件是:
if (!_useCondensedIndices && (_forceCPU || _jointsPerVertex > 4 || pass.numUsedVertexConstants + _numJoints * 3 > 128))
可以看出:
除了_useCondensedIndices ==false,還需要
1._forceCPU == true
2.一個頂點受到大于4個骨骼的影響。
因為每個va只能存xyzw四個數,按照Away3D的頂點著色器的處理,就只能最多一個頂點受到4根骨骼的影響。
3.已經使用的Vc,加上骨骼占用的VC,要少于128個。
由于Away對于骨骼 Transform推入GPU的計算是三個基向量,也就是占用3個緩存器,所以需要 骨骼數*3
后兩個條件,出現了優化的空間:
首先,一般頂點最多受到3根骨骼影響已經很足夠了。超過4根的信息可以考慮判斷其影響大小,將超出的而且權重小的部分排除掉。
然后,可以考慮一下怎樣減少輸入的vc數量,把三個基向量看有沒有辦法變成2個四維向量分別傳入位移和旋轉信息。由于Away3D使用的md5動畫格式本身就沒有導出縮放的,所以在沒有自己再寫解析器的情況下,沒有必要處理縮放的信息。
2、對于沒有超出允許范圍的情況,Away3D會通過代碼解析器組成頂點程序,然后每幀推入骨骼的三個基向量給agal計算。
在SkeletonAnimator.setRenderState方法里面,把計算出的所有骨骼的信息(_globalMatrices)傳入GPU,_numJoints是骨骼的數量。vertexConstantOffset是VC偏移量。也就是說,在vertexConstantOffset之前是其他頂點程序需要的VC,從vertexConstantOffset開始往后的所有VC都是骨骼信息使用的。由于每根骨骼有三個基向量,所以是_numJoints*3。
新聞熱點
疑難解答
圖片精選