unity 角色 动画脚本_Unity大规模角色的GPU顶点动画表达方式

项目中要求某场景中实现数十人奔跑,如果用骨骼动画,那CPU计算蒙皮的开销可太大了。依稀记得 @陈嘉栋 之前实现过一版,不过当时没细看。于是就拿这个思路继续写了。

思路

众所周知的是,因为要在CPU端计算骨骼动画信息,因此蒙皮网格是不能合批的。反过来说,计算骨骼动画实际也就是在计算蒙皮网格各顶点的位置。假如我们把一段动画中各顶点的位置记录下来,放在静态的网格上进行次序的播放,那么应当是等效的。

拿AnimationClip驱动SkinnedMeshRenderer,在每一帧下都Bake一次,把得到的Mesh的顶点都保存在一张纹理上。这样就完成了将动画烘焙成纹理的任务。

当我们要使用纹理的时候,就从纹理中读出某顶点对应像素的颜色值,并转换成空间位置。如何确定顶点和像素的对应关系呢?这就要用到SV_VertexID这个语义了。

实现

这里我做了一个小小的改进,假如动画长度很短,而模型顶点数又多的话,就会烘出3000*30这样的图,委实不美。因此只要在Shader中稍加改进,便可以指定烘出的纹理的尺寸了。

using 

这里需要注意两个地方。

首先是需要指定一个采样空间的尺寸,毕竟输出成纹理之后,分量的范围上是[0,1],需要指定采样空间的尺寸

,这样模型坐标空间中的范围
就映射到了颜色空间中的

第二个就是需要重新导入一次纹理,sRGB和点过滤器是必须要开的,以保证采样结果和计算结果吻合。

Shader没啥说的,就是将uv变换一次:

Shader 

精度修正

当然这样做的话还是有不足之处,就是由于在Unity中即便是RGBA32的图像,精度仍然显得不够。

v2-a156dee3b36ae4a7bd900f9f714f7858_b.jpg
精度不够,导致细节处的顶点已经出现了合并和穿插

为了弥补8位分量精度带来的损失,有必要使用多个分量来进行表达。已知float类型有23位用于有效数字,则我们可以使用两个8位分量或者3个8位分量来进一步修正。一般情况下,两个8位分量已经足够了。

using 

因为使用了RGB24的纹理,因此无论是Shader还是C#部分均修改了对纹理的接口。Shader这边使用变体,更方便操作。

Shader 

在使用16位精度的情况下,动画的表现已经足够支撑特写镜头时数十人狂奔而过的考量了,而不会出现五官抖动的情况:

v2-662201cf210172adf3c0c3f5273b4ea9_b.jpg

要更进一步使用24位也不是不可以,但是那样的话以内存和包体换执行效率的性价比就低了。不建议使用。

总结

本文立足于之前文章的思路,并在尺寸定制和精度修正上做出了一定的改进。但是从信息的角度考虑还有不足之处。

该方法最大的缺陷在于每个模型对每个动作都要烘焙一次,因为顶点众多,烘焙出来的纹理相当大,这是因为记录的是计算后的信息。从信息的角度考虑,顶点的信息都来自于骨骼动画的信息,因此如果能烘焙骨骼动画信息到纹理,信息密度必然更大更好。

参考资料

【1】利用GPU实现大规模动画角色的渲染 - 陈嘉栋 - 博客园

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值