【转】Animation Instancing:高性能大规模动画解决方案

作为开发者,我们总是会关注CPU和GPU的性能。对于更广阔更复杂的场景要想获得一个好的执行效率始终是布满挑战的,特别是当我们添加了更多的角色时。Unity技术支持团队在帮助、支持客户的时候经常会遇到类似的问题,所以我们决定专注去解决这个问题,提高渲染大规模角色的效率。我们把此技术称为Animation Instancing。

我们经常利用GPU Instancing 去实现室外场景,比如草地和树木。但是对于SkinnedMeshRenderer,例如角色,我们是使用不了instancing技术的。因为角色的蒙皮计算通常是在CPU计算的,然后一个一个的提交给GPU渲染。通常来说,我们没办法通过一次提交来画出多个角色。那么当场景中有大量角色时,就会有相应的大量Drawcall和动画计算存在。

Animation Instancing是一种大大减少CPU消耗并且对GPU Instancing的一种补充。你可以在GitHub上获取代码。

下载地址:https://github.com/Unity-Technologies/Animation-Instancing

特别说明:这是一个实验性质的解决方案,在此之前仅分享给个别企业级服务的客户。但是现在我们希望获得更多的反馈以便改进此方案,如果你有任何问题请在GitHub或者后台留言给我们。

目标
我们对这个实验项目最初的目标是:

  • Instancing SkinnedMeshRenderer
  • 尽可能实现动画特性
  • LOD
  • 支持移动平台
  • Culling

由于时间关系,不是所有的目标我们都已经实现的。例如动画特性已经支持的有:Root Motion,Attachment,Animation Events,还不支持的有:Transitions, Animation Layer。同时,对于移动平台的支持需要平台支持OpenGL ES 3.0及以上。

通过我们的测试,这个实验性的解决方案已经可以获得很有趣的结果。让我们来深入了解一下细节。

动画处理
在我们instancing角色之前,我们需要预处理角色的动画。我们把角色动画存储为了texture,以便于在GPU上蒙皮。这些texture我们称其为Animation Texture。

image

这个处理器会收集角色的动画以及动画事件。从Mecanim系统转化到Animation instancing是十分方便的。如果你想挂接某些东西,例如:挂接武器到你的角色上,你需要在Attachment settings中设置要挂接的骨骼节点。

当我们处理完成Animation Texture,名字为Animation Instancing的脚本在运行时会自动读取对应的动画信息。请注意这里的动画信息并不是指animation clip文件。

Instancing
启用Animation Instancing是十分简单的。我们只需添加Animation Instancing脚本到我们已经处理过的Game Object。Bone Per Vertex选项控制着每顶点受影响的骨骼数目。更少的数目带来更高的性能但是更低的动画精确度。

image

之后,我们需要修改角色所用的shader来支持instancing。基本上,你所需要做的就是把下面二句话加到你的shader中。它不会影响你的shader的着色,只是添加了一个顶点着色器来蒙皮。

#include    “AnimationInstancingBase.cginc”`

#pragma vertex vert

性能分析
我们使用了Mecanim Example Scenes中的一个场景来做测试,这个测试结果是在iPhone 6上的,在pc上你可以获得更好的测试结果。让我们来看一下测试结果对比。

CPU
原始的测试场景我们生成了300个角色后FPS大概在15帧左右。由此我们可以粗略的推断要达到30帧大概要生成150个角色。在Animation Instancing版本我们生成了900个角色后,可以稳定在30帧。

image
image

通过下图我们可以发现,瓶颈主要在CPU端。而通过Animation Instancing,我们降低了在CPU上的动画计算与蒙皮。所以,我们相对于原始版本可以生成5、6倍的角色。

image
image

下面让我们来看一下Drawcall。在这个测试场景中,环境的Drawcall大概在80左右。由于我们的测试角色有3个材质,所以我们需要3个Drawcall去渲染一个角色。

原始版本中,我们生成了250个角色,这产生了1100个左右的Drawcall(3*250个角色+阴影)。

在Animation Instancing版本中,我们生成了800个角色,但是Drawcall的增加量只有50左右。同时,在instancing这一行中,你可以看到有Batched drawcall4800个(38角色+38阴影)。这是因为我们把100个角色作为一个批次来提交的。

image
image

GPU
这个技术会提升一点GPU的消耗,因为我们把蒙皮放在了GPU上。如果角色还有阴影的话,我们在shadow pass中会再次计算蒙皮。然后,总体来看它提升了整体的帧率,因为我们大大降低了CPU的消耗。通常在有大量角色存在的场景中,CPU的消耗是主要的瓶颈。

内存
我们需要的额外的内存占用是Animation Textures。这些纹理保存了蒙皮矩阵。我们使用了RGBAHalf格式的纹理(对于不支持此纹理的平台我们还在找寻解决方法)。让我们假设一个角色有N个骨骼且每骨骼保存4个像素作为一个矩阵。我们预处理一个动画为M帧。所以一个动画会花费N * 4 * M * 2 = 8NM bytes。如果一个角色有50个骨骼且我们生成30帧的动画的话,一个动画会消耗50 * 4 * 30 = 6000 像素。所以一张1024x1024的纹理可以存储174个动画。

结论
通过验证我们发现如果你的场景中有大量的SkinnedMeshRenderers,Animation Instancing可以有效的降低CPU的消耗。它十分适合那些有大量角色存在的游戏中,比如僵尸、战争模拟等类型游戏。

原文:http://forum.china.unity3d.com/thread-32215-1-1.html

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,539评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,911评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,337评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,723评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,795评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,762评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,742评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,508评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,954评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,247评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,404评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,104评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,736评论 3 324
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,352评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,557评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,371评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,292评论 2 352

推荐阅读更多精彩内容

  • 有很多种framework以及很多种方法的组合可以在屏幕上渲染UI元素,我们在这里讨论这个过程中发生的事情,希望这...
    纵横而乐阅读 4,489评论 4 25
  • 原文地址 http://www.fx114.net/qa-75-172454.aspx 使用Profiler工具...
    IongX阅读 5,846评论 1 11
  • 基础 核心动画是 iOS 和 MacOS 上的图形渲染和动画基础结构,用于为应用的视图和其他视觉元素设置动画。 核...
    davon阅读 1,899评论 0 8
  • 原文地址:https://unity3d.com/cn/learn/tutorials/temas/perform...
    hellokazhang阅读 4,478评论 0 13
  • 一:什么是协同程序?答:在主线程运行时同时开启另一段逻辑处理,来协助当前程序的执行。换句话说,开启协程就是开启一个...
    CrixalisAs阅读 2,068评论 1 7