西西软件园多重安全检测下载网站、值得信赖的软件下载站!
软件
软件
文章
搜索

首页西西教程其它教程 → Away3D骨骼动画处理方法、Away3D骨骼优化的多种尝试及结果

Away3D骨骼动画处理方法、Away3D骨骼优化的多种尝试及结果

相关软件相关文章发表评论 来源:西西整理时间:2013/11/13 15:37:37字体大小:A-A+

作者:西西点击:81次评论:0次标签: Away3D

  • 类型:滤镜插件大小:7.6M语言:中文 评分:6.6
  • 标签:
立即下载

用过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。

所以最终推入GPU的数据是这样的:

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里面逐个顶点分别乘以受到影响的骨骼的基向量再乘以权重最后相加的过程,求出了每个顶点在每一帧实际的位置坐标,然后返回。

如果角色多、顶点多的情况下,这个过程在CPU算明显是超级大的负荷,难怪几个人物就卡死了。

这里又出现了优化点了,宁愿对美术资源进行限制,也不要用CPU来渲染。Away3D这个功能明显是鸡肋,只是为了做得全面,适应各种没有限制的模型,没有项目可行性。

Away3D骨骼优化的多种尝试及结果

之前针对stage3d支持骨骼数量的优化方案,做出过2个可能性的分析:
1、减少vc的推送,把transform拆分成一个四元数和一个三维向量。
2、拆分模型网格,把超出的部分拆分后分别推送。
之后的这段时间,我对这两种方法都做出了尝试。接下来谈一下结论:

第一种方法:
通过向VC推送四元数和三维向量,结合骨骼的bindpose矩阵,是可以算出顶点在动画之后的位置。之前有位朋友评论说在agal里面不能用四元数计算。这个说法不能算错,因为agal的确没有提供直接的四元数计算。但假如对3d图形数学熟悉的朋友,就可以直接把运算的公式在agal里面重现一下,就可以了。
这种做法的优点是cpu计算实在很少,比如在解析动画之后可以直接把动画关键帧保存成四元数和三维向量。然后需要计算动画的时候,直接获取然后推送就行了。但缺点是公式在agal里面运算会比较麻烦,一条点积的公式,在agal里面就需要拆分成好几行。而agal是有限制的,不能超过200行。我尝试的每个点受4根骨骼影响的情况,生成的agal代码已经有192行了。这是比较危险的情况了。假如我们的代码还需要做其他的处理,那么行数可能就不够了。

第二种方法:
我进行的尝试是把各个蒙皮模型的子模型的信息进行提取,获取到该网格实际受到哪些骨骼的影响,然后推送vc的时候,只推受到影响的骨骼。
这样做是从一个侧面的解决这个问题。我们做人物模型的时候就不能整个模型合并完再一起蒙皮,必须单独逐个部分的做,然后每个部分只蒙受到影响的骨骼。
这样做的结果是只要每个部位蒙皮的骨骼不超过一定量,整个人物就可以支持很多很多的骨骼。
不过这样做也是有缺点的。由于是把模型拆分了,所以本来每个人物每一帧只需要获取一次的骨骼信息,就变成要获取多次了。这样就变成加大了cpu的运算量。而且由于模型数量多了,渲染的实际次数也多了。
对于这种情况,我稍微优化了一下提取信息的方法,让他还是同一个角色同一帧只获取一次骨骼信息。

在没优化之前,由于超出骨骼数量会退回cpu运算,一个2000多面的角色带有40多根骨骼,away3d只能同屏运算10个左右就掉帧了。现在同样的面数和骨骼的人物,可以支持同屏80-90个左右而保持在30帧。
对于这个优化结果,我觉得还是不能实际的应用在项目中。或者我还是需要在很多地方找一下优化的可能性。因为在没有优化之前,对于2000多面的角色,但骨骼减少到20多根的情况下,同屏是可以跑100个而保持30帧的。如果是凑合着来做项目的情况下,其实直接让美工减少骨骼数量会是更快的解决方法。不过这样做,游戏的效果就被限制得很厉害了,很多好看的效果和服装就表现不出来了。

    3d模型
    (13)3d模型
    如今电子商务发展势头迅猛,各种商品广告在网络上铺天盖地,怎样让自己的商品能更全面更显眼的展现给消费者成了所有商家宣传展示自己商品的重中之重。传统的二维照片显然已经无法满足这一要求,于是商品展示技术便开始步入人们的视野。模型的展示,用户不仅仅可以更为清晰直观地浏览广告内容,其互动性以用户为核心,任意视角全方位浏览欣赏,同时根据要求制作用户可直观地参与内容,其广告效果可想而知。这里给大家收集整理了很多...更多>>
    3dmax插件大全
    (19)3dmax插件大全
    除了能够制作出精细的模型外,其中最大的一个亮点就是它的插件功能强大,只要你能够想到的效果,都有相应的插件可以替你实现。这里西西给大家收集了很多非常实用的插件。插件后缀名介绍.位于建立命令面板中,可创建包括建模增加辅助物等的新对象。.位于变动命令面板中,增加新的修改命令,可在中找到。.属于大气效果灯或渲染类插件,位于的环境编辑器中,也可在菜单的面板中找到。.属于特殊用途的插件,位于程序命令面板。.属于后期...更多>>

    相关评论

    阅读本文后您有什么感想? 已有人给出评价!

    • 8 喜欢喜欢
    • 3 顶
    • 1 难过难过
    • 5 囧
    • 3 围观围观
    • 2 无聊无聊

    热门评论

    最新评论

    发表评论 查看所有评论(0)

    昵称:
    表情: 高兴 可 汗 我不要 害羞 好 下下下 送花 屎 亲亲
    字数: 0/500 (您的评论需要经过审核才能显示)