白鹭引擎王泽:重度H5游戏性能优化技巧

2023-11-23 03:30

本文主要是介绍白鹭引擎王泽:重度H5游戏性能优化技巧,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

图片描述
9月15日,无惧17级台风“山竹”,320名开发者齐聚广州贝塔空间共同探讨“怎样做一款赚钱的小游戏”。针对众多开发者关心的重度H5游戏性能优化技巧,我们整理了现场速记分享给大家,详见下文:

王泽:各位开发者下午好!我叫王泽,是白鹭引擎的首席架构师。

今天给大家分享的题目是《重度H5游戏性能优化技巧》。之所以决定用这个题目,是因为我最近几周在广深一带拜访了很多使用白鹭引擎的开发者,发现特别是在广州一带,大部分开发者都在做重度H5游戏。在几周的拜访过程中,我协助许多广州的游戏开发团队进行游戏性能优化,并在在这个过程中发现很多开发者遇到的问题是非常相似的,于是我借这次开发者沙龙的机会,把这些优化技巧整理出来与广大开发者分享。
图片描述
这些技巧都是我在实际项目中得到验证过的优化技巧,并且都是投入产出比很高的优化项,建议做重度H5游戏的开发者重点针对您们的游戏进行这些优化。

在开讲之前,我首先为大家回顾一下白鹭引擎的历史上几个比较重要的版本。2014年3月白鹭引擎发布了0.9版本,并产生了《围住神经猫》这一爆款。紧接着一鼓作气发布了1.0版本引入了完整的GUI,这使得开发者可以开始做具备大量复杂 UI界面的游戏,《愚公移山》就是这样的一款产品,他成功的在 2014年底就取得了每月180万流水的成绩。

接着在 2014年11月发布了 2.0版本,重点包含了白鹭引擎的工作流工具集,特别是 UI 编辑器与动画编辑器,这对游戏开发效率带来了重大提升,因此在 2014年底,使用了白鹭引擎 2.0 版本的《传奇世界H5》 成为了第一款月流水超过千万的 H5 游戏。2016年1月,白鹭发布了3.0版本,这个版本引入了 WebGL 渲染器,大幅提升了游戏渲染效率,这个版本得到了开发者的普遍欢迎,《决战沙城》更是用这个版本实现了 H5 游戏月流水三千万的成绩。

2016年底,白鹭引擎自研了一款名为《莽荒纪》的产品,并同步推出白鹭引擎4.0版本。这款游戏使用了大量的骨骼动画,对动画渲染性能和资源加载效率的要求非常高,得益于4.0版本针对这两点的优化,这款产品在绝大部分设备包括千元机上都有非常好的表现。2017年5月份,白鹭引擎发布了 5.0版本,市场上也出现了第一款月流水过亿的H5游戏——《传奇来了》。

紧接着,在微信发布小游戏后,第一时间发布了引擎5.1版本正式支持微信小游戏,《海盗来了》通过白鹭引擎的底层支持,仅用3天便将游戏从H5版本发布到微信小游戏平台,成为首款月流水过亿的微信小游戏。

回顾白鹭引擎的历史,我们就会发现,随着软硬件的不断升级以及白鹭引擎每个版本迭代的持续努力,不断的刷新着 H5游戏行业的新高度。但我们并未躺在过去的功劳簿上,仍然在持续高效率的进行版本迭代。

白鹭引擎目前按照双周迭代的节奏,同时发布5.2稳定版与5.3特性版本,如果开发者想要开发商业化游戏,可用5.2稳定版本来做;如果你想使用一些新的特性,比如说3D以及一些2D的高级优化技巧,就可以使用白鹭引擎最新的5.3版本来做。
图片描述
白鹭引擎目前在H5游戏的市场占有率达到了70%。统计方法是:取样爱微游、疯狂游乐场以及QQ空间三个业内公认的头部渠道的Top30的游戏,逐一去看这些游戏采用了哪些游戏引擎。
图片描述
除了H5游戏之外,白鹭引擎在微信小游戏上的市场占有率53%。这里有两种统计方法:第一种统计方法是把所有能统计到的微信小游戏都统计起来,一个一个抓包看是什么引擎做的。

