1. 程式人生 > >Epic Games資深程式工程師王禰: 使用UE4製作VR內容的優化

Epic Games資深程式工程師王禰: 使用UE4製作VR內容的優化

遊戲兵工廠新聞報道:

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的位置,來控制引數調整到不同的值,可以在運算比較富裕的時候,展示更精細一點的效果,在優化壓力也很大,沒有辦法做進一步優化的情況下,讓畫面稍微變的糊一點,讓幀數有比較好的提升,這個效果是非常明顯的。

    大家看到經過調整以後,我們的整個一幀的渲染時間,已經變到了18、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降到了可能只有3、400,說明基本上所有的開銷都是在Static Mesh上面,可能需要場景美術去做更大的優化。如果也就降到8、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馬上就解決問題了,根本不需要做什麼優化。其他的就是設計上的考慮,基本上就是這些。

謝謝大家!

相關推薦

Epic Games資深程式工程師: 使用UE4製作VR內容優化

遊戲兵工廠新聞報道: 11月21日下午,由蠻牛精心打造的開發者線下技術交流平臺,第四屆蠻牛杯思享匯系列活動(北京站)在金長安大廈圓滿結束。來自蠻牛社群的遊戲開發者、VR行業、遊戲產業以及媒體記者等超120人。現場異常火爆,座無虛席,學習交流氛圍濃郁。  會上,Epic G

2018TGDCUE4製作多人大地型遊戲的優化

在2018TGDC大會上,來自Epic Games中國資深技術工程師王禰先生髮表了《UE4製作多人大地型遊戲的優化》主題演講。王禰有近10年的虛幻引擎使用經驗,從console遊戲、掌機到PC端MMO遊戲,再到手遊,都有過相關開發經驗;現在Epic Games China,他作為唯一的引擎技術專家,

阿里資深技術工程師程式設計師怎樣快速成長?

夢想很美好,現實卻很殘酷 不管是開發、測試、運維,每個技術人員心裡多多少少都有一個成為技術大牛的夢。畢竟“夢想總是要有的,萬一實現了呢”? 但很多阿里的新人,工作後就會發現,夢想是成為大牛,但做的事情看起來跟大牛都不沾邊。 比如,程式設計師說“天天寫業務程式碼

資深程式設計師的Metal入門教程總結

歡迎大家前往騰訊雲+社群,獲取更多騰訊海量技術實踐乾貨哦~ 本文由落影發表於雲+社群專欄 正文 本文介紹Metal和Metal Shader Language,以及Metal和OpenGL ES的差異性,也是實現入門教程的心得總結。 一、Metal Metal 是一個和 OpenGL ES

哭笑不得的習慣了,告知大家程式工程師的日常

  無奈了,竟然被一個小bug耽誤了那麼長時間,過程是這樣的:     今天搞api的過程,有個頁面死活出不來,沒有報錯,又沒有頁面。無奈之下,打了斷點進行debug,直到debug自己彈射出一個錯誤頁面,才發現是快取的問題。實在無奈,發表點感慨:     程式設計師的習慣,往往與常人有所背離

入門到精通:資深程式設計師規劃JAVA大資料學習路線(附視訊教程)

人類正在從IT時代走向DT(Data Technology)的時代。以網際網路、雲端計算、大資料和人工智慧為代表的技術革命正在滲透至各行各業,改變著我們的生活。 本文主要針對從事大資料開發的程式設計師們整理了整套的大資料學習相關的路線圖和知識材料,希望能幫助到大家。 很多初學者,對大資

資深程式設計師總結了9個java學習需要收藏的網站!

第一個:JavaSED 這是1個很大的資源型別的網站,涉及了很多Java程式碼案例。這個網站也可以檢視很多Java API類原始碼,值得收藏! 第二個:Code Project Code Project:1個可以夠適合程式設計師全部需求的論壇。 第三個:Stack Ove

我是如何在2年內逆襲成為BAT年薪40W的資深開發工程師的?

身邊的師弟師妹經常問到: 非計算機專業出身,你是在2年內如何逆襲成BAT年薪40W的資深開發工程師的。其實很簡單——努力! 我16年畢業於普通的二本學校,非計算機專業出身,只因為對軟體開發感興趣,所以找工作的時候就一直投IT行業的職位。剛踏入這個行業時,以為突擊一下東拼西湊的面試材料,就能有

BAT資深演算法工程師「Deep Learning」讀書系列分享(一) | 分享總結

本文轉載自:https://www.leiphone.com/news/201708/LEBNjZzvm0Q3Ipp0.html 雷鋒網 AI 科技評論按:「Deep Learning」這本書是機器學習領域的重磅書籍,三位作者分別是機器學習界名人、GAN的提出者、谷歌大腦研究科學家 Ian

