標籤:

使用英特爾GPA優化《軒轅傳奇》遊戲的性能

當年和Intel一起優化寫的一篇使用GPA做性能優化的文檔,其實當時對State Changes的性能開銷估計有些偏差,即使最後做了Shader排序大幅降低了渲染狀態切換數性能也只有5%的提升。現在手機版的GPA還是非常好用,特別是能適用在任何GPU的設備上。

介紹

隨著集成顯卡功能和性能的日益增強以及移動平台的不斷普及,集成顯卡已經成了遊戲開發者不可忽視的重要對象。

本文介紹了使用GPA在英特爾集成顯卡上分析和優化《軒轅傳奇》網路遊戲的案例。

《軒轅傳奇》是由騰訊研發團隊打造的一款MMORPG網遊,是騰訊的首款史詩戰爭網遊。該遊戲在引擎技術、美術、伺服器等諸多方面都力求精益求精,達到了國內頂級網遊水準。為了滿足更多玩家的機器配置,我們特別針對集成顯卡進行了測試和優化。

性能分析開始

本文檔的分析和優化基於Intel HD Graphics 3000平台,代號SandyBridge(簡稱SNB)。

SNB是Intel在2011年推出的一款性能非常出色的處理器集成顯卡。它的性能可以媲美一些獨立顯卡。作為一款網路遊戲,《軒轅傳奇》的開發者希望能夠在更多的平台上面流暢運行遊戲,所以儘管遊戲在SNB上的性能已經很流暢了,我們還是要盡量的對遊戲性能進行優化。

以下是我們這次性能分析和優化所選擇的目標場景:

系統分析

GPA HUD能夠實時的顯示遊戲運行的時候CPU,DX

runtime,以及GPU上的性能數據。同時支持多種D3D流水線上的override模式,幫助遊戲開發者進一步定位遊戲的瓶頸所在。

通過GPA HUD的分析,我們發現:

1.遊戲的大多數計算都是在主線程中完成,多核心利用率比較低。那麼在玩家角色多的時候,因為動畫計算比較多,CPU將會成為瓶頸。可以考慮使用多線程來消除這種場景下的瓶頸。

2.遊戲中每幀的State Changes數量不算很多,大概每幀6000個,平均每個DP call

7.5次。能夠做一些優化減少State Changes數量的話,對性能是很有好處的。

3.通過Override模式測試,Null Driver, Null Hardware

都可以使遊戲的fps達到100左右,100fps是遊戲的限幀。所以在該場景下遊戲的瓶頸是在GPU上。我們還在玩家角色比較多的場景進行了類似測試,發現Null

Hardware對fps提升不大,此時瓶頸在CPU上。

幀分析

GPA幀分析器能夠詳細的分析遊戲的一幀的所有draw

call的性能數據以及它們所使用的紋理,d3d狀態,shader等等。圖2顯示了我們使用GPA幀分析器打開我們在目標場景抓取的一幀數據。

通過幀分析器分析,我們得到整個一幀的時間分布為:

生成陰影貼圖:~170 個 DP Calls,

15.9% frame time。場景中所有的物體都計算了實時陰影。我們可以使用靜態陰影來替代其中的一部分,比如某些距離遠的,固定的物體。

天空盒: 3個 DP Calls,4.7%

frame time。實際上在該場景中看不到天空,我們可以在渲染天空盒之前進行可見性檢測。如果不可見,則不渲染。

Terrain:50個 DP Calls,34.9%

frame time。和大多數網路遊戲一樣,地形總是最耗時的部分,是優化的重點。

人物和其他地上物件:~240個DP

Calls,22.4% frame time。沒有發現明顯的可以優化的地方。

後處理:8個DP Calls,8.4% frame

time。沒有發現明顯的可以優化的地方。

UI:55 DP Calls,7.4% frame

time。有許多UI元素過小,可以合併一下再渲染。UI並不是每幀都變化的,可以重複利用上一幀的結果。

優化策略和結果:

1. 陰影貼圖生成

遊戲花費了花費了~170個draw

calls來生成所有物體的陰影貼圖,但實際上,場景中某些固定的物體或者遠處的物體,是沒有必要使用實時計算的陰影的,使用提前生成的靜態陰影即可。這可以節省draw

calls的數量,提高性能。圖3是優化前後的對比,右邊是優化後的陰影貼圖生成,減少了使用實時陰影的物體數量,可以看到draw

calls數量減少到了45個,整個陰影地圖生成花費的時間從2.97ms減少到了1.03ms。

2. 天空盒