通过这种方式,统计到的白鹭引擎的市场占有率高达80%,但是我认为这是有失偏颇的数据,因为能统计到的小游戏有很大一部分是因为与白鹭官方人士有微信好友关系,而这部分好友几乎都在使用白鹭引擎开发微信小游戏,所以我认为这种统计方式是并不准确的。于是我们采用了另一种更为公平的统计方法,通过相对权威的阿拉丁统计数据,把阿拉丁榜单的Top50拉出来,得出白鹭引擎市场占有率为53%。
图片描述
据不完全统计,这五年中,白鹭引擎累计运转的H5游戏和微信小游戏的流水数据约为200亿。非常感谢大家对白鹭引擎的支持。今天能有这个成绩并不是完全是依靠白鹭自己做的,引擎技术并不能解决所有的问题,最大的外因是依靠各位一起努力的结果,特别是各位游戏开发者,浏览器底层技术提供方、渠道方、以及很多支持伙伴的帮助。

除了外因的帮助之外,白鹭自身也帮助开发者做了很多事情,我个人是Flash页游研发出身,白鹭引擎团队的大部分研发也都是游戏行业出身,所以白鹭的研发团队更了解也被称为“手机页游”的H5游戏开发者的痛点需求,并且这五年为各地的H5游戏开发者提供了总计1400天的驻场支持,飞到各个城市,包括广州、深圳、上海、厦门、福州、成都、武汉、南京、西安,当然还有北京。我平均基本上有三分之一的时间是不在公司里的,都在为各地的开发者解决各种各样的问题。通过这些比较务实、接地气的方式,保证白鹭引擎可以运行在尽可能多的设备上,并提升在低端机上的游戏体验。
图片描述
今天广州开发者沙龙的主题是“怎样做一款赚钱的小游戏”。我认为解决技术上的短板决定了游戏是否能赚钱的下限。针对游戏运营的几个关键数据,游戏的运行性能主要影响玩家的在线时长,游戏加载性能主要影响玩家的前期留存。我今天重点介绍如何提升游戏的运行性能。

我见过的大部分寻求技术帮助的 CP 都会提及游戏性能需要提升。但是我认为性能糟糕是一个技术术语,它在产品上一般有如下四种体现方式:
1、帧频很低。
2、设备发热。
3、不定期卡顿。
虽然看起来这些问题都是性能问题,但是产生这些问题背后的原因则是完全不一样的。

在解决问题之前,需要将这些问题首先输出一个可量化的数据指标。

帧频很低可以被量化为:在特定设备上的帧频是XX帧,其中 JavaScript 逻辑开销 XX毫秒,渲染开销YY毫秒,这些数据在白鹭引擎的性能面板中都有体现。

设备发热看似是很难量化的,并不是所有操作系统都提供了设备温度的 API。因此我们向开发者推荐另一种方法作为量化方式,首先将设备充满电,然后统计游戏在 XX分钟后的剩余电量。由于耗电量和发热基本成正比,所以解决耗电问题,发热问题就也能同步得到解决。

至于不定期卡顿。一定要记录卡顿是否存在规律。比如是播放动画的瞬间?打开UI面板的瞬间?或者是毫无规律?
图片描述
上述问题量化之后,接下来再来逐一地尝试解决这些问题。

帧频低和发热主要有如下四个原因:
1、渲染内容过多。
2、渲染方式不当。
3、计算开销过大。
4、 大量创建对象。

这四点又分属两个类别,分别是 JavaScript逻辑开销和引擎渲染开销。关于渲染内容和渲染方式不当最终是可以在引擎渲染层这个环节想办法解决的。而计算开销过大和大量创建对象都是在用户逻辑的JavaScript层去解决的。这两块的解决方式是完全不一样的,对渲染来说,你需要去尝试理解WebGL底层的渲染原理是什么,而对于JavaScript,你需要了解JavaScript底层的一些原理。

