演讲内容

大家好,我叫徐宇峰,负责《球球大作战》的性能优化。

《球球大作战》现在拥有五亿多的玩家,为了吸引如此庞大的玩家群体,我们提供给玩家更炫更酷的皮肤,这些美轮美奂的皮肤,让《球球大作战》的游戏画面更加绚丽多彩,但随着皮肤日益精致,性能问题开始日益突出。

我们的皮肤正面看起来很简单,从侧面看,皮肤由精美模型与很多特效层组合而成。

皮肤的材质大部分为半透明。大量的半透明材质无法合批渲染,导致单套皮肤Draw Calls达到82个,面数1.1万以及骨骼40个。

《球球大作战》最核心技能就是分身吃球,而当玩家分身之后,Draw Calls更是暴涨,游戏中玩家最大16分身时,Draw Calls有820多,面数达17.7万。

在实际游戏中,多玩家多皮肤分身后,Draw Calls经常能轻松过千,下面视频是我们内部的极限测试版情况。

大家能看到,Draw Calls最低有400-500,最高达到2000多,如此高的Draw Calls导致游戏的帧率急剧下降,卡顿严重。而球球作为一款竞技游戏,性能与体验至关重要。

我们团队采用各种优化方法:

  • 模型贴图合并:模型与贴图尽可能的合并在一起,利用Unity的动态合批渲染,减少Draw Calls。
  • 减少半透明材质:半透明会带来融合运算,其次重叠的半透明物体无法合批渲染,导致Draw Calls增加。
  • 减少粒子系统:粒子会增加CPU运算,还会增加Draw Calls,每套皮肤的粒子数量我们控制在40个以内.
  • LOD系统
  • 降低分辨率:皮肤的贴图普遍采用512k,部分贴图在低端机器上降低到256k。

我们来看看优化对比。

下面视频是一个LOD系统的效果对比,左边是高性能机型高画质,右边是低端机型流畅画质。左右相互对比可以看到,右边的皮肤少了些特效与动画,贴图分辨率也相应降低。

通过以上优化,游戏性能大约提升52%,但画面品质同样遭受损失,在中低端机器上尤为明显,这点很容易引起玩家的不满。

美术团队也希望所有机型,画面尽可能的完美,并且过少Draw Calls极大限制了美术的高水平发挥。

《球球大作战》优化的难点是皮肤分身后Draw Calls暴涨的问题

我们想到用RenderTexture来降低Draw Calls峰值,但皮肤有太多半透明,渲染管线中对于透明相关的处理是在管线后期进行的。由于不同物体是按照顺序渲染的,对透明的处理方式是混合,实际上就是shader输出颜色与此像素位置已有颜色的合并过程。

下图中的混合公式是Unity中最标准的混融模式Blend SrcAlpha OneMinusSrcAlpha。

假设将Camera背景的颜色设置为全黑色(0001)或全白色(1111),分别进行渲染,渲染后的颜色分别为Cblack、Cwhite,得到公式1和2。公式中蓝色为已知数,紫色为未知数,2个公式可以求出2个未知数。

具体代码请参考:

下面看看具体制作流程。

我们把原资源用单相机渲染到RenderTexture,相机每帧切换黑白背景,形成连续序列帧,这是因为单个相机能节省更多的Draw Calls,但如果动画速度过快,就必须使用双相机保证品质。

RT经过GPU做算法剔除,输出到多张RenderTexture。RT我们采用512分辨率,一共40张,格式为ARGBHalf,真机占用内存约为20兆,目前市面上主流手机内存大部分为2G以上,所以内存很充足。具体用到那种分辨率与RT数量的多少,需要根据不同机型做适当调整。

多张带RT的RenderTexture组成一套序列帧,利用Plane切换RT做成序列帧动画。序列帧会循环渲染,从RT1渲染到40,再回到第1张。

Plane读取RT时也是循环读取,最后序列帧动画放到场景中与半透明背景,半透明皮肤以及UI等进行融合。