天空盒在這個場景中是不可見的,但是幀分析器顯示遊戲依然渲染了它。我們可以在渲染之前檢測天空盒的可見性,如果不可見,則不渲染。這可以節省0.88ms。而且,天空盒最好是放到場景中不透明物體渲染完之後再渲染,因為天空盒的大部分都是被遮擋的。

3. 地形

地形部分的渲染佔用了最多的時間,網路遊戲一般都是這樣。

其中一部分主要的地形,佔用了6.5ms中的5.1ms,它們使用的同一段Pixel Shader,以下是這部分地形的截屏:

過幀分析器我們可以看到,這部分地形的渲染,PS duration佔用了90%的時間,在幀分析器中我們可以在Shader

Tab查看這些渲染所使用的shader code,如圖5所示,這部分地形的shader 包含了89條指令,其中13個紋理load,76個數學計算,比較複雜。

我們把shader做了一定的簡化,去掉了高光,normal map,AO map等。圖6是修改了pixel

shader後的截圖,修改後pixel shader包含31條指令,其中8個紋理load,23個算術指令。

這部分地形渲染的時間從5.1ms減少到了3.4ms。

我們還為特別低端的平台準備了更加簡單的,只需要2個紋理的shader版本,時間進一步減少到了0.93ms,見圖7所示:

當然,使用2個紋理後,地形畫面質量肯定有所下降。在GPA幀分析器我們能夠實時的看到修改shader code後對畫面的影響。

4. UI

UI部分共佔用7.4%的時間,圖8是遊戲中左上角的人物UI截屏。

通過幀分析器,我們發現為了畫遊戲左上角的人物頭像以及血槽等部分,遊戲使用了9個draw

calls來完成(圖9),而且是每一幀都會花費9個draw

calls來做這件事情。但是對網路遊戲來說,99%的時間,這部分是不會變化的,那麼每幀都使用9個draw

call來畫這部分,是沒有必要的。我們可以把這個頭像部分先渲染到一個image buffer,然後使用一個draw

call把這個image畫到屏幕上,如果下一幀這個頭像部分沒有更新,則繼續使用上次的這個image buffer。這樣一來,只有在頭像部分需要更新的時候,才去重新做這9次draw

calls,其他時候,只需要一個draw call就完成了。

圖10顯示了優化後的截圖,這一幀重利用了image buffer,只使用了一個draw

calls就完成了這部分UI的渲染。我們對其它的UI也進行了類似的優化。優化後,渲染UI所花費的時間從1.38ms減少到了1.17ms。

5. 減少State Changes數量

State Changes過多會導致遊戲程序,d3d runtime, 顯卡驅動和顯卡硬體的負載增加。減少State

Changes的數量能夠提高遊戲性能。通過幀分析器對這一幀的詳細分析,我們發現有很多的draw

calls,都會使用很小的紋理,16*16,32*32或者64*64大小,大量的使用小紋理,不是一種有效率的做法。圖11顯示了兩個相鄰的draw

calls使用了非常小的紋理:

從上面圖11中我們看到,臨近的的2個draw calls,分別調用了3個SETTEXTURE

API,其中第二和第三個texture,都是很小的紋理(見圖12)。我們可以合併這些小的紋理,然後只需要設置一次合併後的紋理,接下來的幾個draw

calls就可以直接使用,而不用再設置了。這可以減少State Changes的數量。當然,使用合併紋理的時候要注意設置正確的UV值。

圖13和14是優化後的截屏,我們合併了3個draw calls所使用的小紋理,SETTEXTURE

API調用的次數從9次減少到了4次。整個一幀,我們減少了~500次State Changes。

優化總結:

我們介紹了在英特爾集成顯卡平台上通過GPA對遊戲性能進行分析和優化的成功案例。GPA工具幫助我們找到了遊戲的瓶頸所在。我們使用它對一幀進行了深入的分析,對shader進行了實時修改,並找到了減少State changes數量的辦法。經過優化,遊戲性能得到了很大提升,能讓更多玩家流暢體驗軒轅傳奇這款遊戲。其實我們還使用GPA對其他不同場景,不同狀態(聊天,騎乘,戰鬥,換裝,技能特效等),不同平台(各個廠商的獨立顯卡,集成顯卡以及不同型號的CPU),不同系統進行了各種測試,限於篇幅這裡只挑出了一個有代表性的例子。


推薦閱讀:

看完性能簡報,想不優化好都難!
為什麼梯度的方向與等高線切線方向垂直?
軒轅傳奇場景優化筆記
如何根據網站日誌進行分析並做出優化改進?

TAG:优化 |