《偶像大师MLTD》为何效果惊艳?项目主程分享13人演出的实现与优化方案
又一次技术突破。葡萄君在此前的文章中,已经对《偶像大师MLTD》(后文简称MLTD)这款本身,以及它的运营技巧进行了非常详尽的报道。MLTD的优秀之处在于,它依靠系列作品12年的内容、技术积累,在移动端表现出了精致的舞台演出效果。
只不过,早期MLTD能够支持同台演出的最大人数,只有5人。对于即时演算的舞台效果而言,要保证足够的表现力,必须融入足够多的光效、动画,以及大量渲染处理,最关键的,就是展现出足够到位的舞台细节,来烘托人物动作、服装风格、词曲表达,乃至整个的舞台氛围。
对于移动端的设备来说,要承载这样的表现,已经比较吃力了。而MLTD在今年又实现了一次技术上的突破,仅用了不到三个月的时间,就将可同台演出人数扩展到了13人,让玩家体验到了13位成员的完整组合,在手机的画面中演出同一首歌曲的精彩场景。
在上个月,Unity在日本举办了“Unite Tokyo 2018”技术分享大会,期间《偶像大师MLTD》开发团队,万代南梦宫工作室的主程序池田早人、程序员加藤政树分享了他们的制作经验,以及遇到各种优化问题时的解决方案。下文部分内容来源于日媒SGI的报道,由于缺少细节,游戏葡萄根据原PPT添加补充说明,可能存在一定程度上不准确的描述。
项目组很幽默地将支撑整个游戏内容的制作流程,用游戏中的角色茜(AKANE)来命名池田于1996年以硬件工程师的身份加入南梦宫,作为客户端工程师的负责人,主要负责进度管理和版本管理等。
万代南梦宫的主程序池田早人(右)、程序员加藤政树(左)MLTD这款游戏与2017年6月上线,以偶像大师系列最早的舞台765事务所为起点,来表现765 MILLION ALLSTARS的偶像们从事的偶像事业。游戏主要玩法为音乐舞蹈,玩家需要指导这些偶像,通过演出、工作、剧场对话等方式,来推动游戏的进展以及加深与偶像的交流,体验角色、故事、世界观背后的乐趣。
在游戏中核心玩法演出的部分,在不同时期有不同程度的迭代。刚上线的时候,游戏可以支持5名偶像同台演出;偶像角色的站位、服装可以随意调整;在特殊的曲目中,5名偶像还可以按照独立的舞步进行演出;部分歌曲支持51名偶像独立演唱;在演出中还会加入特殊的特效展示环节(继承自主机的传统)。在运营的过程中,游戏逐渐追加了支持4人、3人、2人演出的功能;支持了52名角色独立演唱同首曲目的功能(角色琴叶回归);在演出中偶像可以变身了(瞬间换演出服)。最近一次大型的功能迭代,就是支持了13名角色同台演出。
MLTD中,每名角色建模都由10000个面构成,服装材料是一张1024×1024的贴图,表情则使用了BendShape功能来制作。
每个演出场景建模都由15000面构成,其中10000面是基础的舞台建筑,剩下5000面则用来支撑特效演出相关的内容。舞台材质使用了两张1024x1024的贴图,为了降低消耗,观众席上的投射灯只用了1个Mesh来表现。
后期处理采用了景深、Bloom、Blur等效果,在处理光晕(Flare)效果时,由于Unity的高画质效果对手机的负载很高,所以项目组使用了自己编写的优化Shader,灵活运用中间Buffer来节约内存。游戏整体的解析度以720为基准,在iPad等设备上,则调整到960x720。对于GPU性能比较低的设备,游戏也设置了低解析度的模式,但这种情况下锯齿会比较明显,所以可以尝试MSAA处理。尽管这种处理会稍微提高负载,但在绘制面积比较多的场景里,低解析度带来负面效果更多,所以这种做法还是可取的。
在制作演出部分的时候,项目组采用了Timing Sheet工具(舞台事件工具),其实就是Timeline工具。工具分为两类,一种用来制作舞台演出,另一种用来制作运镜效果。这个工具是在家用机采用的工具基础上,在Unity中重新制作的。这套工具,可以将镜头、角色位置、角色表情、舞台演出、舞台灯光动作等所有的数据整合起来,进行自主编排。这套工具也在随着设计和画师的需求不断优化。
在分唱(对应角色声优的个性化演唱)功能上,根据成员站位的不同,游戏中准备了不同的演唱部分。这套功能在主机板偶像大师中就有了,要实现它,必须收录每个偶像的声优演唱音频。在手游版本中,因为有52名角色,所以按照不同的排列组合,5个人的演出队伍,就可以组合出约3.1亿种不同的演唱效果。按照1首曲子2分半的时长,把所有不同版本的歌听完,差不多要花掉465亿秒,也就是538194天,相当于1474年。音频使用了CRI的ADX2格式,通过采用多个通道,以及静音功能,来实现分唱的效果。分唱的数据也由前文提到的舞台演出工具来管理。
从开始开发,到2016年4月,团队主要在尝试制作通过程序和技术美术来表现3D演出的效果;随后的两个月,逐步完成了α1版本的制作,包含标题界面,到剧场场景,到故事功能,再到演出的整个主要流程。从6月到11月的期间,加入了游戏需要的全套外围系统。这次演讲最重点的优化环节,是从2016年11月到2017年7月的这段时间,也就是游戏上架前的5个月。随后就是资源打包,服务器建立,以及整体评测等工作。在上架前的3天,升级了Unity的版本,在应用商店中提交了游戏,紧接着就开服了。
在开发的时候,很容易遇到一些必须设法优化的问题。刚开始,MLTD只考虑了能不能在iPhone的最新机型上流畅运行,结果,在iPhone5s、安卓等机型上,游戏卡得完全玩不了。于是项目组在开发团队之外,建立了一个独立运作的优化团队,来保证游戏能在安卓上流畅运行,他们将优化项目称为“AKANE大作战”。顺便一提,AKANE大作战的命名,是来源于“安卓-高速化-与-自定义化”的日文读音首字母。
图中角色就是茜(日文读作AKANE)整个优化分为四个主要部分:1、重审项目设定;2、3D绘制的高速化,提高CPU和GPU的效率;3、2D绘制的高速化,从画布(Canvas)转向图像拼合(Sprite),判断是否存在无效的透明绘图,集成图片(Atlas);4、防卡顿,不做垃圾数据回收(GC),更不能让它出现。
所需要达成的目标也有四项:首先要减少SetPassCall(DrawCall)。其次要减少GPU负载,包括集成贴图、整合Index Buffer、削减材质、调整绘制顺序。接下来要减少CPU负载,提高摆动物件的计算速度,线程化,合理分配CPU运算量。最后是优化内存,寻找不用做垃圾数据回收的方法。最终目的是让游戏FPS平均稳定在60左右,这意味着16.6666毫秒内要完成所有的运算处理。
在Profile方面,他们在保证不降低视觉品质的基础上做了很多优化。首先,有关CPU的优化方案可以在UnityProfiler中看到。其次,针对GPU做优化的时候,项目组使用了Qualcomm提供的Sanpdragon Profiler。第三,很重要的一点是整合测试环境,提供数值化比较的方案。因为盲目地采用一些优化方案,也没法测出实际效果的好坏,所以就算是很麻烦,也要在有变动的地方做好配置,通过数值来比较效果。从实际情况来看,有些时候做了很大的变动效果其实并不好,相反,有些时候只做了很小的改动却带来非常大的影响,所以监控数据测试环境是非常重要的。最后,理解不同设备的适配情况也很重要,除了设备本身的差异,尤其要注意的是一些日本手机在发热后会启动降频保护。因此很多时候,一些优化方案并不能达到想要的效果。
项目组在实现方案和测试的时候,按照如下流程来进行:将优化方案按照优先度排序→实际添加功能→生成和测量→提供更好的方案。在开发界面,为了更方便测试,项目组设计了随时可以开关优化项目的功能,这对于视觉美术人员来说,也更便于测试。另外他们用了对程序负载最大的五名角色来进行测试。
从引擎的角度来说,也存在很多可以优化和没法优化的方面,比如项目组趁早放弃了多线程化。对于短期内没办法实现的方案,他们的选择就是不做,一方面Unity迟早会推出新的应对功能,等待也是一种方法。另外,活用Unity本身的演讲资料、培训资料也很重要,还有Unity Forum、UnityIssue Tracker等等。需要注意的是,游戏发布之后再进行程序版本升级,会遇到很多难点,必须非常慎重,所以开发的时候尽可能要用最新版的引擎。
在游戏发布之后,MLTD的优化工作也没有停下。比如持续改进演出效果、整合材质、舞台演出轻量化、通过安装独立的动画系统来削减处理负载和数据量、减少GC等。因为游戏后续逐渐上线了新的功能,所以优化团队定期都会执行Profile流程。
基于以上的一套优化流程,MLTD最重大的一个功能“13人LIVE”才得以迅速实现。在2017年底的时候,制作人提出了“能不能让五名以上的角色同台演出”的问题,于是项目组开始尝试制作。但实际上在压力测试的时候,项目组已经采用了超过5人的功能模式,所以这块的功能是验证过可以实现的。在他们只做了15人演出的测试功能后,发现居然能顺畅的运行,于是最终只花了3个月不到的时间,优化成了13人同台演出的完成版。其实在优化过程中,优化团队并没有针对13人模式去实行专用的内存优化、负载优化方案,这得益于他们在整个优化过程中,对系统平衡性进行持续调整的积累。
总结来看,有五个关键点。第一,优化是积累的过程,在优化之前要明确工程量。第二,Profile非常重要。第三,优化效果的可视化非常重要。第四,必须建立起可持续推出并实现优化方案的工作流程。第五,积少成多,不论多么琐碎的事,最终都会展现出极大的成果。
具体再看详细的优化案例。在角色DrawCall的优化方面,先决条件是保证不改变角色的外观,同时不重新制作资源。
从优化的结果来看,经过对Sub Mesh的整合,一个角色建模的DrawCall数量从25降低到了17。通过Command Buffer这项功能,可以实现对模型绘制的细节调控。
MLTD中,角色的模型分为头部和身体。制作中需要着重刻画身形、服装、夜光饰片、皮肤、色彩等方面,可以通过腕饰、项链等小饰品展现出角色的特征。Shader方面,项目组用一条通道来展现角色的建模,用另一条来展现轮廓线。轮廓线的绘制需要注意几点,一是绘制翻转多边形,二是让顶点Shader扩大,三是采用与模型共通的Mesh。
制作中遇到了不小的困难,项目组希望把DrawCall都整合起来,但是这样就很难一次囊括进所有独立的Sub Mesh。
所以它们采用了分类处理的方式,按照模型、Mesh、Sub Mesh的三大类,对头部、身体的建模进行了划分。对于头部而言,Mesh需要包含头发、头颅、头饰三个部分,然后省略Sub Mesh的内容。对于身体而言,Mesh即是整个躯体,Sub Mesh则包含了服装、领口和裙摆、手、腕饰等。对于所有归类到Mesh的资源,都要注意定点构造的区别,而对于Sub Mesh中的资源,则更需要注意材质的差异。
通常,在绘制建模的时候,最关键的几个部分是顶点Buffer、Index Buffer、材质。
在制作时,Sub Mesh的部分需要用Index Buffer来处理,而不用在顶点Buffer上处理。
从这里延伸出来一个点,如果游戏后期需要加入新的Index Buffer用来处理轮廓线、材质等Sub Mesh,那么加入后的内容依然能与整体的建模绘制并行使用。
他们在后续的尝试中也验证了这种做法的可行性,只不过,仅追加Sub Mesh是没用的,还需要扩充材质的排序,加入只有轮廓线的材质。
下面是追加SubMesh的代码:
下面是追加材质的代码:
下面是项目组对Unity内置环境的理解:
整个优化的结果是DrawCall数从25降低到17,尽管看起来减少的并不多,但从游戏变化来看,从5人演出到13人演出,实际上已经实现了非常大的突破。更重要的是,画面品质没有下降、资源也没有重做、上线节点也赶上了。
包括UI在内,优化前后的DrawCall数则是从44降低到36,少了8个。
项目组还表示,尽管他们目前还没有在正式版中实际运用材质LOD、COmmand Buffer的等功能,但实际上他们也找到了能够更加细致地整理角色建模绘制的方法。在材质的LOD方面,他们选择在镜头较远的时候,将衣服和裙摆等资源优化成一个DrawCall,而在近距离的时候就展现出所有的细节。
LOD最重要的一点,是对Sub Mesh资源可见性的调控。比如反射效果会在衣领、裙摆这个材质上实现的,High LOD模式下,需要将全部特效显示出来。而在Low LOD模式下,由于衣领裙摆和服装被绑定成一个Sub Mesh,所以就失去了这个效果。不过对于远距离的单位,反射的视觉效果并不明显,因此进行LOD也是可行的。
另外,他们还研究了Command Buffer的使用。对于整合到一起的Sub Mesh材质,Command Buffer可以进行统一绘制。
需要注意的是,如果要单独将SkinnedMesh渲染关掉,同时继续维持Skinning的运行,则需要将Renderer.materials[ ]的值调为空值,这样一来不仅Skinning会继续运行,Frustum Culling也会继续运行。
具体的代码如下:
材质优化前后的对比:
总结来看,Command Buffer的有点在于,它能够更容易地控制绘制顺序,能够以Sub Mesh为单位进行可视化处理,切换材质时也很方便。
开发组还公开了一组Scene View摄像头与Command Buffer关联运用的代码:
在实际的运用中,一方面可以处理Sub Mesh的可视化效果,另一方面可以用来Debug。
Sub Mesh的可视化效果:
Debug视图:
演讲最后,项目组认为,能够实现这些成果,得益于他们在引擎底层自定义改造的知识。在开发MLTD之前,项目组的很多成员也来自PS4版《偶像大师》的研发团队,灵活运用此前积累的经验,也是实现这些效果的关键。可见,使用游戏引擎来提高游戏品质和开发效率十分重要。