資深程式設計師總結出的 Python十個陷阱與缺陷列表,大部分人都遇到過的問題

我個人對陷阱的定義是這樣的:程式碼看起來可以工作,但不是以你"想當然""的方式。如果一段程式碼直接出錯,丟擲了異常,我不認為這是陷阱。 比如,Python程式設計師應該都遇到過的"UnboundLocalError", 示例: 對於"UnboundLocalErr

資深程式設計師的看法,培訓出來的程式設計師一無是處嗎?

小編曾經有一位叫xxx的朋友說過一段話讓我記憶深刻。 “我覺得培訓本身沒錯,錯的是培訓機構鼓吹了這一行是多麼好賺錢然後吸引了一大堆不適合並且無興趣的人入行,而學員大多數人在發現自己不適合時卻沒勇氣離開,而苦苦的堅持著。” 還有一幫想嘗試卻沒有勇氣走出第一步的人,站在入口處,猶猶豫豫。

國外資深程式設計師的Python中類,靜態和抽象方法的權威總結

Python中方法的工作方式 方法是儲存在類屬性中的函式,你可以用下面這種方式宣告和訪問一個函式 >>> class Pizza(object): ... def __init__(self, size): ...

資深程式設計師給新入行程式設計師的十個建議!

剛剛脫離大學的你帶著殘留著墨香的畢業證書,踏上了充滿憧憬的工作崗位。理想雖然美好,現實卻很殘酷,你很快就被書上沒有的規則和各種繁雜的日常事務來了個下馬威。這樣的故事比比皆是,什麼工作都不例外,程式設計工作也一樣。 ​ 很多剛畢業的學生總覺得自己已經為第一份工作做好了準備,事實上,當你進入單位後發現並沒有做

思聰吃熱狗火了,程式設計師開發各種惡搞小程式校長:我不要臉的啊

最近王思聰吃熱狗火了,各種表情包,各種手機殼,各種素描等等。其實這些還不是最火爆的,竟然有一些程式設計師們開發出各種王校長吃熱狗的小程式,真的是行為惡劣啊! 校長:我不要臉的啊! 網友:思聰啊,當年你餓死也不該吃那一口熱狗! 王校長的獎盃 遊戲玩法: 遊戲開

一個資深程式設計師看12306(終結篇)

“喂?老兄,今晚我請吃飯,你有時間沒”? “有,當然有了。” “很好,你今晚幫我值班吧!” 上面的臺詞估計很多人都看了都會一笑。為什麼會有笑料?因為脫離了人的慣性思維。日常生活中,大家可能只會當笑話,或者會引用這些笑話,會擴散思維,想到很多更為搞笑的笑話。但技術不能這樣,技

BAT資深演算法工程師《深度學習》讀書分享:概率和資訊理論

《深度學習》這本書是機器學習領域的重磅書籍,三位作者分別是機器學習界名人、GAN的提出者、谷歌大腦研究科學家 Ian Goodfellow,神經網路領域創始三位創始人之一的蒙特利爾大學教授 Yoshua Bengio(也是 Ian Goodfellow的老師)、同在蒙特利爾大學的神經網路與資料探勘教授 A

資深程式設計師之路(5)--agile開發

以“瀑布模型”為代表的傳統軟體開發模型針對軟體生命週期的各個階段提供了一套規範, 以期使工程的進展達到預期的目的。核心強調在軟體開發活動中, 所有的活動計劃, 日程安排, 交付工作都要直接或間接的和需求保持一致, 同時強調軟體需求必須形成“ 文件” 。這種基

程式設計的意義何在?——一位資深程式設計師的自問

程式設計的意義是什麼,我又為什麼要程式設計呢?這是一個不時會浮現在我腦海中的問題,它來得並不頻繁,但每次卻都伴隨著對自己職業生涯或人生目標的質疑而產生,令我感到些許困惑和不安。而在這十幾年的職業生涯中,我也似乎總能在每個階段為自己找到一個繼續熱愛程式設計的理由,直到它已無法解答再一次疑惑的產

乾貨分享:十年大廠資深程式設計師的開發經驗總結

本文由騰訊雲加社群整理和釋出,原文連結:cloud.tencent.com/developer/article/1004735,內容有刪減和改動。 1、引言 在網際網路一線做了十年的程式開發,經歷了網易、百度、騰訊研究院、MIG 等幾個地方,陸續做過 3D 遊戲、2D 頁遊、瀏覽器、移動端翻

Fortnite cheats on YouTube spark Epic Games lawsuit in attempt to stop people getting special abilities

The developers of the popular video game Fortnite have filed a lawsuit against two YouTube personalities for allegedly selling cheat codes to their viewers