首先聊聊引擎渲染层面的东西:
1、渲染内容过多。在屏幕之外的内容,可以设置隐藏,不要执行渲染。这就提到一个很有意思的问题了,看似很简单优化方法为什么不在白鹭引擎内部实现呢?其实这涉及到白鹭引擎的一个核心设计理念:不要替开发者去做“自作聪明”的优化。这样才能保证优秀开发者做出更好的游戏。除了屏幕外的内容不进行渲染之外,游戏普遍有很多UI弹窗,当你打开弹窗的时候,强烈建议你把游戏背景隐藏,这同样可以节省大量的渲染开销。

2、渲染方式不当。来看看底层原理:
图片描述
白鹭引擎2D是如何渲染游戏的多张纹理的? 在白鹭引擎里,2D是一次性提交所有的数据,然后设置渲染模式,执行渲染批次,再设计渲染模式,再执行渲染批次。如果你能保证渲染模式这个东西是没有发生变化的,就可以一次尽可能多地渲染,在这种情况下就可以做一次的渲染批次,这个优化听起来很简单,我说说在实际游戏里的典型案例。
图片描述
这张图是我昨晚自己画的示例图。做游戏时经常会遇到这样的场景,就是有很多人、很多怪,每个人都包含了影子、模型动画、血条三个部分。最简单的渲染方式是,将一个人设置成一个 DisplayObjectContainer,这个对象有三个子对象:一个人、一个影子和一个血条,这样每个人的渲染次数就是3,进而8个人的渲染次数就是24。优化后是10,如何做这个优化?方法非常简单,就是你把所有的影子放在一个Container上,把人放在一个Container上,再把血条放在一个Container上。

由于所有影子的纹理都是一样的,所以引擎底层会自动开启批次合并,渲染次数是是1,然后渲染8个人,这8个人的纹理一般都是不一样的,所以就是8,上面就是血条的纹理也是一样的所以也是1。把这三者加起来,最终的优化结果就是从 24降低到10。
图片描述
第二个示例。这是大家做的重度游戏的典型UI,DrawCall是30,这种游戏可以做很多优化,就是把所有的图片、文字合成一张纹理集。这个全做完之后,渲染批次就从30变成2,之所以不是1而是2,是因为右上角的lv888肯定是个动态文本,无法参与批次合并。

所以这就是一个简单的例子,希望大家以后做UI 时可以尝试着去把所有的动态文本都尽可能放在最上层,把图片都放在下层,并将这些图片合并成纹理集。特别是在游戏的 ListItemRenderer 之中,一般游戏中的一个 List 至少会显示 5个 ListItemRenderer,如果你能将 ItemRenderer的DrawCall降低5,那整体的 DrawCall就能降低 25,所以针对ListItemRenderer的优化是投入产出比非常高的,强烈推荐各位开发者重点优化这里。
图片描述
3、计算开销过大。对骨骼动画使用缓存,优化骨骼开销;避免大量的数学计算与浮点数计算;逻辑帧与渲染帧分离。这个提升是比较明显的,因为很多游戏都是做30帧的,但是现在有些是60帧,所以要作一些逻辑帧和渲染帧的分离,逻辑上可以是15帧,然后渲染上做60帧,那么逻辑的开销就可以少很多。
图片描述
4、还有一个是非常重要的大家可能不太注意的,就是大量创建对象。JavaScript虚拟机有一个特点,就是对象创建的开销远远大于对象计算的开销,并且对象创建会导致垃圾回收,而垃圾回收会导致游戏不定期卡顿,所以有一个很重要的原则就是不要在你的主循环里创建任何对象,强烈建议游戏中的人物、怪物、技能特效统统做成对象池,这样可以大幅降低游戏的不定期卡顿现象的出现。分享一个常用的测试函数。
图片描述
来看这个函数的原理。它就是显示了每一秒钟去拿一个hashCount跟上一个hashCount作对比,这个hashCount是由白鹭引擎内部 API,用于统计引擎对象的创建数量。如果你的游戏静止放置不动,那么理论上hashCount diff的结果应该是0,实际上要尽可能控制在120以下,我给大家分享一个数据,我见过的最赚钱的那一批游戏的 hashCount diff 都控制在120以下的。

如果这个数字超标,应该如何去解决呢?只需要在引擎的 HashObject 的构造函数这里添加一个断点,在运行时去检查调用堆栈就可以了。