下面我们来看看原资源与RT资源的实时效果对比。这是原素材与RenderTexture的实时效果对比,原素材由十几层特效叠加,而RenderTexture只有单个面。

大家看看不同资源的效果对比,新技术首先必须保证美术品质才能投入使用。

在美术品质保证后,再看看优化前后Draw Calls对比。

当分身不断增加时,Draw Calls以线性增长,大家可以看看下面的Draw Calls图表,从最开始63暴涨至900多。

在RT模式下,分身的增加带来Draw Calls的个位数增加,同时可以看到在RT模式下,因为我们利用多张RenderTexture,每个分身的动画帧是错开的,动画并不完全一样。

1

我们再看看真机数据对比,测试平台为普通千元机。

如下图所示,左图分身数从1至16,普通模式Draw Calls从63暴涨至917,翻了14.5倍,每一次分身数量的翻倍都让Draw Calls剧烈变化。而RT模式从64到83只增加19个。

有图CPU消耗图,在RT模式下,CPU的消耗非常平稳,而普通模式最大分身时消耗已经翻倍。

再来看看FPS与内存消耗。

如下图所示,手机号码帧率在普通模式下,16分身帧率已经降低到25,加上UI与其它逻辑消耗,已经产生游戏卡顿。而RT模式帧率非常平稳。

内存方面因为RT用了40张16位的512贴图,内存大约多20MB,这是RT模式唯一消耗点。实际应用中我们会根据机器的内存容量,控制RT的数量与分辨率。

《球球大作战》同屏有上千物体,每帧数千个物体的位置、大小、动画、网络数据等伴随着产生大量逻辑运算。

主要逻辑有:

  • 利用插值函数使物体的移动更加平滑
  • 玩家吃球后重量会增加:根据重量来计算球的尺寸与前后位置,尺寸越大物体越靠近摄像机。
  • AI状态机:玩家根据游戏状态,如二个玩家距离接近时,会播放调侃动画,吃掉其他玩家时播放炫耀动画;
  • 相机视野计算:玩家所有球的数量与尺寸变化,都伴随着相机位置与FOV调整,每个分身必须在相机视野内,最大分身尽可能处于屏幕中心;
  • 其它逻辑:还有网络数据解压缩、解密、背景迷雾、UI运算等。

以上这么多的实时运算量会对CPU产生巨大压力。

我们利用Unity 2018的ECS系统,把所有逻辑做分类,纯逻辑运算做成PureECS,其他部分做成HybridECS。数千物体的逻辑运算,尽可能分配到多个核心。

这极大的提升游戏性能,并且更快更复杂的运算让物体的移动、旋转更加平滑和细腻,增强游戏的用户体验。

上述的优化方法,部分处于《球球大作战》的试用阶段,我们一直都在不断尝试和创新,使用各种优化方式,让《球球大作战》拥有更好的用户体验,并不断焕发新的活力!

我的演讲到此结束,谢谢大家。

