本港台开奖现场直播 j2开奖直播报码现场
当前位置: 新闻频道 > IT新闻 >

报码:【腾讯GAD】Unity 实现传统的GPU Skinning (1)

时间:2017-07-08 13:52来源:香港现场开奖 作者:本港台直播 点击:
1. Unity5.6 目前对 Skinning 的处理有两种模式 : a) 一种是 CPU Skinning , 多线程 +SIMD ,性能实测非常不错 b) 还有一种是 unity GPU Skinning , 但它与传统的 vertex shader 做顶点混合不一样,是通过

1.Unity5.6目前对Skinning的处理有两种模式:

a)一种是CPU Skinning,多线程+SIMD,性能实测非常不错

b)还有一种是unity GPU Skinning,但它与传统vertex shader做顶点混合不一样,是通过transform feedback+ vertex shader (opengl)/ stream output + geometry shader(dx11)做顶点混合,写到新的GPUverticesbuffer,再提交一次一般模型的渲染完成的.如果这个Skinning模型会触发多遍渲染(shadow pass/reflecionpass/..),理论上相对传统GPU Skinning能节省一些顶点混合的计算而变快,实测PC上确实有5%左右的提升(仍然CPU Bound).

2.因为实测中发现Unity这两种做法目前都是CPU Bound,理论上传统的GPU Skinning会更快(1 pass),所以我尝试在Unity5.6实现传统的GPU Skinning,并在C#上尽力做了一些优化和处理...

3.主要流程:

a)修改原Mesh,让顶点数据带上BoneWeight所有信息

b)替换SkinneMeshRenderer为普通MeshRenderatv,切换新的传统GPUSkinning材质及shader

c)每帧动画做完后,计算Bone Palette,并传给shader渲染。

d)Vertex Shader里做顶点混合相关计算,这里v.texcoord1对应上面的indicesv.texcoord2对应上面的weights

4.尝试优化

a)通过上面的流程已经能完成传统的GPU Skining,但是因为上面的‘c计算Bone Palette过程是在主线程完成的(C#),加上Unity自身对Transform非主线程访问的限制,相对Unity5.6的多线程CPU Skining,性能不理想,当然,如果是单线程应该是变快了...

b)第一个优化就是打包顶点数据,看上面代,打开C#的宏PACK_WEIGHT_AND_BONEID,打开vertex shader里对应USE_PACKED_ID_WEIGHT开奖因为BoneIndex是整数索引,weight 0.0-1.0fweight缩小一点点再加在一起传入,shader读出还原,指令简单。这个做法需要高精度浮点值支持,手机目前是不行的,(参考链接https://community.arm.com/graphics/b/blog/posts/benchmarking-floating-point-precision-in-mobile-gpus),理论上也可以仔细做数值分析与打包,但shader会复杂化,很可能得不偿失。

c)第二个优化,很有创意,通过多构建一个特殊的SkinnedMesh(顶点数 == Bone Num x 4, 通过unityBakeMesh接口,计算出了当前模型的Bone Palette(结果存在这个特殊的SkinnedMeshBakeMesh后的vertices上),性能上比默认实现提升了40%+,主要区别就是C#计算BonePalette换成了BakeMeshnative simd计算,但是仍然在主线程。Unity源码层面,BakeMeshSkinning.Skin是一套代码,主线程与Worker线程计算的区别。

i.构建特殊用途的SkinnedMesh,通过特殊的Vector3,使BakeMesh的计算结果可以简单反推Bone Palette。见下面代码的几行注释,分别取到了矩阵的4列,实际因为UnityPosition只能是Vector3,结果不是直接取到4列,需要再做简单计算。

ii.动画做完后CPU BakeMesh复制出BonePalette,简单计算还原

(责任编辑:本港台直播)
顶一下
(0)
0%
踩一下
(0)
0%
------分隔线----------------------------
栏目列表
推荐内容