我协助优化过一款产品,它的hashCount diff数字高达4000,每秒创建4000个对象,我调试他的代码后发现,其实只是一个很小的问题导致了这个结果,花了15分钟修复之后,游戏的发热、卡顿等问题都得到了大幅的缓解。

接下来我跟大家介绍一下白鹭的3D引擎的核心功能,以及内部优化技巧,也给大家做重度游戏时以一些启发。
图片描述
Egret3D内部的所有资源都采用了GLTF文件格式。这是一种对OpenGL ES、WebGL非常友好的3D内容格式标准。面向实时渲染,尽量提供可直接传输给图形API的数据格式,而不再需要反序列化。
图片描述
刚刚我提到了尽量提供可直接传输给图形API的数据格式,在 Egret3D内测版本中,在3D引擎加载一个模型文件,需要首先加载了模型文件,然后解析模型文件,这就像配置文件一样。第三步要生成WebGL所需要的数据格式,最后把它提交到GPU。而在正式版本的流程变成了加载新的 GLTF文件,进而由于GLTF的文件格式和GPU想要的文件格式是几乎一样的,所以不需要解析也不需要生成,直接把它作一个简单的ArraryBuffer切割,然后提交到 GPU就可以了。

通过这个优化达到什么样的效果?模型解析速度提升170%,内存占用降低1倍,加载速度提升30%,所有这些优化的底层的本质原因是由于底层采用了GLTF的模型文件的标准范式。这就相当于是白鹭引擎3D版本的比较常见的引擎优化。
图片描述
《泡泡学园OL》是白鹭自研团队打造的一款标杆品质的3D微信小游戏。在这款游戏制作过程中,不断挑战 Egret3D 与微信小游戏的性能极限极限,具体技术指标包括: 100,000 Vertex , Lightmap贴图、GPU骨骼动画,GPU粒子动画,碰撞引擎,帧同步网络通讯,基于行为树的AI 等。
这款游戏前期开发过程中使用了 Unity3D 编辑场景,然后通过白鹭引擎的 Unity3D导出插件发布到 Egret3D 中。目前已经使用白鹭引擎正在研发的 3D 编辑器进行后续开发和维护。

图片描述
目前白鹭科技已经发布了 Egret3D的1.1版本,即将在9月底发布1.2版本,这个版本重点针对开发者的开发效率进行优化,首先是推出一款可视化的调试工具 Egret Inspector 3D ,其次就是将3D编辑器提供给更多开发者进行试用并收集反馈,如果您已经使用 Egret3D 立项并进入项目开发阶段,可以优先试用3D编辑器。
图片描述
以上就是我为大家分享的全部内容。谢谢大家!

这篇关于白鹭引擎王泽:重度H5游戏性能优化技巧的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/415021

相关文章

Vue3 的 shallowRef 和 shallowReactive:优化性能

大家对 Vue3 的 ref 和 reactive 都很熟悉,那么对 shallowRef 和 shallowReactive 是否了解呢? 在编程和数据结构中,“shallow”(浅层)通常指对数据结构的最外层进行操作,而不递归地处理其内部或嵌套的数据。这种处理方式关注的是数据结构的第一层属性或元素,而忽略更深层次的嵌套内容。 1. 浅层与深层的对比 1.1 浅层(Shallow) 定义

Ilya-AI分享的他在OpenAI学习到的15个提示工程技巧

Ilya(不是本人,claude AI)在社交媒体上分享了他在OpenAI学习到的15个Prompt撰写技巧。 以下是详细的内容: 提示精确化:在编写提示时,力求表达清晰准确。清楚地阐述任务需求和概念定义至关重要。例:不用"分析文本",而用"判断这段话的情感倾向:积极、消极还是中性"。 快速迭代:善于快速连续调整提示。熟练的提示工程师能够灵活地进行多轮优化。例:从"总结文章"到"用

性能测试介绍