《球球大作战》游戏优化之路(下)相关推荐

  1. 《球球大作战》游戏优化之路(上)

    自从2015年<球球大作战>发布以来,现已拥有五亿多的玩家.如此庞大的玩家群体,对游戏的画面,性能要求是非常高的.在Unite Shanghai 2019大会中,<球球大作战> ...

  2. html5小游戏 typescript,使用TypeScript和Canvas编写移动端贪吃蛇大作战游戏

    基本介绍 一款移动端贪吃蛇大作战游戏.(只支持移动端) 这是一个临近 deadline 的课设项目,为了方便地使用TS,我直接使用angular-cli生成了TypeScript的项目结构.如果你有好 ...

  3. 小球大作战-搜索优化

    为什么80%的码农都做不了架构师?>>> 模仿球球大作战: 一个大小为1000*1000的地图中,有1W个 食物 需要判断是否能吃掉,游戏设计是帧同步(帧数40),如果全部搜索的话很 ...

  4. 原谅帽大作战游戏程序

    原谅帽大作战 制作人:崔帅宽 时间:2020.11.10 一.如何创建原谅帽大作战的窗体: (1)先创建一个原谅帽的类包,然后创建:游戏客户端GameClinet类. /* 游戏客户端 */ publ ...

  5. 面向对象版贪吃蛇大作战游戏创作

    贪吃蛇大作战 创作思路: 1.创建蛇头蛇身-----2.让蛇动起来-----3.随机投放食物-----4.吃掉创建的食物------5.判断游戏开始结束 前期准备工作: 创建一个宽1200 高800的 ...

  6. 【项目实战】轻松实现C/C++大作业:贪吃蛇大作战游戏!

    这是一个贪吃蛇大作战类游戏,修改特性为 AI 不互杀: 该程序有四个类:蛇基类 SnakeBase,玩家类 Player,AI 类,Game 类:SnakeBase 和 AI 均继承自 SnakeBa ...

  7. Python—飞机大作战游戏(附源代码及素材)

    目录 过程说明: 主函数 键盘控制 创建类 01.飞机基类 02.子弹基类 03. Hero飞机类 04.enemy飞机类 源代码及素材 过程说明: 应用到的库:         import pyg ...

  8. 前端作品-球球大作战游戏

    点此查看 所有教程.项目.源码导航 文章目录 1. 作者简介 2. 效果展示 3. 源码下载 1. 作者简介 本网站作者田迅,是我的20级软件技术专业学生,爱好前端.擅长使用HTML.CSS.JS.j ...

  9. Python版见缝插针小游戏源代码,球球旋转大作战源程序

    见缝插针游戏是一款非常考验玩家手眼协调能力的休闲益智虐心虐脑小游戏,玩法很简单,但要过关却很有挑战性哟! 主要是将一系列的小球,插入到旋转的摩天轮转盘当中,插入过程中不能碰到旋转的摩天轮上的其他小球, ...

最新文章

  1. 【组队学习】【28期】基于transformers的自然语言处理(NLP)入门
  2. Sci. Adv. | 新算法识别治疗肺动脉高压的候选抗癌药物
  3. mint 15用fcitx框架安装中文谷歌输入法
  4. “深度学习不能拿来乱用”,Nature论文引发激烈争论
  5. MinGW 仿 linux 开发环境
  6. server2016安装mysql_windows server2016安装MySQL5.7.19解压缩版教程详解
  7. 【动态规划】方格取数 (ssl 1010)
  8. [Leedcode][JAVA][第200题][岛屿数量][DFS][BFS][并查集]
  9. github page hexo博客gitee_利用Github和hexo搭建个人免费博客
  10. pve 加大local容量_proxmox ve (PVE) 增加 local 目录的大小即扩容
  11. 在Windows上创建CUDA C程序
  12. ssis 包配置组织程序_如何停止失控的SSIS程序包
  13. 2020 年百度之星·程序设计大赛 - 初赛一 Drink
  14. 【SDOI2014】数表
  15. Linux 端口占用情况查看
  16. git如何回滚远程仓库
  17. 网站加速--Cache为王篇
  18. WINDOWS自带的压缩,解压工具命令
  19. spring源码--第七个后置处理器的使用:初始化方法
  20. ExtJS6-项目创建

热门文章

  1. php多线程swoole,swoole究竟能够多线程么_PHP开发框架教程
  2. rpa 手机_容智正式推出全球首款移动端RPA产品
  3. oracle pid查看,查看佔用aix oracle pid
  4. java sftpv3client_Ganymed SSH-2 for Java系列8之SFTPv3Client说明
  5. 华中数控机器人编程循环三次_数控机床固定循环编程(G80~G84)详解
  6. [tomcat]-tomcat8启动时SessionIdGeneratorBase.createSecureRandom耗时
  7. Linux日志 系统日志及分析
  8. CF1000G Two-Paths
  9. Ubuntu 中Eclipse 默认的OpenJDK 和 SUNJDK问题总结
  10. KDE 4.3.2 发布