天天看點

UE4 Render Flow縱覽UE4 Render Flow縱覽

UE4 Render Flow縱覽

https://blog.ch-wind.com/ue4-render-flow-overview/

渲染優化時品質和效率的平衡,雖然按照官方的建議進行相應的調整即可,但是不稍微了解其内部的原理的話還是有些許讓人困惑的。

本文基于CEDEC2016的一篇講稿,目标UE4版本為4.13。

由于到目前的版本(4.18)引擎渲染已經有了很大的變動,是以有的内容隻有參考作用。

從概覽的角度來看,UE4的渲染可以劃分成以下的階段:

UE4 Render Flow縱覽UE4 Render Flow縱覽

這個通路是針對延遲渲染的,與目前主要針對VR裝置的前向渲染并不對應。

[針對渲染通道的優化]雖然之前有做過總結,但是并沒有詳細的研究過各個通道在整體渲染中的地位。

Base Pass

作為最重要的基礎性通道,Base Pass運算的結果作為之後所有通道運算的基礎。

基礎通道裡主要的可見操作是對Opaque/Masked材質的物體進行的遮蔽運算并完成G-Buffer的生成,VS和PS也在這個階段進行計算。

UE4 Render Flow縱覽UE4 Render Flow縱覽

針對Base Pass的優化方向主要針對Vertex Shader和Pixel Shader兩個階段,另外在材質的Shader制作本身上也需要注意降低運算量。

Vertex Shader

頂點計算的優化主要就是一些通常的建議:對物體的Bound進行規劃,不要讓bound過大,避免使用覆寫視野前後的物體。以使得Culling能夠在早期就剪除掉不需要的頂點計算。

在Console中可以使用一下指令輔助優化:

Stat InitViews可以檢視裁剪計算的效果

FreezeRendering可以當機裁剪,對裁剪結果進行可視化分析

更進一步的可以根據平台的GPU特性不同進行對應的優化。

Pixel Shader

由于Base Pass是後面所有通道的基礎,是以會有較高的固有消耗。同時也是在場景中添加物品、Shader等産生性能消耗最直覺的地方。

在理想的狀态下,在沒有Masked或者Translucent的情況,在PreZ階段完成時就可以決定各個像素的深度并形成遮蔽計算了。在這種情況下,就可以極好的減小Piexel Shader階段的運算量。但是實際上,為了場景中的特效品質,不能光依靠Opaque的材質,事情就沒有那麼簡單了。

會導緻PreZ完成時深度計算結果不完全的運算有,Masked材質的Alpha Test以及在Pixel Shader内部對深度資料的重寫。是以需要有PostZ階段對深度資料進行重新處理。

是以在這裡容易形成兩種造成性能影響的錯誤操作:在制作通用的材質時,明明有的不使用半透明蒙版通道情況卻開啟了半透明蒙版并往其上連接配接一個參數或者将參數連接配接到Piexel Depth Offset上。

由于PreZ和PostZ的決策是在GPU中完成的,無法在UE4中進行預覽,是以在進行優化的時候要注意對上面的兩種情況進行觀察。

總體而言,作為G-Buffer的生成階段,BassPass會直接的受到物體增加的影響,在添加物體時要注意檢查以下兩項:

Bounds的設定是否很好的完成了Culling。

Material的設定是否很好的避免了不必要的Pixel Shader計算。

另外,在項目設定中可以對G-Buffer的精度進行設定,對于需要高品質運算結果的情況或者想要降低性能消耗的情況,可以在這裡進行調整。

Z PrePass

這是在BasePass之前嘗試進行深度計算。經過Z PrePass計算之後,可以減少到達Vertex Shader的頂點數量,以提高效率。

在項目設定中可以對Early Z-Pass相關的選型進行調整。

對于單個物體,這裡的Use as Occluder預設是開啟的,将其去掉就不會參與Early Z-Pass的計算。這個大部分時間應該保持預設,讓引擎自行決定是否讓物體參與深度計算。

