用过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。
新闻热点
疑难解答
图片精选