性能测试是一种测试方法,旨在评估系统、应用程序或组件在现实场景中的性能表现和可靠性。它通常用于衡量系统在不同负载条件下的响应时间、吞吐量、资源利用率、稳定性和可扩展性等关键指标。 为什么要进行性能测试 通过性能测试,可以确定系统是否能够满足预期的性能要求,找出性能瓶颈和潜在的问题,并进行优化和调整。 发现性能瓶颈:性能测试可以帮助发现系统的性能瓶颈,即系统在高负载或高并发情况下可能出现的问题

HDFS—存储优化(纠删码)

纠删码原理 HDFS 默认情况下,一个文件有3个副本,这样提高了数据的可靠性,但也带来了2倍的冗余开销。 Hadoop3.x 引入了纠删码,采用计算的方式,可以节省约50%左右的存储空间。 此种方式节约了空间,但是会增加 cpu 的计算。 纠删码策略是给具体一个路径设置。所有往此路径下存储的文件,都会执行此策略。 默认只开启对 RS-6-3-1024k

性能分析之MySQL索引实战案例

文章目录 一、前言二、准备三、MySQL索引优化四、MySQL 索引知识回顾五、总结 一、前言 在上一讲性能工具之 JProfiler 简单登录案例分析实战中已经发现SQL没有建立索引问题,本文将一起从代码层去分析为什么没有建立索引? 开源ERP项目地址:https://gitee.com/jishenghua/JSH_ERP 二、准备 打开IDEA找到登录请求资源路径位置

使用opencv优化图片(画面变清晰)

文章目录 需求影响照片清晰度的因素 实现降噪测试代码 锐化空间锐化Unsharp Masking频率域锐化对比测试 对比度增强常用算法对比测试 需求 对图像进行优化,使其看起来更清晰,同时保持尺寸不变,通常涉及到图像处理技术如锐化、降噪、对比度增强等 影响照片清晰度的因素 影响照片清晰度的因素有很多,主要可以从以下几个方面来分析 1. 拍摄设备 相机传感器:相机传

购买磨轮平衡机时应该注意什么问题和技巧

在购买磨轮平衡机时,您应该注意以下几个关键点: 平衡精度 平衡精度是衡量平衡机性能的核心指标,直接影响到不平衡量的检测与校准的准确性,从而决定磨轮的振动和噪声水平。高精度的平衡机能显著减少振动和噪声,提高磨削加工的精度。 转速范围 宽广的转速范围意味着平衡机能够处理更多种类的磨轮,适应不同的工作条件和规格要求。 振动监测能力 振动监测能力是评估平衡机性能的重要因素。通过传感器实时监

MySQL高性能优化规范

前言:      笔者最近上班途中突然想丰富下自己的数据库优化技能。于是在查阅了多篇文章后,总结出了这篇! 数据库命令规范 所有数据库对象名称必须使用小写字母并用下划线分割 所有数据库对象名称禁止使用mysql保留关键字(如果表名中包含关键字查询时,需要将其用单引号括起来) 数据库对象的命名要能做到见名识意,并且最后不要超过32个字符 临时库表必须以tmp_为前缀并以日期为后缀,备份

黑神话,XSKY 星飞全闪单卷性能突破310万

当下,云计算仍然是企业主要的基础架构,随着关键业务的逐步虚拟化和云化,对于块存储的性能要求也日益提高。企业对于低延迟、高稳定性的存储解决方案的需求日益迫切。为了满足这些日益增长的 IO 密集型应用场景,众多云服务提供商正在不断推陈出新,推出具有更低时延和更高 IOPS 性能的云硬盘产品。 8 月 22 日 2024 DTCC 大会上(第十五届中国数据库技术大会),XSKY星辰天合正式公布了基于星

滚雪球学Java(87):Java事务处理:JDBC的ACID属性与实战技巧!真有两下子!

咦咦咦,各位小可爱,我是你们的好伙伴——bug菌,今天又来给大家普及Java SE啦,别躲起来啊,听我讲干货还不快点赞,赞多了我就有动力讲得更嗨啦!所以呀,养成先点赞后阅读的好习惯,别被干货淹没了哦~ 🏆本文收录于「滚雪球学Java」专栏,专业攻坚指数级提升,助你一臂之力,带你早日登顶🚀,欢迎大家关注&&收藏!持续更新中,up!up!up!! 环境说明:Windows 10