UE4 Render Flow縱覽UE4 Render Flow縱覽

早期深度計算是為了減少Base Pass的運算負荷而存在的,但有時場景中物體布局可能會導緻這個階段形成瓶頸,可以在這裡針對物體進行開啟關閉來調整效果。

Custom Depth/Stencil

在BasePass之後有一個可以自行進行定義的階段,就是自定義深度。

自定義深度可以使得使用者為物體在渲染時額外的生成一張深度貼圖,可以很好的對需要的物體進行裁剪。

在項目設定中開啟自定義深度

UE4 Render Flow縱覽UE4 Render Flow縱覽

然後在需要自定義深度的物體上打開

UE4 Render Flow縱覽UE4 Render Flow縱覽

需要注意的是,由于是額外進行的深度計算,基本上等同于對Base Pass進行了一次重新計算,自定義深度在場景較大的開放世界或者物體較多的場景中尤其會造成大的性能損失。

是以雖然使用Custom Depth可以相對簡單的實作一些效果,但是卻是以性能為代價的,應當盡量避免使用這個思路,如果非用不可的話,需要進行更加嚴格的Profiling。

Pre-Lighting

這是光照計算之前的一個運算階段,主要的作用是Decal和AO的計算。

在過去的版本中Decal經常與光照計算産生沖突,造成一些奇特的明顯不符合預期的最終結果。

是以後來加入了

UE4 Render Flow縱覽UE4 Render Flow縱覽

的選項,目前的引擎中是預設開啟的,無需太多關心。由于之前的項目中Decal的使用似乎沒有遇到過什麼問題,想來目前的預設選項已經很好的解決了問題。

如果在Decal的使用過程中遇到了問題,可以針對性的進行搜尋。

Lighting

就是光照計算階段,光照的優化其實能找到很多資料。光照在UE4的操作上分為三種,StaticLight是全靜态光照,全部使用預計算的結果進行光照。而Movable的光照則是全動态的,所有的光照都在運作時進行計算。Stational的光照則介于兩者之間,靜态物體的陰影會在預計算階段進行緩存。

另外Stationary Light有同一個區域隻受5個光照作用的限制,多出來的範圍最小的那個會變成紅叉叉,變成動态光照,在使用時需要注意。在視圖選項中可以使用

UE4 Render Flow縱覽UE4 Render Flow縱覽

來對整體場景進行排查。

在動态光照的優化上,動态光照是重疊的越多性能消耗就越高的,相反的個數很多卻互相不重疊的話光照複雜度的上升卻不是很快。可以在編輯器中使用光照複雜度視圖進行确認和優化。

UE4 Render Flow縱覽UE4 Render Flow縱覽

還有一點是,靜态光照并不是在運作時完全沒有性能消耗。靜态光照在運作時InitDynamic Setup計算階段是會造成CPU消耗的,是以并不是由于是預計算的就可以無計劃的放置。另外,據說StaticLight在被移動等時會自動的被變更為Movable的,沒有進行過測試是以并不是很确定呢。

總之在進行光照布局時,首先使用Stationary是比較合理的政策。

Reflect

反射計算雖然在概念上算是光照的一部分,但是其實在運算中是一個額外的階段。

Reflection Probe

反射捕獲,是預計算的反射。在引擎中提供了球體反射捕獲和盒體反射捕獲兩個選擇,在使用反射捕獲時,可以在拖入後對所在區域進行手動的重新捕獲,也可以自己在其中指定CubeMap。

在項目設定中可以進行設定來調整反射捕獲的精度。

UE4 Render Flow縱覽UE4 Render Flow縱覽

這部分的消耗是在Reflection Environment Compute Shader XXXX中反映的,與動态光照相同,個數對其性能消耗的影響不如區域重疊造成的影響。

官方的建議是,在場景全體放置一個總的反射捕捉,然後在一個機關房間内放一個整合性的捕捉,最後在反射性的物體上針對性的放置。

