咱們的引擎架構師作某一沙龍活動的演講速記,純純的乾貨,分享給你們。瀏覽器
王澤:各位開發者下午好!我叫王澤,是白鷺引擎的首席架構師。緩存
今天給你們分享的題目是《重度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 都會說起遊戲性能須要提高。可是我認爲性能糟糕是一個技術術語,它在產品上通常有以下四種體現方式:
一、幀頻很低。
二、設備發熱。
三、不按期卡頓。
雖然看起來這些問題都是性能問題,可是產生這些問題背後的緣由則是徹底不同的。
在解決問題以前,須要將這些問題首先輸出一個可量化的數據指標。
幀頻很低能夠被量化爲:在特定設備上的幀頻是XX幀,其中 JavaScript 邏輯開銷 XX毫秒,渲染開銷YY毫秒,這些數據在白鷺引擎的性能面板中都有體現。
設備發熱看似是很難量化的,並非全部操做系統都提供了設備溫度的 API。所以咱們向開發者推薦另外一種方法做爲量化方式,首先將設備充滿電,而後統計遊戲在 XX分鐘後的剩餘電量。因爲耗電量和發熱基本成正比,因此解決耗電問題,發熱問題就也能同步獲得解決。
至於不按期卡頓。必定要記錄卡頓是否存在規律。好比是播放動畫的瞬間?打開UI面板的瞬間?或者是毫無規律?
上述問題量化以後,接下來再來逐一地嘗試解決這些問題。
幀頻低和發熱主要有以下四個緣由:
一、渲染內容過多。
二、渲染方式不當。
三、計算開銷過大。
四、 大量建立對象。
這四點又分屬兩個類別,分別是 JavaScript邏輯開銷和引擎渲染開銷。關於渲染內容和渲染方式不當最終是能夠在引擎渲染層這個環節想辦法解決的。而計算開銷過大和大量建立對象都是在用戶邏輯的JavaScript層去解決的。這兩塊的解決方式是徹底不同的,對渲染來講,你須要去嘗試理解WebGL底層的渲染原理是什麼,而對於JavaScript,你須要瞭解JavaScript底層的一些原理。
首先聊聊引擎渲染層面的東西:
一、渲染內容過多。在屏幕以外的內容,能夠設置隱藏,不要執行渲染。這就提到一個頗有意思的問題了,看似很簡單優化方法爲何不在白鷺引擎內部實現呢?其實這涉及到白鷺引擎的一個核心設計理念:不要替開發者去作「自做聰明」的優化。這樣才能保證優秀開發者作出更好的遊戲。除了屏幕外的內容不進行渲染以外,遊戲廣泛有不少UI彈窗,當你打開彈窗的時候,強烈建議你把遊戲背景隱藏,這一樣能夠節省大量的渲染開銷。
二、渲染方式不當。來看看底層原理:
白鷺引擎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的優化是投入產出比很是高的,強烈推薦各位開發者重點優化這裏。
三、計算開銷過大。對骨骼動畫使用緩存,優化骨骼開銷;避免大量的數學計算與浮點數計算;邏輯幀與渲染幀分離。這個提高是比較明顯的,由於不少遊戲都是作30幀的,可是如今有些是60幀,因此要做一些邏輯幀和渲染幀的分離,邏輯上能夠是15幀,而後渲染上作60幀,那麼邏輯的開銷就能夠少不少。
四、還有一個是很是重要的你們可能不太注意的,就是大量建立對象。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編輯器。
以上就是我爲你們分享的所有內容。謝謝你們!