GameRes報道 / 11月21日下午,由蠻牛精心打造的開發者線下技術交流平臺,第四屆蠻牛杯思享匯系列活動(北京站)在金長安大廈圓滿結束。來自蠻牛社區的遊戲開發者、VR行業、遊戲產業以及媒體記者等超120人。現場異常火爆,座無虛席,學習交流氛圍濃郁。緩存
會上,Epic Games 資深程序工程師王禰與你們分享了以「使用UE4製做VR內容的優化」爲主題的純純乾貨。分別從UE4引擎底層方面爲開發者作的一些優化內容,以及開發者本身自己須要用到的一些優化內容方面深刻講解。多線程
如下爲演講實錄:
你們好!今天我來這裏主要介紹的是使用UE4作VR內容的一些優化技巧。VR須要給你們一個沉浸式的體驗,這要求兩點:一點是你的畫面要儘量的精美,另一點是你的呈現要儘量的流暢。
這兩點實際上是相互矛盾的,由於你畫面作的越細緻、越精美,其實你的內容就越重,你的渲染壓力也就越大。你要作到75幀雙眼同時渲染難度就很是高。
咱們看用UE4引擎幫你作了多少事情,第一個已經早就完成了。引擎的輸入更新並非只有一次,傳統引擎輸入多是遊戲線程一開始有個輸入,把全部這幀的輸入都獲取。獲取完以後遊戲線程再計算遊戲邏輯而後送給渲染線程繪製。這種狀況下,假設咱們遊戲跑在60幀,最後更新的HMD或者其它輸入設備的最後數據,其實都是要有16毫秒左右的延遲。
最簡單能夠作的第一步是引擎在把數據送給渲染線程以前,咱們會把整個渲染的View Matrix從新更新一遍,遊戲邏輯是按照這一幀剛開始收集到的數據來計算。視點實際上是經過遊戲線程的邏輯線程幾乎已經結束後送給渲染線程來計算的。
爲何我要這麼說呢?由於引擎自己是多線程的,如今不少顯卡都有雙緩存或三緩存的。咱們繪製的這一幀,你看到的幀都是前幾幀的內容,這樣給你帶來的延遲是很是重的。少則也有40來毫秒的延遲,超過10毫秒延遲,你就很容易,稍微長一點時間就有不適感。這也是我剛說的,要下降延遲,首先要把渲染的多緩存關掉,也就變成了原本能夠多線程渲染的,不少時候須要線程等待遊戲邏輯線程的輸入計算完成才能作這一幀的數據渲染,這其實又對你的渲染壓力形成更大影響。
咱們第一步作的是在邏輯線程計算都結束之後從新更新了ViewMatrix。這個是對頭顯設備和輸入設備都作了一樣的操做,包括動做捕捉設備、手柄類的設備,你最後都要捕捉到它的動做。爲了讓延遲更低,因此咱們作了一個屢次的Deferred的輸入更新。
第二個是咱們最近剛作完的一個Demo。這裏有兩個功能,一個是叫Instanced Stereo Rendering,一個是叫HMD Distortion Mask,咱們最近測試基本上能在咱們的測試Demo上效率提高將近1倍,並且縱觀其餘市場上全部支持VR的引擎,尚未一家在使用這樣的技術。
HMD Distortion Mask,簡單介紹一下。你們都知道經過HMD設備鏡片畸變之後,其實圖像輸出以前是先要反向畸變的,反向畸變後四周實際上是黑的,根本不輸出內容的,如今大部分引擎的瓶頸也都是在Pixel Shader(像素着色器)或Fragment Shader(片斷着色器)上面,若是咱們能讓這些黑色的區域都不去計算PS(像素着色器),黑色的那些區域其實都不通過咱們Pixel Shader的運算。其實就能省掉很大的開銷,因此咱們作了這麼一個優化。
Instanced Stereo Rendering,這個功能簡單來講,咱們VR的輸入在引擎對接,一個是獲取你的ViewMatrix矩陣,在每幀更新時從頭顯設備得到輸入的ViewMatrix矩陣。另一個是使輸入的視點往兩邊偏移同距的寬度,來作立體渲染。立體渲染最簡單的作法,引擎的渲染由於已是定的,比較簡單的作法就是渲染兩遍,左邊眼睛渲染一遍,右邊眼睛渲染一遍,帶來的開銷就是DrawCall(繪製調用)數翻了1倍。你們作手遊可能對DrawCall都很敏感,尤爲是國內的狀況,由於國內如今500塊錢的手機已經算挺好的,主流的開發者面對的是一兩年前的500塊錢的手機,如今主流論點仍是手遊的DrawCall要控制在150如下。
我這裏隨便介紹一下,咱們Epic作的一個Demo在iPhone5和5s上就能跑得很流暢,跑到30幀的一個Demo。在AppStore上能夠免費下載,叫《Zen Garden(禪意花園)》。這個Demo咱們主要秀的一個技術就是蘋果的Metal的API,跟如今DX12,OpenGL Next就是Vulkan,包括以前AMD推的Mantle,這一系列你們的主流想法都差很少,包括Console(主機)的那些,好比說索尼一向的API其實都是這樣,我暴露給你更底層的控制,API的Level更低一點,你本身在引擎裏面去作Draw和Batch的優化。CPU上的開銷就會降到更小。一些作渲染的API,好比說DrawCall這樣的API,開銷不僅僅是在CPU上,GPU的開銷也很是大。這也是爲何移動芯片會對DRAW CALL那麼敏感,開發遊戲會要求你們把DRAW CALL限制在很低的程度。
使用了這些新的圖形API之後,對底層控制更細緻之後,咱們能夠作很大範圍的優化,好比說我剛纔介紹的《Zen Garden》Demo,最極端的狀況下,保持30幀的狀況下,渲染的DRAW CALL數能夠到5000、到7000,這是很是誇張的數值,在iPhone5IPhone和5s上可以跑起來的應用。這裏Instanced Stereo Rendering解決的也是一個相似的問題。
在大部分圖形API尚未更新到下一代以前,DrawCall那麼敏感,怎麼解決這個問題?你們考慮一下雙屏立體渲染的時候,視點作那麼小範圍的偏移,咱們繪製的內容幾乎是相同的,我Camera看到的東西基本上差很少,尤爲是場景裏的Mesh之類的Bounds通常都會超出一些,周圍兩個視角看到不同的東西,但都是須要繪製的。這個時候作Instance的思路是什麼?我這兩個繪製並非完整的繪製兩遍,而是把其中所繪製的Mesh作一個Instance。也就是說Mesh數會翻倍,而頂點數將近減半。
你們用過UE4能夠知道,咱們作大量草木渲染的時候,作大量一樣物件擺放的時候,咱們會用到叫Instanced Static Mesh Component這樣一個東西,這個東西能夠有一大批如出一轍的東西,它只記錄每一個Instance的Transform的Matrix,也就是說我只記錄它的Position、Uniform的Scale和Rotation的這些信息,每一個Instance只記這些信息,由於它用到的頂點信息都是同樣的。這樣就可把一批東西並在一個DrawCall上。雙屏渲染就是把兩屏的東西都當作一個Mesh的兩個Instance,這樣就能夠把原本翻倍的DRAW CALL減到跟之前同樣。假設你的場景自己已經有了大量Instance的狀況下,其實圖形API的Instance和Index Buffer也是有上限的,因此在這種狀況下,可能Instance的效果不是很明顯,但大部分狀況下,在座的各位普通狀況下作到的應用和遊戲裏面,這樣基本上都能提高50%以上的效率,這些技術如今是隻有咱們支持的。
咱們如今正在作,可能在12月中,或者到明年初就會提供的功能,這個跟AMD還有Nvidia合做的,你們知道Nvidia作VR的GameWorks裏有一些功能,其實很是實用,包括多GPU的渲染,還有一個比較有用的多分辨率的渲染Multi-Resolution,由於咱們知道人眼都只對你關注的,看的中間位置比較敏感一些,因此其實屏幕中間的分辨率渲染的更高一點,周圍的渲染更低一點,這也是下降我剛纔說的Pixel Shader瓶頸問題,跟剛纔的HMD Mask有殊途同歸的妙處。
這裏是引擎內建已經有的內容,對於無論是第三方的硬件商,HMD的接入商,仍是對內容開發者來講,都是你們須要瞭解,但不須要關心的內容,這也是底層已經儘量的幫開發者作的一些優化。編輯器
下面我主要要講的內容仍是開發者本身自己須要用到的一些內容。爲了方便起見,咱們本身作的VR Demo都是通過深度優化的,我來剖析的話,前期的那些項目工程,我這裏其實也已經沒有了,因此剖析的效果可能不是那麼好。由於我拿到的數據都是優化後的數據,我這裏先隨便拿一個Demo來作一個簡單的剖析。
你們在MarketPlace上均可以看到,是Particle(粒子)的Cave這樣一個Demo。展現一些粒子效果,粒子原本就是很費的東西,這個Demo不是爲VR準備的,因此這個Demo在VR設備上跑起來,幀數很是低,可能只有三四十幀。
咱們來看一下大概的一個優化思路是什麼樣子的。固然第一步很簡單粗暴,先看看瓶頸在哪裏。這些命令對於使用過UE4或者稍微有一些Profiling經驗的人確定是第一步要作的事情。既然要優化,就要把力量花在你該花的地方,第一步確定是查找你的瓶頸,看看是CPU Bounding仍是GPU Bounding。第二步Stat fps就是看FPS,若是FPS已經知足了,固然進一步優化老是好事,可是也沒有必要,由於畢竟優化也是要花費人力、物力的,已經知足你的目標,就沒有進一步優化的必要。
若是沒有知足,接下來Stat unit這個東西主要有三個數據信息,你們能看到這裏有一個是Game,一個是Draw,一個是GPU。Game是遊戲邏輯線程這一幀所耗費的時間。Draw也是GPU端的,是渲染線程所耗費的時間。GPU就是GPU耗費的時間。從這裏就能推斷出你是CPU端的Bounding仍是GPU端的Bounding,是邏輯線程的Bounding仍是渲染線程的Bounding。
對於VR內容,我我的認爲以如今的硬件來看,CPU邏輯線程Bounding的可能性幾乎爲零。若是是CPU邏輯線程Bounding,必定是哪裏的實現或設計出現了嚴重的問題。由於VR體驗裏不會有很是重的邏輯運算。
我看到那麼多VR Demo裏面,邏輯運算最重的應該是咱們本身作過的一款叫《Bullet Train》的Demo,裏面有很是大量的AI,有尋路,是一個相似第一人稱射擊的遊戲,有各類設計的彈道都是ProjectTiled的實體,而不是一個射線檢測,因此動態運算量,CPU的運算量會比較大,但即便是這樣,CPU仍是很富裕。跟傳統遊戲來比,咱們的電腦CPU已經很是強了,VR對於邏輯的要求,其實跟普通的大型遊戲來比是要輕得多的,因此CPU的Bounding,若是是邏輯線程的Bounding,通常來講意味着哪裏代碼寫的有問題。
好比說大量是靜態的對象,你可能如今是動態的在Tick,而後Tick裏面你作了一些,好比說很是長的空循環之類的不合理的行爲,這個東西其實經過咱們的Profiler能夠很容易一眼就看出來。
我今天要講的大部分都是GPU的Bounding,一個就是我剛纔說的,若是你Draw Call偏高的話,實際上是同時渲染線程Bounding和GPU Bounding都會發生。由於有時候渲染線程是要等GPU的,你看到數字,這裏能夠看到GPU是28毫秒,總的Frame時間也是28毫秒,毫無疑問就是GPU Bounding。由於這裏面用了大量的Particle和大量的半透,並且是比較暗的場景,確定Translucency會佔的比重比較大一點,這個色調確定也是後期處理可能佔的比重也比較大一點。
通常來講GPUBounding的更大的可能性都是在Pixel Shader上面,我剛纔說的這兩個都是影響Pixel Shader的,這是第一感受看場景之後的。接下來咱們來看看具體用什麼比較快的方法能定位問題,而後解決咱們的問題。
第一步能作的,這是一個命令行HMD SP 100,咱們的HMD接入的設備大部分都有這樣一個Debug的命令行,叫HMD SP,SP(Screen Percentage)是屏幕的比例,至關因而輸出分辨率是固定的,但Render Buffer的分辨率能夠調整,100%之後,你會以爲畫面有點糊,不夠精細,由於眼睛看的是當中的,因此通常咱們默認值是120%,若是你的渲染幀數有富裕,甚至調到150%也是能夠的,並且這個命令是實時生效的,你能夠在遊戲過程當中,根據不一樣的關卡,甚至不一樣的進程,Camera的位置,來控制參數調整到不一樣的值,能夠在運算比較富裕的時候,展現更精細一點的效果,在優化壓力也很大,沒有辦法作進一步優化的狀況下,讓畫面稍微變的糊一點,讓幀數有比較好的提高,這個效果是很是明顯的。
你們看到通過調整之後,咱們的整個一幀的渲染時間,已經變到了1八、19毫秒,剛剛是28毫秒,已經減掉了三分之一,很是很是的明顯,說明就是Pixel Shader的Bounding,很明顯。通常來講咱們判斷是Pixel Shader瓶頸,仍是Vertex Shader瓶頸,最簡單的作法就是設置分辨率。HMD的輸出分辨率固定,沒有辦法設置,因此咱們提供了這樣一個Debug命令行,你經過這個調整,就能立刻知道,首先能肯定是否是GPU Pixel Shader的Bounding,是這個Bounding的話,而後來看影響有多少,並且這個值,雖然理論上是越高越好,可是其實有時候也跟內容有關係。好比說我內容色調不同,可能對銳度、精細度的邀請也沒有那麼高,有時候100徹底能夠接受,甚至咱們有些Demo就是放到90的,你們有沒有感覺?有什麼不對的地方。這個就是根據項目來,對你來講優化壓力比較大,你能夠把這個參數放小一點,這是一個最立竿見影的調整效果。
接下來這個是Editor裏面內建的,咱們是調整整個渲染Quality的Scale Ability的設置,原本默認都是開在Epic上面,Epic是最牛逼的畫面效果,我如今先把它調到中等,一會兒13毫秒,爲何是13毫秒?實際上是由於咱們限制了幀數75幀。事實上,若是咱們把幀數限制關掉之後,發現可能更短,可能已經能跑到100多幀,這是一個最快的效果。你們看到已經到75幀,是否是知足咱們優化的效果了?能夠說是,但確定也不是,由於這是以犧牲大量的畫面的渲染效果爲前提的。作這樣一個設置,只是爲了讓咱們快速的定位到哪一檔差很少的設置能知足咱們的幀數要求。
接下來要作的就是比較細緻的分析,到底哪些地方有問題了。有一個Profiling的命令行叫Profile GPU或GPU Profile都同樣,這兩個命令行的快捷鍵是「Ctrl+Shift+,」,這個東西在Editor裏面,或者在遊戲Runtime均可以實時的運行,你只要輸入這個命令,咱們就會作這一幀的GPU Profiling。我是推薦你們不要在編輯器裏作,起碼出一個Standalone的進程來作這件事。由於編輯器Slack等各方面也都是要通過渲染前的開銷的,這些東西可能會誤導你對Profiling一些開銷的判斷,因此最好是在Standalone的Game裏面來作這樣一個Profiling行爲。
作完後你們能看到,比較大頭的幾個,一個是Base Pass,一個是Deferred Decals,一個是Lighting,而後是SSR(Reflection Environment),而後是剛剛說到的半透(Translucency),而後是一個後期處理效果(Postprocessing)。最厲害的是Base Pass和Postprocessing。渲染管線至關複雜,我這裏不會更細的闡述,由於你們製做內容可能也不是那麼關注引擎底層的細節。
我先簡單說一下基本的概念。咱們默認是把Pre Z Pass關掉的,若是你看到Base Pass高,引擎提供了很大的便利性,咱們有一個命令行,能夠打開Early Z Pass,這樣會影響DRAW CALL,由於有些東西會先繪製一遍。帶來的好處是Base Pass的開銷會大量下降,這個須要你根據本身的場景去嘗試。你看看是打開Early Z Pass總的GPU開銷來的高,仍是關掉來的高。在這裏會發現打開Early Z Pass會帶來很大的收益。
你們看到以前是總共一幀用掉了12毫秒,優化後只用掉了8毫秒,另外幾個Decal,咱們看你的鏡頭所在位置,首先這個跟你的VR設計內容有關係。若是你看到場景在移動,你本身沒有在移動,尤爲移動速度比較快,並且不是線性狀況下,人很容易暈,如今不少作VR內容的開發者都從設計層面上解決這個問題,固然咱們有能夠移動的設備,可是這個設備對大部分人來講,還算是不太實際的設備。從設計上規避,咱們儘量的站在原地不動,而後用Teleport。甚至我能夠提供一個思路,好比說我要移動到另一個地方,好比說按鍵或者手柄各類操做之後,我看到一個虛擬的Avatar。我站在這裏,我看到一個第三人稱的角色往那邊移,Camera並無移動到那邊。而後我把某個鍵鬆掉,而後人就Teleport過去。以這樣的形式來呈現就能夠避免暈眩。
在這種狀況下,咱們大部分的時候視點都是固定的,這時候會發現不少位置的貼花Decal等,在屏幕上佔的象素很是低,這種狀況下能夠把它去掉。咱們知道用這種技術是爲了提高畫面效果,但有些時候你須要作一些取捨,好比說這個東西帶來的提高不那麼明顯,那你就能夠去掉。Translucency也是同樣。
不少粒子特效,尤爲是糊到你臉上的東西是很是很是費的,半透的儘量不要使用。而後就是後期處理,大部分後期處理確定都是全屏的都要處理的,因此儘量的減低後期處理,咱們在大部分的Demo裏面都是沒有使用後期處理。
這幾個優化完以後對幀數的影響很是明顯,咱們剛纔已經看過了調整分辨率是會很大的提升幀數的,說明是Pixel Shader的Bounding,咱們作的這一些包括Translucency和Decal,這些大部分都是影響了提高這一部分的效率。這是優化完之後,優化完之後幀數就已經到75幀了,這是由於剛說過這裏限幀了。其實如今已經120幀,甚至150幀了。
咱們把畫面配置效果,剛剛調過去了,忘調回來了,咱們如今調回來,好像依然有75幀,就是說剛剛優化起到效果了。一開始咱們作這樣一個設置是下降畫面質量,提高幀數,在咱們進一步分析之後,如今咱們能把畫面效果再從新調回來,依然達到比較流暢的幀數。
另外還有一些手段,好比說用咱們內建的編輯器裏面的一些ViewMode,就能看到好比說這裏的Shader的複雜度,那些有大量半透的粒子,有一些貼花的地方顏色都會比較深。咱們的這個ViewMode裏的綠顏色就說明Shader是比較簡單的,紅色就是說明Shader比較複雜,粉色就是很是很是複雜,白色就已經複雜的一塌糊塗了。通常來講,咱們場景都會控制在紅色和綠色之間,若是發現你有大量的粉色和白色,Shader確定已經太過複雜,必定要作比較針對性的優化。
下面的Stat scenerenering,這個也能夠看總的DRAW CALL數量,咱們最近在970上能夠跑到75幀的Demo,我剛纔說的叫《Bullet Train》的Demo,視野最開闊的時候DRAW CALL有1500多,其實已經很是高了。最近CryTek剛剛出來一個恐龍的那個在Steam上免費,那個DRAW CALL數比咱們低,固然頂點數很高有大概8M,它的Index Buffer也很高,由於它是大量的草木環境,因此它用了巨量的Instance,可是在其餘的環節上都是咱們的數據要高的多,由於我剛剛說到的,咱們作的那個Instance Rendering和HMD Mask的優化,因此使得咱們能有比較好的效率,能在大量渲染的負擔更重的狀況下,能有一個更流暢的效果。
Stat Scenerenering就能夠看到咱們比較細緻的一些渲染的Profiling數據,甚至你能夠經過,好比說有不少Particle,甚至有些有比較複雜的UI,又會有一些Decal,一些Static(靜態的)和動態的Mesh,,你來第一時間衡量,哪些東西對你的渲染形成最大的影響,你能夠先把這一幀的渲染停下來,而後咱們有一個Show Flag,能夠把每一類我剛說的東西去開關,來看看這些東西對DRAW CALL和幀數的影響。
例如,若是你發現Static Mesh一關,好像DRAW CALL影響從1500降到了可能只有三、400,說明基本上全部的開銷都是在Static Mesh上面,可能須要場景美術去作更大的優化。若是也就降到八、900,說明你有很大的開銷在其餘上面,你去優化場景是得不償失的。
ViewMode、Wireframe能看到咱們的網格信息,這裏你能看到,好比說比較遠的地方網格很是密,你們知道,若是一個三角面片渲染在2x2象素之內是很是浪費的。我剛纔說的在設計上,咱們不少內容都是視點固定的,既然在這個視點看到的內容離你那麼遠,密度就徹底不須要那麼高,這時候你能夠儘量的對模型作一些簡化。
剛纔我說的這是一個很是快速的例子,就是拿一個實際的例子來說,我隨便拿到一個Demo,用什麼樣比較快的方法能優化到一個能夠在VR裏面跑起來,致使你不暈眩的一個效果。實際上若是你真的作優化,其實有很是多的東西要來關注。
我接下來講的東西可能更細緻一點,可是整體思路跟剛纔同樣。咱們先是尋找限制你幀數的緣由。測試以前,先要找到一個穩定的環境。咱們在作GPU Profiling的時候,我但願不要在編輯器模式下跑,但願你在Standalone的Game裏面跑,或者你即便是在編輯器裏面,你也用編輯器去跑一個Standalone的進程,而後來作Preview。你在測試的時候,由於Camera移動,你的Oculus Update的信息都是不同的,你可能會針對一些,好比說某個角度幀數特別低,你能夠把遊戲邏輯停下來,而後把渲染也停下來,這時候你能夠用Debug Camera去看看你調的內容,以及不該該被繪製的內容是否是被繪製了。
剛剛我也說到還有一點,咱們有一些幀數設置,你能夠去把限制最高幀數的設置先打開,由於在咱們下降整個渲染效果之後,很容易就到上限了。因此在作優化的時候,但願先把幀數上限去掉,而後把垂直同步關掉。
這些都是在判斷問題和調試以前要建立的一個比較穩定的環境,固然包括你的目標硬件有沒有在跑其餘程序,這些都是有關係的。咱們但願在一個比較穩定的環境下,你最終的目標環境下來作這樣一個測試。
這個我剛剛大概解釋過了,就是用Stat unit能夠看到這幾個模塊每一幀耗費的毫秒數。這個就能看出來是GPU Bounding,而不是由於我設置了幀數的上限。由於若是我設置幀數上限,那必定是Game這裏的毫秒數最高,由於Game會去每一幀判斷是否是達到上限了,若是沒有達到上限,我還能夠Sleep,因此我主線程的時間會跟整個Frame是同樣。若是Game跟Frame同樣可能不是遊戲主線程瓶頸,第一點先查看是否限幀。若是達到目標幀數,又是Game和Frame數值同樣,基本上就是你限幀的關係。
SceneRendering這裏能列出最敏感的信息就是DrawCall,能夠看到這裏的DrawCall數量。DrawCall數量多的緣由上面說了,計算公式基本上是Mesh數量乘上ID再乘上投影的燈光數。
一個比較簡單且高效的優化手段是這樣,咱們提供了一些統計的工具在編輯器裏面,你打開Statistics統計面板,按照使用次數排序,能看到被你使用最多的Mesh對象是哪個,你看一下它的ID是多少,若是它的ID是負數個數,你有很大的可能性,能夠作一個很是快的優化。
好比用到了30個不同的Mesh資源,其中有50%是用了同一個資源,好比說我就渲染這樣一個場景,頗有可能大量的都是椅子,咱們先不說椅子作Instance的狀況,假設每一個椅子是一個獨立的Static Mesh Component的一個Actor,我發現椅子用了三個ID,相對來講我讓美術把ID合併一下,假設這個Mesh佔了一半,原本1500個DRAW CALL,其中有800DRAW CALL是椅子的,我改一下,這800裏面的三分之二就省掉了。並非說讓美術盲目的判斷Static Mesh形成的影響太大,我就讓美術把全部的Static Mesh,場景裏面的東西能合併的就合併,並非這樣。一個是Instance這樣的手段,一個是經過使用頻度來減小它的ID,優先減小頻度使用高的對象的ID。
另外你Staionary的燈光,或者動態燈光,儘量的減小,而且能不要投影的就不要投影,而且減小Overlaid(覆蓋)。
這裏就是我剛纔說的計算公式。這個命令行跟我剛纔說的另一種方式功能差很少。判斷一下有沒有什麼東西出錯的,這個命令行叫VisualizeOccludedPrimitives,綠色的框就是說這些被Occlude掉沒有繪製的Primitive對象。若是你發現有對象是在它後面的,可是並無被綠色的框畫出來,那就意味着有一些東西不對了。通常來講是什麼不對?通常來講是你的Bounds設的太大了。好比說尤爲是對於Static Mesh這樣的對象,若是你不是Root Motion的一些動畫,頗有可能我人站在這個位置,從這裏移動到那裏,其實個人Root沒有變化,這個時候個人Bounds自動就會變的很是大,最終的結果,我人明明站在某建築後面,被遮擋掉了,但仍是在繪製它,引擎認爲這個東西是可見的。這些狀況下,須要美術注意,能夠經過這樣的命令行來調試發現這樣的問題。
另外一種方式是,你Freeze住這一幀的渲染,用Debug Camera去漫遊這個場景,看看從你漫遊以前的Camera位置,須要被遮擋掉的那些對象是否是還能繪製的出來,若是繪製出來,必定是我剛纔說的好比說Bounds設置有問題。這個是跟我剛纔說的配合起來,ToggleDebugCamera能夠在Freeze Render那一幀狀況下,跑到它的背後去看看被遮蔽的東西有沒有能繪製出來,繪製出來了,就說明有問題。
還有就是ADB和bounding box的計算,若是你的東西不是LocalSpace有旋轉的話,其實它的Bounds也會變大。尤爲是長條的物件。
而後一個比較費的就是ParticleParticle,經過Stat Particle能看到Particle的詳細信息。能把一些特別費的Particle尤爲是靠Camera比較近的,半透比較多的,利用率比較高的那些作集中的優化。有一些比較離的比較遠的,你們能夠多作一些Particle的LOD。遠的那些其實不太敏感。咱們知道GPU在作立體渲染(Stereo Rendering)的時候,離屏幕近的那些ParticleParticle很容易穿幫。由於離視點越近,視差看到的位移就越遠。通常來講,咱們的遊戲引擎裏面的Particle都不是一個實體3D空間的對象,實際上是相似叫Billboard的東西。它永遠朝向你的Camera,當兩次渲染的時候,它永遠是朝向你左邊一個Camera,右邊是這樣的,並非實際在中間,視差到兩邊的例子。離你眼睛越近越大的Particle,在3D渲染下錯誤越明顯。這時通常會用一些創造性的做假手段,好比說用一個實體的Mesh來作這樣的Particle,咱們也有不少Demo來演示比較有技巧性的Particle。好比說爆炸,好比說一些煙霧軌道,我這裏就不着重介紹了。
我剛纔說的這些就是爲了說明,對屏幕影響比較大的Translucency這些Particle,大部分狀況下均可以轉化成Mesh的形式,並不必定要半透。這就是我剛纔說的咱們的一個統計工具,靜態場景的統計工具,能夠按照上面任何一列作排序。頂點數最多、使用數最多等等,按使用數最多排序,你能看到這個Mesh用了多少ID,是否是須要作進一步的優化。
還有一些比較Tips(技巧性)相關的功能,好比說能夠選中一組對象作一樣的優化。好比說這一組Mesh都要作一樣的優化,好比說這一組Mesh對東西的影響都比較小,我都不但願它接受Cast Shadow,或者說我都但願統一對它作某一些優化參數設置如LOD設置等,一個比較簡單的辦法,場景裏面選中它,右鍵能夠選中全部使用這個Mesh的對象,選中後你能夠打開一個叫Property Matrix的東西,這時候你能夠勾選本身須要用到的屬性,勾選了屬性之後,那個頁面上會把橫向是全部你選中的對象,縱向是你選中的屬性,以一個Matrix的形式列出來,你能夠很清晰的看到,你同一類對象的參數屬性。由於當美術不停的往裏面放了不少燈光,有些屬性調整,可能本身也記不清楚了,能夠經過這樣Matrix的工具來很方便的把全部你關注的對象的屬性都列出來,很明顯,一眼就能看出來,並且能夠作批量調整,很是方便。
這就是我剛纔說的一些Showflag,用來判斷哪些類型的Primitive的繪製對象,對你的幀數影響比較大。這個我剛剛在Showcase示例裏面也講到了,比較方便的,一開始就能夠用來調整的HMD的調試命令行。
其實比較主要的,一個是SHADER的複雜度,一個是燈光,一個是後期處理,還有一個是投影。有不少高級的優化技巧,好比說,咱們儘量把Reflection Capture減小,不讓它們Overlaid,甚至把整個場景的SSR都關掉,在《Bullet Train》Demo中就關掉了SSR,可是你能看到很明顯,在火車站的大理石石板上,人和廣告燈箱牌是有倒影的,那些東西是咱們本身作的材質,作了一個模擬SSR的材質,這樣就至關於打開逐對象的SSR計算,就能夠省去不少沒必要要的開銷。包括咱們在《Showdown》用到的一些Cast Shadow的技巧,咱們把大部分的Dynamic Shader都已經去掉了,經過一些簡單的Blueprint的控制,好比說人腳步離地面的遠近,來Scale他腳下黑色的陰影面片大小,這樣能夠很好的知足視覺效果。
我剛纔介紹引擎默認的有一些Viewmode,能夠方便的看到Shader複雜度、貼圖密度、燈光密度,引擎各方面的開銷均可以看到。另一些比較次要,可是對幀數影響也比較明顯的showflag,這些開銷很是大,可是有些時候徹底能夠捨棄掉。在咱們的Demo裏面你們看到畫面效果很是好,可是咱們不少時候都不用後期處理和動態投影。
這裏也是我剛纔說的一些,咱們在《Showdown》裏面用到的,右邊是太糊了,可能看不太清楚。右邊是咱們《ShowDown》的設置,這是咱們比較推薦的後期處理的設置,儘量把全部東西都關掉,右邊的設置就是在《ShowDown》Demo裏面用到的設置。
GPU Profiler是更細緻的每一個環節的列表。工具
除了剛纔說的這些是技術手段上的內容,還有更多的是你們須要在製做以前就制訂一些規範,好比說你最終的目標是跑在什麼樣的硬件上面的,你美術製做的時候,在一開始可能作一些Protype的時候,設置一些美術的標準,根據這個標準來作,後期再作比較統一的優化,這樣效率可能會比較高一點。
VR既須要更好的效果,又須要更高的流暢度,但同時VR自己對你的開銷又更高,因此對優化的要求就更大。在剛剛那些內容優化,咱們都找到了之後,接下來更細一步的就是美術從新去作美術資源了,來作LOD,作遠處的剔除沒必要要的東西。也是一些咱們用到的渲染參數調整優化。
咱們後處理的一些設置。你們能看LPV (一種動態GI的solution)這種東西確定不能開的。AA,咱們基本上也能夠不用,全部的AA基本思路就是超採樣,但由於都是經過採樣定律來作的,要麼是時間上,要麼是空間上的。若是Screen Percentage已經能夠提升了,對你來講就不須要開AA了,好比說已經150%了,天然而然就已經AA了。你們知道爲何Retina屏幕的手機有些基本上不須要開AA,就是這個緣由。這是引擎內建能夠作渲染參數調整的一些設置。時間關係,後面的一些設置我就先帶過了。Shader材質的一些統計數據。這裏的Pixel和Vertex Shader的指令數。經過調整Shader來作一些優化。而後燈光儘量不要Overlaid。
最後我想說的是,你老是要先定一個目標,若是你的目標機器是很是差的機器,怎麼樣作優化,都不可能知足你的目標除非改變設計初衷。若是你的目標就是很是強的Titan X或980等,不少時候你也不必定須要作有優化,包括有時候你要認準你的機器,咱們不少時候開發可能用的是工具性的好比至強的處理器,主屏可能比較低,CPU的核數比較高,我在編譯開發環境上有優點,可是引擎作渲染的時候,優點比較差。有時候你會發現有影響,甚至CPU Bounding怎麼回事,隨便換一塊正常的遊戲用的i7 CPU立刻就解決問題了,根本不須要作什麼優化。其餘的就是設計上的考慮,基本上就是這些。
謝謝你們!學習