UE4 Render Flow縱覽UE4 Render Flow縱覽

覆寫全體的捕捉

防止在場景内完全丢失反射資訊的情況

房間機關的捕捉

在場景單元内形成詳細的反射資訊

物體機關的捕捉

反射要求較高的物體附近進行更加詳細的捕捉

Screen Space Reflection

動态反射計算,沒有深入看過其實作。

這裡的主要問題是,由于是在螢幕空間内進行的計算,在螢幕外的反射無法正确的反映,同時有較多的噪點而且對Translucent的材質在計算時容易出現問題。

是以通常是與上面的反射捕獲共同使用,作為其補充而存在的。是以如果出現了反射表面投影品質比較奇怪的問題,通常也可以檢查一下是否該區域沒有放置反射捕獲,而不是一味的去加強動态光照和間接光照的次數,畢竟他們的性能消耗還是非常可觀的。

Planar Reflection

效果很好的反射,全動态計算。

但是其負荷相當的高,如果場景中有兩個以上的話,會有目視可見的性能消耗。

無法控制反射通道中啟用的渲染功能。

反射通道中的動态陰影不正确。

為保證達到目标幀率,需計算資源是否足以使用平面反射。

隻支援恒定的粗糙系數,其在平面反射元件上(而非在材質上)進行指定。

如可能,須盡量将世界場景中的平面反射 Actor 數量限制為 1 個,将其移動、旋轉、縮放,和世界場景搭配。也可使用多個平面反射 Actor,但需多加注意,因為平面反射 Actor 不執行任何距離剔除,隻進行視錐和遮蔽剔除。是以,如果畫面中同時存在兩個平面反射 Actor,項目的幀率将受到嚴重影響。

渲染平面反射 Actor 的開銷直接來自目前關卡中渲染的内容。啟用此功能後,由三角形組成、繪制調用較大的場景将遭受嚴重的性能影響,因為這些開銷不會随螢幕百分比變化。

以上内容引用自官方文檔,在使用時需要額外的進行留意。

Translucent

由于深度計算的效率等問題,Translucent單獨在另一條路徑上進行處理。是以在半透明的計算在延遲渲染中,總是會有很多的問題。

深度計算

将半透明的粒子投放到場景中時,可以看到并不會在深度資料中産生影響。這樣在一些使用深度資料進行的效果如DOF中就會出現BUG。

是以UE4使用Separate Translucency來對半透明物體的深度進行處理

在項目設定中可以看到開關

UE4 Render Flow縱覽UE4 Render Flow縱覽

關于DepthOfField,在材質中有其運算結果的節點。

成本問題

半透明物體會極大的加重場景的渲染負擔,在着色器複雜度中能夠看到,通常半透明的粒子會導緻複雜度變為紅色。

優化上可以考慮降低Separate Translucency的分辨率,使用r.SeparateTranslucencyScreenPercentage指令可以通過降低分辨率來減小其消耗。

另一個解決方案是使用Particle CutOut有效的減少半透明計算的區域。

似乎隻要使用Create SubUV Animation就會自動應用,沒有測試是以并不清楚。

Responsive AA

在半透明材質中可以看到這個選項,主要是針對使用了半透明材質的粒子的。

UE4 Render Flow縱覽UE4 Render Flow縱覽

Post Process

pp是渲染的最後一個階段,可以在這裡對渲染結果進行進一步的加工。

UE4 Render Flow縱覽UE4 Render Flow縱覽

PostProcess的成本消耗與添加的特效相關,每一個特效都會産生額外的消耗。如果自己使用了pp的材質來進行控制的話,其Shader複雜度也會對性能産生影響。

自帶的PP特效可以通過指令來調整其效果,例如r.BloomQuality,其運算負荷是作為PostProcessWeightedSampleSum顯示。

UE4的後期處理能在官方找到很多詳細的[文檔]。

Rendering | UE4

UE4

繼續閱讀